一、关联源码调试(有缺陷)
第一步:新建一个JAVA项目
new一个最简单的java项目,如图,一直next最后finish就行了。这边给项目起的名——JavaSourseLearn
,代表jdk源码学习。
第二步:源码解压
找到Project Structure
(ctrl + shift + alt + s),找到SDKs -> Sourcepath,可以看到源代码src.zip的存储位置。
src.zip解压,删除com目录(这块代码不需要,而且不删除会因为缺少部分文件而报错),解压目录随意。
第三步:修改配置
Project Structure
- SDKs,点击新增("+"),新增1.8_clone(名字自取),删除sourcepath里面的src.zip源码,将源码链接指向src.zip解压的目录。
Project Structure
- Modules,引用前面新增的sdk;或者是修改Project -> Project SDK。
- 编写hashmap测试代码,尝试调试
启动debug,f7发现进不去hashmap的构造方法。因为idea限制了一些包com.sum.、java.、javax.*等等不能step into。修改配置如图。
如果debug run提示资源不足,可以尝试如图方法。(非必要,这边就没有出现这种情况)
第四步:编写测试代码,debug调试代码。
此时,如上上上图,step into hashmap的构造函数。我们尝试加点注释。如下图。
增加单行注释会导致debug错位,当然我们可以增加行尾注释避免错位的问题(但是这不够优雅)。根据上图我们可以得知,执行的代码还是jdk的代码,不是执行我们修改的source目录下的源代码,所以我们在源代码上增加比如System.out.print的代码也是不生效的(除非重新编译jdk)。
二、CentOS7编译open jdk8
1、拉取源代码
- github镜像:https://github.com/openjdk/jdk
注意不要用git先在windows拉取源码再放到linux,会出现大量换行符问题,windows是\r\n,linux是\n。如果是要编译linux的源码,直接在linux安装git拉取代码。因为文件的换行符在git拉取的那一瞬间就决定了。
# 拉取jdk代码
git clone https://github.com/openjdk/jdk
# 进入代码目录
cd jdk
# 切换到 tag标记 jdk-b120, github上8版本的最新的tag
git checkout jdk8-b120
2、安装BootStrap JDK
需要安装BootStrap JDK,也就是前导jdk,用来引导jdk编译的。比如我们要编译jdk8,就要先安装jdk7(比当前要编译的版本早一些的版本,最好是早一个版本号。这边使用的是jdk-7u80-linux-x64.tar.gz——解压出来是jdk1.7.0_80
)。
3、linux上安装必要的工具集(我的是CentOS)
yum install -y zip
yum groupinstall -y 'Development Tools'
yum install -y libXtst-devel libXt-devel libXrender-devel
yum install -y cups-devel
yum install -y alsa-lib-devel
yum install -y freetype-devel
4、编译
可以把export以及编译命令写成shell脚本,因为export不写进/etc/profile退出shell将失效。
# jdk是刚拉取的源代码根目录
cd jdk
# 设置configure执行权限
chmod +x configure
# 设置编译参数
export LANG=C
# 使用预编译头文件,不加这个编译会更慢一些
export USE_PRECOMPILED_HEADER=true
#比较本次build出来的映像与先前版本的差异。这对我们来说没有意义,
#必须设置为false,否则sanity检查会报缺少先前版本JDK的映像的错误提示。
#如果已经设置dev或者DEV_ONLY=true,这个不显式设置也行
export SKIP_COMPARE_IMAGES=true
# 要编译的内容
export BUILD_LANGTOOLS=true
export BUILD_HOTSPOT=true
export BUILD_JDK=true
#把它设置为false可以避免javaws和浏览器java插件之类的部分的build
export BUILD_DEPLOY=false
# 把它设置为false就不会build出安装包。因为安装包里有一些奇怪的依赖
# 但即使不build出它也已经能得到完整的JDK映像,所以还是别build它好了
export BUILD_INSTALL=false
unset JAVA_HOME
unset CLASSPATH
unset JAVA_TOOL_OPTIONS
# configure检查(注意前导jdk7必须提前安装)
bash ./configure --with-target-bits=64 --with-boot-jdk=/usr/local/jdk1.7.0_80 --with-debug-level=slowdebug --enable-debug-symbols ZIP_DEBUGINFO_FILES=0
最后这个提示可以无视,直接编译
# 检查无误,开始编译
make all CONF=linux-x86_64-normal-server-slowdebug ZIP_DEBUGINFO_FILES=0
编译成功如图所示(如果编译失败会自动退出)
检测下我们自己是否编译成功了,进入jdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin目录下,执行./java -version
。
make clean (清除之前的数据,用于修改源码后多次编译)
ide中使用jdk的源码路径
jdk/jdk/src/share/classes/
注:如果在ide中使用src.zip,调试时会找不到部分package源码,如sun.misc.*。
#这个对上前面【一、关联源码调试(有缺陷)】删除com目录的操作
jdk/build/linux-x86_64-normal-server-slowdebug/images/src.zip
注意:这个编译的jdk大约1G左右,而且这个jdk是无法在win上跑的,所以win上使用idea的同学无法配置这个jdk,这种方式编译的jdk只能在mac、ubuntu、centOS等类unix的平台上使用,如果使用mac的同学可以直接编译完然后再idea里配置就可以了。
另外因为环境变量配置export LANG=C,所以如果安装的系统是中文版本的,会让系统无法识别中文,甚至中文乱码。我的centOS原来echo $LANG
是en_US.UTF-8
不是中文版的不会出现这种问题。
所以在编译完后,如果怕出现中文乱码问题,还需要进行设置
运行:vim /etc/locale.conf 查看是不是 LANG=zh_CN.UTF8
如果不是,那么进行修改。如果是,不用修改,直接退出。
接着运行:source /etc/locale.conf 然后系统语言切换到中文。
三、Win10编译open jdk8
1. 编译环境说明
- cygwin
- freetype 2.7
- Visual Studio 2010 Professional (英文版)
- jdk8-b120
- JDK7 (oracle官网下载-直接安装)
2. 软件安装
通过git下载openjdk8
# git在提交时把CRLF转换成LF,签出时不转换。因为源文件是lf,在cygwin上执行也要lf,不设置pull下来就变成crlf。
git config --global core.autocrlf input
# clone jdk8最后一个标签版本 -b是标签tag --depth 表示克隆深度, 1 表示只克隆最新的版本
git clone -b jdk8-b120 --depth=1 https://github.com/openjdk/jdk.git
cygwin
cygwin安装步骤
首先安装cygwin:这个是模拟Linux环境的软件,主要编译工作在里面。
cygwin官网:http://www.cygwin.com/
注意:cygwin安装目录和cygwin package安装目录最好分开。比如cygwin装在D:/cygwin,cygwin package安装在D:/cygwin/download。
需要安装的Package:
Binary Name | Category | Package | Description |
---|---|---|---|
ar.exe | Devel | binutils | The GNU assembler, linker and binary utilities |
make.exe | Devel | make | The GNU version of the ‘make’ utility built for CYGWIN |
m4.exe | Interpreters | m4 | GNU implementation of the traditional Unix macro processor |
cpio.exe | Utils | cpio | A program to manage archives of files |
gawk.exe | Utils | awk | Pattern-directed scanning and processing language |
file.exe | Utils | file | Determines file type using ‘magic’ numbers |
zip.exe | Archive | zip | Package and compress (archive) files |
unzip.exe | Archive | unzip | Extract compressed files in a ZIP archive |
free.exe | System | procps | Display amount of free and used memory in the system |
不知道是不是哪里弄错了,装了92G的文件,安装的时候注意下磁盘空间是否够。
cygwin配置环境变量
将cygwin安装路径下的bin目录配置到环境变量path中,如我的安装路径为:D:\develop\openjdk\cygwin\bin
vs2010安装
需要该软件的原因:JDK中最核心的代码(Java虚拟机及JDK中Native方法的实现等)是使用C++语言及少量C语言编写的,官方文档中说他们的内部开发环境是Microsoft Visual Studio C++ (VS2003)中进行编译,及Microsoft Visual Studio C++ (VS2010)测试过。
解压iso文件,双击setup.exe
,一直下一步最后finish。安装完桌面如果没有快捷方式:开始 -> 所有程序 -> Microsoft visual studio 2010 ->Microsoft visual studio 2010,找到后创建到桌面快捷方式。(安装路径不要有空格)
第一次打开vs2010,选择VC++,如下图。
FreeType安装
需要该软件的原因:这是一个免费的字体渲染库,JDK的Swing部分和JConsole这类工具使用到。
将下载的freetype2.7解压。接下来介绍通过vs2010编译64位的freetype-2.7。
编译freetype
vs2010打开freetype,如下图。我的freetype路径:D:\develop\openjdk\freetype-2.7
打开后,右键项目,选择properties,如图
编译freetype.lib:
编译freetype.dll
然后跟上一步一样build。编译好的文件,文件在freetype目录下,我的是D:\develop\openjdk\freetype-2.7\objs\vc2010\x64
在freetype目录下新建lib并将上面编译的两个文件复制进去,如下图。
编译openjdk之前会校验并用到freetype下的include文件下的ft2build.h和lib文件夹下的dll和lib文件
设置freetype的环境变量
FREETYPE_CFLAGS=D:\develop\openjdk\freetype-2.7\include
FREETYPE_LIBS=D:\develop\openjdk\freetype-2.7\lib
编译openjdk
打开Cygwin,切换到解压的openjdk8的文件夹根目录,如
执行命令:
bash ./configure -with-freetype=/cygdrive/d/develop/openjdk/freetype-2.7 -enable-debug -with-target-bits=64 --with-boot-jdk=/cygdrive/d/develop/jdk/jdk7 --disable-ccache
命令解析:
- -with-freetype参数是使用指定的freetype
- --with-debug-level=slowdebug。用来设置编译的级别,可选值为release、fastdebug、slowde-bug,越往后进行的优化措施就越少,带的调试信息就越多。默认值为release。slowdebug 含有最丰富的调试信息,没有这些信息,很多执行可能被优化掉,我们单步执行时,可能看不到一些变量的值。所以最好指定slowdebug 为编译级别。
- -enable-debug是编译可调试的openjdk,fastdebug级别
- -with-target-bits=64,是指编译64位的。
- --with-boot-jdk:指定引导JDK所在目录,以防其他安装的JDK影响
- --with-jvm-variants=server : 编译JVM的模式,有server, client, kernel, zero and zeroshark 五种 ,默认server模式;
- --enable-debug-symbols ZIP_DEBUGINFO_FILES=0:生成调试的符号信息,并且不压缩;(用这个提示找不到objcopy,懒得弄了,把这个去掉)
再执行上述操作前如果设置了环境变量JAVA_HOME, CLASSPATH 记得删除,否则会报错。
编译时遇到的问题:
- 提示cygwin版本太老((ˉ▽ˉ;)...这个是2021/8/20官网下载的最新版本),这是检测脚本的bug,该脚本在common/autoconf目录下使用文本编辑器打开generated-configure.sh搜索Your cygwin is too old,关注7249行原来是1.7这里我根据自己的cygwin版本改成了3.2.0。
- 提示找不到freetype-2.7/lib的freetype.dll。因为上一步vs2010编译的时候我们没有修改freetype的名称。我们的文件名称是freetype27MT.dll,修改成freetype.dll(这个上一步的流程已经修改改成freetype了,不会出现这个问题)。
最终,configure检测完毕:
最后make clean && make all
编译。
编译时可能出现的错误:
-
在configure中加入参数 --disable-ccache
-
CreateJars.gmk格式异常
解决办法:用vi打开jdk/make目录下的CreateJars.gmk
cd /cygdrive/d/develop/openjdk/openjdk8/jdk/make
vi CreateJars.gmk
定位到268行,相距不远处有两个$$换行符,将其转换为Windows下的换行符。
在VI下,可输入268gg。
将光标定位到两个$$之前,按i切换到insert模式后,按Ctrl + V, Ctrl + M,即可打出^M。
完成后按esc退出编辑模式,然后按:进入命令模式,输入wq保存并退出。
- 修改源码增加中文编译报错
找到jdk/make/Setup.gmk,用文本编辑器打开(我是vs code),搜索一下encoding
,默认是ascii,改成utf-8并保存。之后修改代码或者加中文注释就不会出现编码问题啦。
编译完的结果在build\windows-x86_64-normal-server-fastdebug中。
jdk编译出来的成品在images文件夹下, 如我的D:\develop\openjdk\openjdk8\build\windows-x86_64-normal-server-fastdebug\images\j2sdk-image,这个和我们从官网下载的基本一样。
调试:
idea新建项目jdkLearn,新建SDKs,Classpath指向D:\develop\openjdk\openjdk8\build\windows-x86_64-normal-server-fastdebug\images\j2sdk-image,SourcePath指向D:\workshop\idea-mine\jdk\jdk\src。
修改源码后,要重新编译执行make images
,这次是增量编译会快很多。
官网上编译用:make images
,的确,make all
编译花了我们比较多的时间,而且编译的大部分我们也用不上。后面configure
后可以直接make images
。
verify用images下的java文件:
Verify your newly built JDK:
./build/*/images/jdk/bin/java -version
不想make clean,直接make images增量编译但是报错了。去目录\build\windows-x86_64-normal-server-fastdebug\jdk 下删除objs和demoobjs,将这两个文件夹下的所有文件删除。重新编译正常,我这边重新编译花费4、5分钟。
参考与鸣谢:
https://blog.csdn.net/qq_39575279/article/details/81609395
https://blog.csdn.net/wqlinloveruby/article/details/80409031
https://blog.csdn.net/weixin_34144450/article/details/92575977
https://blog.csdn.net/wangshuaiwsws95/article/details/107375724
https://blog.csdn.net/linpeijieaini/article/details/118891404