jdk源码写过注释后debug提示source code does not match the bytecode

4 篇文章 0 订阅
1 篇文章 0 订阅

一、问题说明

环境说明:

jdk:jdk1.8.0_161

阅读过jdk源码的人,肯定遇到过这个问题:当你在源码中写过注释,然后再次打断点,你就会发现提示你“Source code does not match the bytecode”。接下来我们来解决这个问题

如果不清楚如何在idea中搭建jdk1.8源码阅读环境的,可以参看https://blog.csdn.net/u010999809/article/details/101922489

二、解决问题

我在网上找了下,有现成的解决方法,就是再重新编译一次带调试信息的jdk源码(https://www.jb51.net/article/115931.htmhttps://blog.csdn.net/wl23301/article/details/35792235https://stackoverflow.com/questions/18255474/debug-jdk-source-cant-watch-variable-what-it-is

提前解释下名词,底下说的源码,是指你写过注释后的源码

简单再说下步骤:

把源码解压放到f盘(放到根目录,这样路径不用写太长),在f盘创建jdk_debug目录

进到f盘根目录,打开cmd命令窗口
1. 生成需要编译的文件列表
dir /B /S /X src\*.java > filelist.txt

2. 执行编译操作(rt.jar是在JDK_HOME\jre\lib下找的,tools.jar是在JDK_HOME\lib下找的)
javac -J-Xms16m -J-Xmx1024m -sourcepath f:\src -cp f:\rt.jar;f:\tools.jar -d f:\jdk_debug -g @filelist.txt >> log.txt 2>&1
(如果只是编译一小部分,只用rt.jar没问题;要编译完整的,就还得加上tools.jar)

3. 生成rt_debug.jar
进入jdk_debug目录执行命令jar cf0 rt_debug.jar *

4. 把新生成的jar包放到JDK_HOME\jre\lib\endorsed中(如果没有endorsed文件夹,则手动创建)

既然这个过程已经非常明确了,我就想能不能写成一个bat脚本,每次只要执行过一次,sourcecode就和bytecode就一致了,毕竟每次都要手动敲一遍上面这个步骤还是比较费时间的

下面是我写的脚本(里面保留了一些注释,如果要调试的话,解开某些部分,或者自己添加都可以),里面注释写的很详细

compileSourceCode.bat

@echo off

rem 记录当前位置
set "CURRENT_DIR=%cd%"

rem jdk源码目录
cd ..
set "SOURCE_DIR=%cd%\src"
cd /d %CURRENT_DIR%

rem 编译rt_debug.jar存放的目录
set "RT_DEBUG_DIR=%CURRENT_DIR%\jdk_debug"

rem jdklib目录(编译代码要用的)
rem set "LIB_PATH=%JAVA_HOME%\jre\lib\rt.jar;%JAVA_HOME%\lib\tools.jar"
set "LIB_PATH=%JAVA_HOME%\jre\lib\rt.jar %JAVA_HOME%\lib\tools.jar"

rem rt_debug.jar需要存放的位置
set "RT_DEBUG_ENDORSED_DIR=%JAVA_HOME%\jre\lib\endorsed"

rem 显示JAVA_HOME变量
rem echo "%JAVA_HOME%"

rem 如果jdk_debug不存在,则进行创建
if not exist "%RT_DEBUG_DIR%" mkdir "%RT_DEBUG_DIR%"

rem 生成需要编译的文件列表
dir /B /S /X "%SOURCE_DIR%\*.java" > "%CURRENT_DIR%\filelist.txt"

rem 执行编译操作
rem javac可能不支持在指定cp的时候,写不同路径的jar包,这里简单起见,直接把rt.jar和tools.jar复制到当前目录下
rem javac -J-Xms16m -J-Xmx1024m -encoding UTF-8 -sourcepath %SOURCE_DIR% -cp %LIB_PATH% -d %RT_DEBUG_DIR% -g @filelist.txt >> log.txt 2>&1

rem 批量将jar包复制到当前目录下(如果不存在,则复制过去)
rem 临时存放路径的变量
set "my_path="
setlocal EnableDelayedExpansion
for %%i in (%LIB_PATH%) do (
rem setlocal
call:getFileName "%%i"
if not exist "!my_path!" copy /y "%%i" "%CURRENT_DIR%"
rem endlocal
)
setlocal DisableDelayedExpansion

javac -encoding UTF-8 -J-Xms16m -J-Xmx1024m -sourcepath %SOURCE_DIR% -cp rt.jar;tools.jar -d %RT_DEBUG_DIR% -g @filelist.txt >> log.txt 2>&1

rem 生成rt_debug.jar
cd /d "%RT_DEBUG_DIR%"&&jar cf0 rt_debug.jar *

rem 把新生成的jar包放到JDK_HOME\jre\lib\endorsed中(如果没有endorsed文件夹,则手动创建)
if not exist "%RT_DEBUG_ENDORSED_DIR%" mkdir "%RT_DEBUG_ENDORSED_DIR%"
copy /y "%RT_DEBUG_DIR%\rt_debug.jar" "%RT_DEBUG_ENDORSED_DIR%\rt_debug.jar"

rem pause&goto:eof
goto:eof&exit


rem 自定义函数:通过全路径获得文件名
:getFileName
rem for %%a in ("%~1") do (echo %%~nxa)
rem for %%a in ("%~1") do (echo %CURRENT_DIR%\%%~nxa)
for %%a in ("%~1") do (
set "my_path=%CURRENT_DIR%\%%~nxa"
)
goto:eof

rem 参考链接
rem 如何在bat脚本中定义函数? https://www.jb51.net/article/53016.htm
rem 如何从文件全路径中提取文件名? https://blog.csdn.net/techfield/article/details/83061295
rem 常用匹配模式 https://www.jb51.net/article/97588.htm
rem for循环中无法改变变量的值 https://zhidao.baidu.com/question/140583844767053805.html
rem https://www.cnblogs.com/mq0036/p/3478108.html

三、对脚本的说明

我在网上看到过很多提供脚本文章,可能由于作者本身个人习惯原因,通常可能相关的环境(目录之间的层级关系是否有特定要求,如果需要做修改哪些地方是需要注意的)不会说的太详细,导致别人在拿来用的时候,需要花大量的时间来进行调试。这里我做下说明:

我创建了一个普通的java项目,如下图所示,

src目录下就是jdk源码,

test目录放的是单元测试,

scripts目录下只用放一个compileSourceCode.bat脚本文件,该目录里其他的东西都是bat脚本执行后产生的

我目前觉得自己的目录结构算是划分的比较清晰的,如果有人有需要看源码的我也会建议按我这种方式。

bat脚本里面主要就是SOURCE_DIR,RT_DEBUG_DIR这两个目录,其他都是固定的,没什么可改的

用的话,非常简单,给jdk源码写过注释后,再双击下compileSourceCode.bat,等个2~3min就ok了

 

参考链接: 

如何编译带调试信息的jdk源码?(这几个链接我都看过,都差不多,我通常会找中文和英文的相关链接来做验证,一般我会更偏重于找英文的解答)

https://www.jb51.net/article/115931.htm

https://blog.csdn.net/wl23301/article/details/35792235

https://stackoverflow.com/questions/18255474/debug-jdk-source-cant-watch-variable-what-it-is

写bat脚本时参考的链接(写的过程确实比较曲折,因为平时工作不需要写脚本,导致这块很生疏,查了很多资料;但是想想一个脚本可以节省出很多重复敲代码的时间,觉得这还是挺值得的)

如何在bat脚本中定义函数?https://www.jb51.net/article/53016.htm

如何从文件全路径中提取文件名?https://blog.csdn.net/techfield/article/details/83061295

常用匹配模式 https://www.jb51.net/article/97588.htm

for循环中无法改变变量的值 https://zhidao.baidu.com/question/140583844767053805.html

https://www.cnblogs.com/mq0036/p/3478108.html

 

  • 10
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值