Java 调试jdk源无法观察变量是什么
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18255474/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
debug jdk source can't watch variable what it is
提问by Amitābha
I'm debugging the JDK source like:
我正在调试 JDK 源代码,例如:
public static int codePointAt(CharSequence seq, int index) {
char c1 = seq.charAt(index++);
if (isHighSurrogate(c1)) {
if (index < seq.length()) {
char c2 = seq.charAt(index);
if (isLowSurrogate(c2)) {
return toCodePoint(c1, c2);
}
}
}
return c1;
}
and I want to see c1
variable before I step into if (isHighSurrogate(c1))
.
However, when I debug watch c1
variable
it display :
我想c1
在进入if (isHighSurrogate(c1))
. 但是,当我调试监视c1
变量时,它显示:
I really have tried added rt.jar source, and it really can step into breakpoint of JDK source, like:
我确实尝试过添加rt.jar源,它确实可以进入JDK源的断点,例如:
but why c1
variable can't display?
但是为什么c1
变量不能显示?
采纳答案by c.s.
Generally speaking, to be able to watch the variables while stepping through JDK source code, you need the class files to be compiled with debug information i.e. compile using javac -g
.
一般来说,为了能够在单步执行 JDK 源代码的同时观察变量,您需要使用调试信息编译类文件,即使用javac -g
.
So your best bet is to either find an already compiled version with debug information (I couldn't find anything for JDK 7) or you can try compiling the source for yourself.
因此,您最好的选择是找到带有调试信息的已编译版本(我找不到 JDK 7 的任何内容),或者您可以尝试自己编译源代码。
According to this post(please note that I haven't tried it) you don't need to compile all sources, only the ones you need. Putting your newly compiled classes in the $jdk/jre/lib/
ext/endorsed
directory, the new classes would be used instead the ones in the original rt.jar
.
根据这篇文章(请注意,我还没有尝试过),您不需要编译所有源代码,只需编译您需要的源代码。将新编译的类放在$jdk/jre/lib/
ext/endorsed
目录中,将使用新类而不是原始rt.jar
.
I believe that should get you started.
我相信这应该让你开始。
Update:Actually I have just tried this process and it is not hard at all. Tested on Windows, JDK 1.7.0_11. All the commands are invoked from command line:
更新:实际上我刚刚尝试过这个过程,它并不难。在 Windows 上测试,JDK 1.7.0_11。所有命令都是从命令行调用的:
- Create your working folder. I chose
d:\
root folder - Inside your working folder create the source folder i.e.
jdk7_src
and output folderjdk_debug
- From your
JDK_HOME
folder get thesrc.zip
file and unzip it insidejdk7_src
- Select what you will compile and delete the rest. For all of them you might need additional steps. I have chosen the folders:
java
javax
org
- From your
JDK_HOME\jre\lib
get the filert.jar
and put in the work folder (this is only for convenience to not specify too large file names in the command line). - Execute the command:
dir /B /S /X jdk7_src\*.java > filelist.txt
to create a file namedfilelist.txt
with the list of all java files that will be compiled. This will be given as input tojavac
- Execute
javac
using the command:javac -J-Xms16m -J-Xmx1024m -sourcepath d:\jdk7_src -cp d:\rt.jar -d d:\jdk_debug -g @filelist.txt >> log.txt 2>&1
This will compile all the files in thejdk_debug
folder and will generate alog.txt
file in your working folder. Check the log contents. You should get a bunch of warnings but no error. - Go inside the
jdk_debug
folder and run the command:jar cf0 rt_debug.jar *
. This will generate your new runtime library with degug information. - Copy that new jar to the folder
JDK_HOME\jre\lib\endorsed
. If theendorsed
folder does not exist, create it.
- 创建您的工作文件夹。我选择了
d:\
根文件夹 - 在您的工作文件夹中创建源文件夹 ie
jdk7_src
和输出文件夹jdk_debug
- 从您的
JDK_HOME
文件夹中获取src.zip
文件并将其解压缩到里面jdk7_src
- 选择您要编译的内容并删除其余内容。对于所有这些,您可能需要额外的步骤。我选择了文件夹:
java
javax
org
- 从您
JDK_HOME\jre\lib
获取文件rt.jar
并放入工作文件夹(这只是为了方便在命令行中不指定太大的文件名)。 - 执行命令:
dir /B /S /X jdk7_src\*.java > filelist.txt
创建一个以filelist.txt
将被编译的所有java文件列表命名的文件。这将作为输入提供给javac
javac
使用命令执行:javac -J-Xms16m -J-Xmx1024m -sourcepath d:\jdk7_src -cp d:\rt.jar -d d:\jdk_debug -g @filelist.txt >> log.txt 2>&1
这将编译文件jdk_debug
夹中的所有文件,并将log.txt
在您的工作文件夹中生成一个文件。检查日志内容。你应该得到一堆警告,但没有错误。- 进入
jdk_debug
文件夹并运行命令:jar cf0 rt_debug.jar *
. 这将生成带有调试信息的新运行时库。 - 将该新 jar 复制到文件夹中
JDK_HOME\jre\lib\endorsed
。如果该endorsed
文件夹不存在,请创建它。
Debug your program in Eclipse. Note how the variables are named normally (no more arg0, arg1 etc). Happy debugging :)
在 Eclipse 中调试您的程序。注意变量是如何正常命名的(不再是 arg0、arg1 等)。调试愉快:)
回答by weberjn
c-s's jre\lib\endorsed solution is great. Easier to build is with Eclipse: create a Java project, put javax*, java* into src and let Eclipse compile. Then export the jar.
cs 的 jre\lib\endorsed 解决方案很棒。使用 Eclipse 更容易构建:创建一个 Java 项目,将 javax*、java* 放入 src 并让 Eclipse 编译。然后导出罐子。
回答by Andrew
This article http://www.thejavageek.com/2016/04/03/debug-jdk-source-code/describe the same but in simple and nice way. You do stuff(compile,make jar) by using eclipse only.
这篇文章http://www.thejavageek.com/2016/04/03/debug-jdk-source-code/描述了相同但简单而漂亮的方式。你只使用 eclipse 来做东西(编译,制作 jar)。
回答by aliopi
Just so you know, the endorsed override mechanism is deprecated and will be removed in a future release(http://docs.oracle.com/javase/8/docs/technotes/guides/standards/).
正如您所知,认可的覆盖机制已被弃用,并将在未来的版本中删除( http://docs.oracle.com/javase/8/docs/technotes/guides/standards/)。
Use this pom.xml
to get JDK 1.8.0_111
sources with debug information:
使用它pom.xml
来获取1.8.0_111
带有调试信息的JDK源代码:
<project>
<modelVersion>4.0.0</modelVersion>
<name>JDK sources with debug information</name>
<groupId>ex.jdk.debug</groupId>
<artifactId>jdk-debug-sources</artifactId>
<version>1.8.0_111</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>jdk-rt</artifactId>
<version>1.8.0_111</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<debug>true</debug>
<debuglevel>lines,vars,source</debuglevel>
<source>1.8</source>
<target>1.8</target>
<excludes>
<exclude>com/sun/java/swing/**</exclude>
<exclude>com/sun/source/util/**</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
You'll have to do a manual install of the original rt.jar
to be able to run mvn clean install
您必须手动安装原始版本rt.jar
才能运行mvn clean install
mvn install:install-file -Dfile=rt.jar -DgroupId=com.oracle -DartifactId=jdk-rt -Dversion=1.8.0_111 -Dpackaging=jar
The rt.jar
I copied to the endorsed
directory is the original rt.jar
but with the original classes replaced by my newly generated classes.
将rt.jar
复制到我endorsed
的目录是原始的rt.jar
,但与我的新生成的类取代了原来的类。
回答by PbxMan
In case anybody needs this with tomcat. You need to set up the VM argument Djava.endorsed.dirs and put your compiled jdk jar in it. You can do this c-s's solution or exported with eclipse(all the Java Compiler ClassFile Generation used by de debugger must be active)
如果有人需要使用tomcat 进行此操作。您需要设置 VM 参数 Djava.endorsed.dirs 并将编译的 jdk jar 放入其中。您可以执行此 cs 的解决方案或使用 eclipse 导出(调试器使用的所有 Java 编译器类文件生成必须处于活动状态)
Go to Run Configurations > Arguments > VM arguments
转到运行配置 > 参数 > VM 参数
Djava.endorsed.dirs="/your/folder/apache-tomcat-xxx/endorsed"
Djava.endorsed.dirs="/your/folder/apache-tomcat-xxx/endorsed"