1. 程式人生 > 其它 >Mac OS 給jdk8原始碼加註釋或程式碼

Mac OS 給jdk8原始碼加註釋或程式碼

前言

網上有很多關於除錯檢視jdk原始碼的教程, 但問題在於添加註釋時, 再次進入debug後, 出現行號對應不上的情況.

當然這種情況也有解決辦法, 即自己編譯jdk原始碼, 然後在idea裡直接引入自己編譯的原始碼, 對原始碼修改或添加註釋後, 再增量編譯一下即可.

但問題就在於這個自己編譯jdk原始碼, 這邊編譯出現各種問題, 大部分都有解決方案, 但對於升級了Mac系統後, 很可能無法很好地成功編譯, 同時, 會造成大量的時間浪費

所以, 這裡參考網上的解決方案, 只編譯需要閱讀的部分原始碼


效果



引入原始碼

找到jdk目錄

  • 使用命令 echo $JAVA_HOME 檢視jdk路徑
MacBook:~ user$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home
  • 使用命令 /usr/libexec/java_home 檢視jdk路徑
MacBook:~ user$ /usr/libexec/java_home 
/Library/Java/JavaVirtualMachines/jdk-13.0.2.jdk/Contents/Home

解壓原始碼包


idea引入原始碼


專案引用原始碼


正常閱讀原始碼

這時可以正常閱讀原始碼, 但只能在不改變原始碼行的情況下, 在行末添加註釋
ps: 這是不可接受的



編譯原始碼

建立原始碼專案

建立一個純java專案, 將jdk目錄下的src複製過來:


ps: src/sun原來是沒有的, 參考網上方案的加上的
主要是openjdk8的兩個類: sun.awt.UNIXToolkit.javasun.font.FontConfigManager.java
可以直接到 openjdk 專案下, 指定版本將原始碼複製過來即可



編譯原始碼

使用javac命令, 編譯src原始碼

javac -J-Xms1024m -J-Xmx1024m -sourcepath source_code -cp /path/rt.jar:/path/tools.jar -d classes -g @filelist.txt
  • source_code: 原始碼的絕對路徑, 如: /Volumes/myplace/jdk8src/src
  • /path/rt.jar: 即rt.jar的絕對路徑: 如: /Volumes/myplace/jdk8src/scripts/rt.jar
    • 這個rt.jar是本人為了方便, 直接從$JAVA_HOME/jre/lib/rt.jar複製而來, 放至scripts路徑下
  • /path/tools.jar: 即tools.jar的絕對路徑: 如: /Volumes/myplace/jdk8src/scripts/tools.jar
    • 這個tools.jar是本人為了方便, 直接從$JAVA_HOME/lib/tools.jar複製而來, 放至scripts路徑下
  • classes: 編譯後的class檔案的存放路徑, 如: /Volumes/myplace/jdk8src/classes
  • filelist.txt: 原始碼的java檔案的絕對路徑集合
    • 通過命令: find /Volumes/myplace/jdk8src/src -name "*.java" > filelist.txt得到


生成jar包

進入classes目錄, 執行如下命令生成jar包

jar cf0 rt_debug.jar *


複製到指定目錄

rt_debug.jar包儲存到$JAVA_HOME/jre/lib/endorsed, 即: /Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre/lib/endorsed

ps: 如果endorsed不存在, 直接建立即可



指令碼自動化

既然流程很清楚, 那就建立指令碼來自動執行, 方便使用

在原始碼專案上新增指令碼

  • 指令碼檔案如下, 可參考自己的環境進行修改:
#!/bin/bash

# 注意, mac下, 使用 /bin/bash 執行這個指令碼, 可以編譯成功
# 但使用 /bin/zsh 執行這個指令碼, 編譯失敗, 不知道為什麼....

# 設定開始時間
starttime=`date +%s`

echo "===========編譯開始=============="
echo "--設定基本引數--"
echo ""

# 獲取當前指令碼的路徑
shell_dir=$(cd "$(dirname "$0")";pwd)
echo "shell_dir is : $shell_dir"
echo ""

# 切換到指令碼目錄下
echo "change to $shell_dir"
cd $shell_dir
echo ""

