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.java
和sun.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