从检测方法调用自己的类时出现 Java NoClassDefFoundError
我正在开发一套简单的 Java 代理工具包,以帮助我(也希望其他人)排除 Java 应用程序的故障。我想创建的代理之一是 JComponent.getToolTipText() 方法,只需将鼠标光标悬停在任何 GUI 类上即可快速识别该类。
您可以在这里找到我的变压器的代码和项目的其余部分:
我启动测试 GUI,并附加了代理,如下所示:
$ java -javaagent:target/jars/sfn-0.1-agent.jar=JComponent -cp lib/jars/bcel-5.2.jar:target/jars/sfn-0.1-test.jar:target/jars/sfn-0.1-agent.jar org.leplus.sfn.test.Main
sfn-0.1-agent.jar 包含 org.leplus.sfn.transformer.JComponentTransformer 类。 sfn-0.1-test.jar 包含 org.leplus.sfn.test.Main 类。
以下是当我启动应用程序并将鼠标放在它上面时,应用程序打印的内容:
Loading agent: JComponent Instrumentation ready! Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/leplus/sfn/tracer/ComponentTracer at javax.swing.JComponent.getToolTipText(JComponent.java) at javax.swing.ToolTipManager$insideTimerAction.actionPerformed(ToolTipManager.java:662) ...
令我惊讶的是,如果我更改变压器以调用 JRE 中的任何类,它就会起作用。但是当我调用自己的类org.leplus.sfn.tracer.ComponentTracer时它不起作用。我的第一个猜测是类路径问题,但 ComponentTracer 既在类路径中又在代理的 jar 中。所以我迷路了。
如果你们中有人看到我遗漏了什么。
干杯,
汤姆
I am working on a kit of simple Java agents to help me (and hopefully others) troubleshoot Java applications. One of the agents I would like to create instruments the JComponent.getToolTipText() method to quickly identify any GUI class by just hovering the mouse cursor over it.
You can find the code of my transformer and the rest of the project here:
I launch my test GUI with the agent attached as follow:
$ java -javaagent:target/jars/sfn-0.1-agent.jar=JComponent -cp lib/jars/bcel-5.2.jar:target/jars/sfn-0.1-test.jar:target/jars/sfn-0.1-agent.jar org.leplus.sfn.test.Main
sfn-0.1-agent.jar contains the org.leplus.sfn.transformer.JComponentTransformer class.
sfn-0.1-test.jar contains the org.leplus.sfn.test.Main class.
Here is what the application prints when I launch it and I put the mouse over it:
Loading agent: JComponent Instrumentation ready! Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/leplus/sfn/tracer/ComponentTracer at javax.swing.JComponent.getToolTipText(JComponent.java) at javax.swing.ToolTipManager$insideTimerAction.actionPerformed(ToolTipManager.java:662) ...
What is surprising to me is that if I change my transformer to call any class from the JRE, it works. But it doesn't work when I call my own class org.leplus.sfn.tracer.ComponentTracer. My first guess was a classpath issue but the ComponentTracer is both in the classpath and in the agent's jar. So I am lost.
If any of you see where I am missing something.
Cheers,
Tom
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个类加载器问题。您正在检测由引导类加载器管理的类 (javax.swing.JComponent),并让它引用由系统类加载器管理的类 (org.leplus.sfn.tracer.ComponentTracer)。
如果将 ComponentTracer 类放入引导类加载器中,问题就会消失。
It's a class loader issue. You're instrumenting a class (javax.swing.JComponent) managed by the bootstrap class loader, and having it refer to a class (org.leplus.sfn.tracer.ComponentTracer) managed by the system class loader.
If you put your ComponentTracer class in the bootstrap class loader, the problem should disappear.
尝试使用 -DDEBUG 运行,因为它可能会显示更多信息。
另外,我在这里看到了目标目录。 http://sfn.cvs.sourceforge.net/viewvc/sfn/core/ target/ 它包含一个classes文件夹,但没有jars文件夹?检查以确保 jar 路径相对于项目根目录。
Try running with -DDEBUG as it might show you more information.
Also, I see the target directory here. http://sfn.cvs.sourceforge.net/viewvc/sfn/core/target/ It contains a classes folder, but no jars folder? Check to make sure the jar paths are relative to the project root.