本文首發於個人博客: 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 – 更多的錯誤處理可以看這篇文章