我正在编写一个Java代理来检测目标类的目标方法。
我使用javassist库来做乐器。
所以java代理(让我们命名为CnAgent.class)需要它的依赖:javassist库来运行。
目录层次结构为:
.
├── META-INF
│ └── MANIFEST.MF
├── com
│ └── yet
│ └── another
│ └── test
│ └── agent
│ ├── CnAgent.class
│ └── CnTransformer.class
└── lib
└── javassist-3.18.2-GA.jar
和MANIFEST.MF文件内容为:
Manifest-Version: 1.0
Class-Path: lib/javassist-3.18.2-GA.jar .
Agent-Class: com.yet.another.test.agent.CnAgent
Created-By: 1.8.0_11 (Oracle Corporation)
Can-Retransform-Classes: true
我按照以下命令创建了jar球:
jar cvfm CnAgent.jar META-INF/MENIFIEST.MF . lib
当我使用JVM的Attach API加载代理时。 错误打印:
error when transform : javassist/ClassPool
java.lang.NoClassDefFoundError: javassist/ClassPool
表示代理程序代码无法找到javassist库。
所以我的问题是:
如何设置代理库的类路径,让它找到依赖项?
为什么MANIFEST.MF中的Class-Path选项不起作用,是否仅在jar中直接在命令行中运行?
感谢你的智慧:)
答案 0 :(得分:3)
您可以使用选项-Xbootclasspath :(设置路径)或-Xbootclasspath / a :(将给定路径附加到现有引导类路径)(请参阅doc from oracle)。但是,如链接中所述,它是非标准的。
作为替代方法,您可以将缺少的jar文件复制到%JAVA_HOME%/ jre / lib / ext目录中。
答案 1 :(得分:0)
上面的每Guido's条评论,您应该向代理商Boot-Class-Path
添加MANIFEST.MF
。
请参阅这些java.lang.instrumentation
文档(清单属性部分)
就我而言,我在Ant的build.xml中有这个:
<manifest file="META-INF/MANIFEST.MF">
<attribute name="Premain-Class" value="de.bodden.tamiflex.playout.Agent"/>
<attribute name="Main-Class" value="de.bodden.tamiflex.playout.Agent"/>
<attribute name="Can-Retransform-Classes" value="true"/>
<attribute name="Implementation-Version" value="${tf.version}"/>
<attribute name="Boot-Class-Path" value="guava-22.0.jar:guice-4.1.0.jar" />
</manifest>
然后将guice和guava jar复制到我运行命令的目录中。 java -verbose:class -javaagent:poa.jar -jar ExampleProject.jar > loaded.txt
这也列出了所有加载的类,以便您调试Java类加载器实际正在执行的操作。
whiskeyspider的选项都不适用于我的案例。