本文首发于个人博客: https://joemendezckh.github.io/posts/35ab761c.html
本文是针对 深入理解Java虚拟机 一书第一章的实践, 手动编译 JDK
环境信息:
- CentOS 7.8
- OpenJDK7u75
- jdk1.7.0_81
准备工作与开始编译
-
安装所需要的依赖
# 需要的依赖 yum -y install gawk m4 binutils libstdc++-static ant gcc gcc-c++ cups-devel alsa-lib-devel libX* zip unzip glibc-static
-
准备 bootjdk
- 即下载一个正常使用的 jdk 版本, 要与编译的 openjdk 版本相同
-
测试安装环境是否完善
# 以下操作在解压的openjdk目录下操作 make sanity # 有一个 waring [WARNING]: LANG has been set to zh_CN.UTF-8, this can cause build failures. Try setting LANG to 'C'. # 解决办法 export LANG=C # 重新执行 make sanity # 看到只有 Sanity check passed. # 说明环境准备好了
-
编写启动脚本
- 还是在上文解压的 openjdk 目录下
vim compile.sh #!/bin/bash # 语言选项, 这个必须设置, 否则编译好后会出现一个HashTable的NPE错 export LANG=C # Bootstrap JDK的安装路径. 必须设置. # export ALT_BOOTDIR=/opt/jdk1.8.0_221 export ALT_BOOTDIR=/opt/jdk1.7.0_81 # 允许自动下载依赖 export ALLOW_DOWNLOADS=true # 并行编译的线程数, 设置为和CPU内核数量一致即可 export HOTSPOT_BUILD_JOBS=4 export ALT_PARALLEL_COMPILE_JOBS=4 # 比较本次build出来的映像与先前版本的差异. 这个对我们来说没有意义, 必须设置为false,否则sanity检查会报缺少先前版本JDK的映像. 如果有设置dev或者DEV_ONLY=true的话这个不显式设置也行. export SKIP_COMPARE_IMAGES=true # 使用预编译头文件, 不加这个编译会更慢一些 export USE_PRECOMPILED_HEADER=true # 要编译的内容 export BUILD_LANGTOOLS=true # export BUILD_JAXP=false # export BUILD_JAXWS=false # export BUILD_CORBA=false export BUILD_HOTSPOT=true export BUILD_JDK=true # 要编译的版本 export SKIP_DEBUG_BUILD=false export SKIP_FASTDEBUG_BUILD=true export DEBUG_NAME=debug # 把它设置为false可以避开javaws和浏览器Java插件之类的部分的build。 BUILD_DEPLOY=false # 把它设置为false就不会build出安装包. 因为安装包里有些奇怪的依赖, 但即便不build出它也已经能得到完整的JDK映像, 所以还是别build它好了. BUILD_INSTALL=false export COMPILER_WARNINGS_FATAL=false # 编译结果存放的路径 # export ALT_OUTPUTDIR=/tmp/server/jdk1.7 # 这两个环境变量必须去掉, 不然会有很诡异的事情发生(我没有具体查过这些“”诡异的事情”,Makefile脚本检查到有这2个变量就会提示警告“) unset JAVA_HOME unset CLASSPATH make 2>&1 | tee $ALT_OUTPUTDIR/build.log # =======================end compile================== chmod +x compile.sh ./compile.sh
-
如果一切顺利的话, 会出现如下结果
>>>Finished making images @ Mon May 25 15:56:48 CST 2020 ... make[2]: Leaving directory `/opt/openjdk/jdk/make' ######################################################################## ##### Leaving jdk for target(s) sanity all docs images ##### ######################################################################## ##### Build time 00:10:07 jdk for target(s) sanity all docs images ##### ######################################################################## #-- Build times ---------- Target all_product_build Start 2020-05-25 15:46:00 End 2020-05-25 15:56:48 00:00:16 corba 00:00:15 hotspot 00:00:03 jaxp 00:00:04 jaxws 00:10:07 jdk 00:00:03 langtools 00:10:48 TOTAL ------------------------- make[1]: Leaving directory `/opt/openjdk'
编译完成后的测试
-
还是在 openjdk 目录下操作
- 验证编译成功
cd build/linux-amd64/j2sdk-image/bin [root@jvm bin]# ./java -version openjdk version "1.7.0-internal" OpenJDK Runtime Environment (build 1.7.0-internal-root_2020_05_25_15_25-b00) OpenJDK 64-Bit Server VM (build 24.75-b04, mixed mode)
-
将之前安装 ant 时安装的 openjdk 卸载掉 (可选)
-
将 build/linux-amd64/j2sdk-image 放在 JAVA_HOME 下, 配置好环境变量后, 即可正常使用自己编译的 jdk (可选)
[root@jvm bin]# source /etc/profile [root@jvm bin]# java -version openjdk version "1.7.0-internal" OpenJDK Runtime Environment (build 1.7.0-internal-root_2020_05_25_15_25-b00) OpenJDK 64-Bit Server VM (build 24.75-b04, mixed mode)
编译中出现的错误
大部分错误的导致原因都是由于缺少相应的依赖, 但是本文在开始已经下载好了所需要的依赖, 所以出现的错误不多, 如果有出现其他错误的, 可以参考文章结束部分的参考资料
build-bootstrap-javac
build-bootstrap-javac:
[mkdir] Created dir: /opt/openjdk/build/linux-amd64/langtools/build/bootstrap/gensrc
[mkdir] Created dir: /opt/openjdk/build/linux-amd64/langtools/build/bootstrap/classes
[pcompile] Generating 7 resource files to /opt/openjdk/build/linux-amd64/langtools/build/bootstrap/gensrc
[copy] Copying 1 file to /opt/openjdk/build/linux-amd64/langtools/build/bootstrap/gensrc
[pcompile] Generating 1 resource files to /opt/openjdk/build/linux-amd64/langtools/build/bootstrap/gensrc
[javac] Compiling 298 source files to /opt/openjdk/build/linux-amd64/langtools/build/bootstrap/classes
[javac] /opt/openjdk/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java:2182: warning: [overrides] Class Resolve.InapplicableSymbolsError.Candidate overrides equals, but neither it nor any superclass overrides hashCode method
[javac] private class Candidate {
[javac] ^
[javac] error: warnings found and -Werror specified
[javac] 1 error
[javac] 1 warning
BUILD FAILED
/opt/openjdk/langtools/make/build.xml:452: The following error occurred while executing this line:
/opt/openjdk/langtools/make/build.xml:795: Compile failed; see the compiler error output for details.
- 解决办法:
- 之前使用的是 jdk 1.8 查阅资料发现, 是版本的问题, 换成 jdk1.7 即可
- jdk1.7下载链接
Error: time is more than 10 years from present: 1136059200000
Error: time is more than 10 years from present: 1136059200000
java.lang.RuntimeException: time is more than 10 years from present: 1136059200000
at build.tools.generatecurrencydata.GenerateCurrencyData.makeSpecialCaseEntry(GenerateCurrencyData.java:285)
at build.tools.generatecurrencydata.GenerateCurrencyData.buildMainAndSpecialCaseTables(GenerateCurrencyData.java:225)
at build.tools.generatecurrencydata.GenerateCurrencyData.main(GenerateCurrencyData.java:154)
-
解决方法
# 修改配置文件 在 openjdk 下 vi openjdk/jdk/src/share/classes/java/util/CurrencyData.properties # 修改108行 AZ=AZM;2009-12-31-20-00-00;AZN # 修改381行 MZ=MZM;2009-06-30-22-00-00;MZN # 修改443行 RO=ROL;2009-06-30-21-00-00;RON # 修改535行 TR=TRL;2009-12-31-22-00-00;TRY # 修改561行 VE=VEB;2009-01-01-04-00-00;VEF # 修改年份至今小于 10 年 :)
参考资料
-
CentOS7下编译OpenJDK – 更多的错误处理可以看这篇文章