# 獲取當前指令碼路徑
cur_dir=`pwd`
echo "----cur_dir----"
echo "cur_dir is : $cur_dir"
echo ""

# 設定檔案列表 及 檔案的路徑
filelist=$cur_dir"/filelist.txt"
echo "----filelist----"
echo "filelist is : $filelist"
echo ""

# 設定需要的jar包路徑
extlib=$cur_dir"/rt.jar:"$cur_dir"/tools.jar"
echo "----extlib----"
echo "extlib is : $extlib"
echo ""


# 切換到jdk src 原始碼目錄
cd ..
src_project=`pwd`
src_dir=$src_project/src
echo "----src_dir----"
echo "src dir is : $src_dir"
echo ""

# 設定class檔案輸出路徑
src_class=$src_project"/classes"
echo "----src_class----"
echo "src_class is : $src_class"
echo ""

# 將project的src目錄下的所有java檔案的全量名稱存入到project/scripts/filelist.txt檔案中
rm -rf $filelist
find $src_dir -name "*.java" > $filelist
echo ""

# $src_class是存放編譯的class檔案的目錄
rm -rf $src_class
mkdir $src_class
echo "after recreate classes"
echo ""

echo "===========開始編譯=============="
echo "編譯中..."
# 批量編譯java檔案
# 編碼:-encoding utf-8
# 依賴庫以冒號:隔開
#javac -J-Xms1024m -J-Xmx1024m -sourcepath /Volumes/myplace/jdk8src/src -cp /Volumes/myplace/jdk8src/scripts/rt.jar:/Volumes/myplace/jdk8src/scripts/tools.jar -d /Volumes/myplace/jdk8src/classes -g @/Volumes/myplace/jdk8src/scripts/filelist.txt
echo "javac -J-Xms1024m -J-Xmx1024m -sourcepath source_code -cp /path/rt.jar:/path/tools.jar -d classes -g @filelist.txt"
javac -J-Xms1024m -J-Xmx1024m -sourcepath $src_dir -cp $extlib -d $src_class -g @$filelist  >> log.txt 2>&1
echo "編譯中..."
echo "===========編譯結束=============="
echo ""

# 進入classes目錄
cd $src_class
cur=`pwd`
echo "change to classpath dir, current dir is : $cur"
echo ""

# 將class檔案打包成jar包
echo "run command : jar cf0 rt_debug.jar *"
echo "package classes to rt_debug.jar"
jar cf0 rt_debug.jar *
echo ""

# 指定新jar包的存放路徑
rt_debug_endorsed_dir=/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre/lib/endorsed
echo "target dir is : $rt_debug_endorsed_dir"
echo ""

#如果資料夾不存在,建立資料夾
if [ ! -d $rt_debug_endorsed_dir ]; then
  # echo "passwd" | sudo -S shutdown -P now
  echo "vito" | sudo -S mkdir $rt_debug_endorsed_dir -P now
  echo "create target dir"
  echo ""
fi

# 複製jar包到指定路徑
echo "copy rt_debug.jar to target dir: $rt_debug_endorsed_dir"
echo "vito" | sudo -S mv rt_debug.jar $rt_debug_endorsed_dir

echo ""
echo "=====操作結束===="

echo ""
endtime=`date +%s`
echo "本次執行時間: "$((endtime-starttime))"s"

新增使用者配置

  • 進入使用者目錄: cd ~
  • 編譯使用者配置: vim .bash_profile(Mac 各版本可能不同, 按各自版本修改即可)
  • 新增配置: alias compilejdk8="/bin/bash /Volumes/myplace/jdk8src/scripts/compiler.sh"
  • 使用配置生效: source .bash_profile

測試指令碼

  • 開啟終端
  • 輸入命令: compilejdk8, 可以得到如下結果:

  • 指令碼執行成功! 可以愉快的玩耍了~~~~~~



參考來源

jdk原始碼寫過註釋後debug提示source code does not match the bytecode

JDK原始碼寫過註釋後DEBUG提示SOURCE CODE DOES NOT MATCH THE BYTECODE

曹工力薦:除錯 jdk 中 rt.jar 包部分的原始碼(可自由增加註釋,修改程式碼並debug)

利用原始的javac編譯整個Java專案

Mac環境下的Java操作