当前位置: 首页 > article >正文

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

一、问题说明

环境说明:

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.htm,https://blog.csdn.net/wl23301/article/details/35792235,https://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 offrem 记录当前位置
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>&1rem 批量将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 DisableDelayedExpansionjavac -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>&1rem 生成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&exitrem 自定义函数:通过全路径获得文件名
: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:eofrem 参考链接
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

 

http://www.lryc.cn/news/2419419.html

相关文章:

  • nodejs中的__filename和__dirname的使用说明
  • UIE: 信息抽取的大一统模型
  • 推荐使用:jQuery FullScreen 插件 —— 让全屏模式优雅而简单
  • 钓鱼邮件从入门到放弃
  • SWT简介
  • 查看占用网速的程序
  • 【LINUX】linux中修改文件命名
  • isalpha()方法介绍
  • Oracle数据库的下载安装教程
  • 在虚拟机上安装Ubuntu系统(详细附图)
  • 系统流程图
  • 蓝牙技术简介
  • 1分钟带你理解pairwise
  • 设计原则之贰——里氏替换原则
  • C语言中静态变量的作用
  • 开发自己的web搜索引擎——MyGoGo
  • 文本相似度检查实现
  • Codeforces Round #168 (Div. 2) B. Convex Shape(BFS || 模拟)
  • [19/03/16-星期六] 常用类_Date时间类DateFormat类
  • LC滤波器设计学习笔记(一)滤波电路入门
  • adb bugreport :查看设备所有信息(获取错误报告)
  • android gallery3d 源码分析(一)
  • Winpcap的安装使用方法
  • 【论文笔记】Progressive Layered Extraction (PLE): A Novel Multi-Task Learning (MTL) Model for Personalized
  • iptables/netfilter/iproute2/ip/tc/qdisc经常被混淆的几个概念
  • 调色盘管理器
  • 熊猫烧香专杀工具的编写
  • 鱼哭了,水知道。我哭了,谁知道
  • 天虹办公系统kk服务器,客户齐点赞,蓝凌KK 7.0大幅提升工作效率
  • 老牌技术员系统更新啦!(x86/x64)装机版/纯净版 2016.08