參考原文html
JAVA 11 是 JAVA 8 以後的第一個 LTS 版本,爲了瞭解下一代 JAVA 版本更新的內容,也爲了能調試到 JAVA 的內部代碼,因此筆者決定源碼安裝試試。java
官方給出的安裝教程[1]是這樣的:shell
hg clone http://hg.openjdk.java.net/jdk/jdk
bash configure
。缺失依賴會致使 configure 失敗,但錯誤日誌都會給出操做建議,根據建議安裝依賴便可make images
./build/*/images/jdk/bin/java -version
make run-test-tier1
這個安裝步驟大致上沒問題,可是有些差別須要指出,所以我也給出個人安裝步驟。macos
安裝 jre 11 運行時,這個能夠經過 brew 來安裝,或者直接下載 oracle 或 openjdk。xcode
由於編譯的是比較新的 jdk 11,直接用 xcode 最新版便可(官方推薦的是 9.4,我用的是最新版 10.3 沒問題)。bash
經過 brew 安裝 autoconf 和 freetype。oracle
從 jdk 10 開始,源碼再也不分散在不一樣的倉庫中,因此只須要 clone 單獨的 repository 便可[1:1]。我選擇是 jdk11u,並且不是經過 hg clone 的方式(比較慢,常常出錯須要重試),而是直接下載整個源碼包,以下圖示。jvm
執行 configure,爲了 debug,須要加上對應的參數。ide
sh configure --with-target-bits=64 --enable-ccache --with-jvm-variants=server --with-boot-jdk-jvmargs="-Xlint:deprecation -Xlint:unchecked" --disable-warnings-as-errors --with-debug-level=slowdebug 2>&1 | tee configure_mac_x64.log
複製代碼
通常第一次執行老是會遇到些小問題,但編譯 jdk 11 的問題比 jdk8,9少多了,根據提示很容易就能夠解決。當看到以下返回即代表配置成功。模塊化
====================================================
A new configuration has been successfully created in
/Users/haidao/Downloads/openjdk11/build/macosx-x86_64-normal-server-slowdebug
using configure arguments '--with-target-bits=64 --enable-ccache --with-jvm-variants=server --with-boot-jdk-jvmargs='-Xlint:deprecation -Xlint:unchecked' --disable-warnings-as-errors --with-debug-level=slowdebug'.
Configuration summary:
* Debug level: slowdebug
* HS debug level: debug
* JVM variants: server
* JVM features: server: 'aot cds cmsgc compiler1 compiler2 dtrace epsilongc g1gc graal jfr jni-check jvmci jvmti management nmt parallelgc serialgc services vm-structs'
* OpenJDK target: OS: macosx, CPU architecture: x86, address length: 64
* Version string: 11-internal+0-adhoc.haidao.openjdk11 (11-internal)
Tools summary:
* Boot JDK: openjdk version "11.0.2" 2019-01-15 OpenJDK Runtime Environment 18.9 (build 11.0.2+9) OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode) (at /Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk/Contents/Home)
* Toolchain: clang (clang/LLVM from Xcode 10.3)
* C Compiler: Version 10.0.1 (at /usr/bin/clang)
* C++ Compiler: Version 10.0.1 (at /usr/bin/clang++)
Build performance summary:
* Cores to use: 4
* Memory limit: 8192 MB
* ccache status: Active (3.7.2)
複製代碼
而後執行 make 便可。根據 build 文檔[1:2],執行 make 不帶任何參數等同於make default
和make jdk
,這會 build 出一個較小的編譯結果,並提供一個 exploded image。不知道怎麼翻譯 exploded image,大概意思是,這是一個分解開的鏡像,能夠直接使用,各個模塊都是解壓好的,不包含源碼。這種設計是爲了方便 jdk 的開發者漸進式開發,每次 make 只會 recompile 變化的部分。
其餘 make 的經常使用 target 以下:
hotspot
- Build all of hotspot (but only hotspot)hotspot-<variant>
- Build just the specified jvm variantimages
or product-images
- Build the JDK imagedocs
or docs-image
- Build the documentation imagetest-image
- Build the test imageall
or all-images
- Build all images (product, docs and test)bootcycle-images
- Build images twice, second time with newly built JDK (good for testing)clean
- Remove all files generated by make, but not those generated by configuredist-clean
- Remove all files, including configuration咱們以 $BUILD 表示構建結果目錄[2],構建結果目錄以下[1:3]:
jdk
: 這就是以前所說的 exploded image 的目錄。執行make jdk
以後,你能夠經過運行$BUILD/jdk/bin/java
直接啓動新構建的 JDK。images
: 這個目錄是 make *-image 的輸出位置。例如,make jdk-image
會構建出 jdk image, 目錄是images/jdk
。test-results
: 測試結果目錄。support
: 這個目錄保存的是 build 過程當中的中間文件,好比源碼,對象文件,類文件等。support
中比較重要的是gensrc
,它包含生成的源碼;modules_*
包含了按模塊層級分佈的文件,它會在以後合併到 jdk 目錄下。因爲咱們執行的是最簡構建,咱們主要看下 $BUILD/jdk 和 $BUILD/images/jdk 的差別:
$BUILD/images/jdk $BUILD/jdk
├── bin ├── _packages_attribute.done
├── conf ├── bin
├── demo ├── conf
├── include ├── include
├── jmods ├── lib
├── legal ├── modules
├── lib └── release
├── man
└── release
複製代碼
和 $BUILD/jdk 不同,$BUILD/images/jdk 這個目錄下沒有解壓好的 modules 目錄,而是以壓縮包的形式放在 jmods 下。這是自 JAVA 9 引入的模塊化打包設計,旨在減少 JAVA 應用的包體積,使得部署更加輕量。
$BUILD/jdk 下的 lib 目錄是動態庫文件和調試信息文件,不包含源碼。而 $BUILD/images/jdk 下的 lib 目錄下的動態庫文件沒有可執行權限,但包含源碼 src.zip。
$BUILD/jdk 做爲 exploded image,不像 product-image 那樣須要包含法律文件和 demo。
除了這些區別以外,兩者在使用上沒啥差異。
如今,能夠直接經過 $BUILD/jdk/bin/java 來使用編譯出來的 JAVA11。你也能夠配置 jenv:jenv add $BUILD/jdk
。關於 jenv 的使用請參看 Mac OS 使用 jenv 管理 java 版本。
增長 SDK,配置 classpath 和 sourcepath。配置好 sourcepath 即可以正常查看代碼了。
若是使用的是 $BUILD/images/jdk,直接將該目錄加入到 classpath 便可,IDE 會自動識別 src.zip 並放在 sourcepath 中;
若是使用的是 $BUILD/jdk,因爲這是 exploded image jdk,不包含源碼,因此須要分別加入 classpath 和 sourcepath,sourcepath 即下載的 openjdk 下的 src 目錄。
其餘須要修改的配置不在贅述,以下圖示。
在 IDE sdk 中配置好 jdk 11 以後即可以正常調試 JAVA 代碼了。若是咱們想調試 jdk/jvm 源碼的 C 代碼怎麼辦呢?咱們已經 build 一個能夠 debug 的 java11 運行環境,下面就是配置 IDE 來 debug。
首先導入源碼。使用 New Cmake Project from Sources,這樣能夠自動建立 CMakeLists.txt 文件。而後按照引導便可導入源碼。你能夠導入 src/hotspot,也能夠整個導入 src。
導入以後,具體的 cpp 文件會報錯,可是不影響調試,能夠暫時忽略。
導入成功,reload CMakeLists.txt 以後,會自動生成一個 debug configuration。下面配置 debug configuration。如圖所示,將 executable 改成你的 java 二進制文件,而後在 program arguments 裏設置程序參數。咱們先設置爲 -version。
此時咱們在share/prims/jni.cpp
文件上打一個斷點,而後執行 debug,就能夠看到效果了。