用JAVA作為開發工具的人都不會對JDK陌生,幾乎天天都在用
其中有多少人真正編譯過JDK呢?
估計是少之又少了
但是我們可能經常會遇到一些問題,現象奇特詭異,難以界定,但是如果能在JDK中做點兒手腳,也許就會讓問題找到解決的方向
這篇文章,就是手把手教你怎麼編譯一個JDK
别光看,凡是都要自己動手做一遍
環境準備
我使用的環境是在虛拟機上安裝的Centos7.6,純淨系統,其他啥都沒裝
檢視說明
這是openjdk8的build說明,後面我會把裡面重要的部分截圖拿出來并簡單說明
http://hg.openjdk.java.net/jdk8u/jdk8u/raw-file/tip/README-builds.html根據說明

指令就兩步
bash ./configure
make all
但是需要一些環境準備
make版本有要求,要大于3.8.1,自己檢查一下,centos7.6以上的肯定滿足
需要有一個Bootstrap JDK,需要7的,不能用8的,需要把bin加到path裡面,這樣就不用配置參數了
下載下傳jdk7,tar形式的
jdk-7u80-linux-x64.tar.gz
解壓
tar zxvf jdk-7u80-linux-x64.tar.gz
記下java的位置
/home/jdk/jdk1.7.0_80/bin
不着急加path,後面編譯的時候用臨時的就行了
有一個要注意
如果環境變量裡面有JAVA_HOME,要去掉
安裝元件
檢視元件
需要這四個元件
search一下
yum search alsa freetype cups xrender
選擇一部分安裝
yum install alsa-lib alsa-lib-devel freetype-devel freetype cups cups-devel libXrender libXrender-devel
有很多教程裡面說要安裝ant
但實際上ant已經不需要了
Ant is no longer used when building the OpenJDK
安裝完對版本
比要求的版本高就行
centos7.6通過yum安裝的都能夠達到要求
安裝其他元件
這裡面說了這麼多,實際上就安裝下面這些就行
yum groupinstall "Development Tools"
yum install libXi libXi-devel libXtst-devel libXt-devel
下載下傳資源
安裝mercurial
然後下載下傳源檔案的資源擷取工程(類似git的一個clone指令,這裡面是編譯的一些配置和資源擷取檔案,個頭較小,clone之後再擷取大的資源)
之後進入目錄
yum install mercurial
hg clone http://hg.openjdk.java.net/jdk8u/jdk8u60 jdk8u60
cd jdk8u60
bash ./get_source.sh
然後泡個茶等着吧
這個過程中很容易失敗
如果發現這樣的提示
WARNING: jaxws exited abnormally (255)
WARNING: jdk exited abnormally (255)
那就再執行get_source吧
他隻會下載下傳沒成功的幾個元件,已經下載下傳成功的是不會再下載下傳的
如果卡住長時間不見動靜,看一下帶寬占用,如果也沒有
那就用
ps aux|grep clone
把python的clone程序殺掉
get_source這邊就會出現失敗
再把失敗的這幾個的目錄删掉
重新執行get_source就能夠重下了
這部分可能會重複很多次,我至少重複了4,5次,jaxws jdk這兩個始終下不下來
最終放棄了,jdk這個怎麼也下不下來
直接用控制台上列印的clone的位址去浏覽器通路
下zip包,再來解壓縮吧
很快就下完了,之前重試這麼多遍的我,簡直就是傻子
執行編譯
執行之前先把Bootstrap JDK加到環境變量中去
網上很多文章在這一步會給configure增加很多參數,比如Bootstrap JDK的路徑啊alsa的路徑之類的,實際上如果是通過yum安裝alsa這些依賴,并在path中增加了Bootstrap JDK的bin目錄,這些都不用加
export PATH=/home/jdk/jdk1.7.0_80/bin:$PATH
java -version
bash ./configure --enable-debug --with-target-bits=64
這樣configure就算OK啦,最後提示的這個ccache可以不用管,是個編譯加速的東西,沒有也行,而且就算安裝,也會發現yum裡面找不到
OK,根據官網提示執行最後一步
make all
經過漫長的等待
中途出現無數warning,搞得人很焦慮啊
編譯完成啦
這裡就完了嗎?當然不是
接下來我們還要用啊
使用自己編譯的JDK
images下面就是打好的包
j2sdk-image:JDK
j2re-image:JRE
進JDK看看,目錄結構是不是很熟悉了
讓我們用cp指令把jdk目錄拷貝走
cp -r /home/jdk/jdk8u60/build/linux-x86_64-normal-server-fastdebug/images/j2sdk-image /home/jdk/openjdk-8u60-make
檢視一下版本
/home/jdk/openjdk-8u60-make/bin/java -version
openjdk version "1.8.0-internal-fastdebug"
OpenJDK Runtime Environment (build 1.8.0-internal-fastdebug-root_2020_03_22_10_01-b00)
OpenJDK 64-Bit Server VM (build 25.60-b23-fastdebug, mixed mode)
接下來讓我們驗證
找一個java執行的,又比較複雜的,我選用metabase
去metabase的官網下載下傳執行的jar
寫一個run.sh
export MB_DB_TYPE=mysql
export MB_DB_DBNAME=metabase
export MB_DB_PORT=3306
export MB_DB_USER=賬号
export MB_DB_PASS=密碼
export MB_DB_HOST=mysql所在機器
/home/jdk/openjdk-8u60-make/bin/java -jar metabase.jar
執行起來
中間一個小插曲,metabase最後初始化資料庫連接配接的時候沒有成功,提示
Timed out after 5.0 s
這個問題搞得好惱火,一直沒有解決,關防火牆也不管用,換成Oracle的JDK也不行,看來應該是我建立虛拟機的時候把網絡的什麼東西設定壞了,先放在一邊吧
從已經執行的日志看,編譯的jdk是能夠順利運作的
恭喜,至此終于編譯成功
可以打包拿去用了