如何为java代理指定类路径

Chi*_*ing 5 java jvm jvm-hotspot

我正在编写一个 Java 代理来检测目标类的目标方法。

\n\n

我使用javassist库来做仪器。

\n\n

因此java代理(命名为CnAgent.class)需要它的依赖项:javassist库才能运行。

\n\n

目录层次结构是:

\n\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 META-INF\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 MANIFEST.MF\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 com\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 yet\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 another\n\xe2\x94\x82\xc2\xa0\xc2\xa0         \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 test\n\xe2\x94\x82\xc2\xa0\xc2\xa0             \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 agent\n\xe2\x94\x82\xc2\xa0\xc2\xa0                 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CnAgent.class\n\xe2\x94\x82\xc2\xa0\xc2\xa0                 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 CnTransformer.class\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 lib\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 javassist-3.18.2-GA.jar\n
Run Code Online (Sandbox Code Playgroud)\n\n

MANIFEST.MF 文件内容是:

\n\n
Manifest-Version: 1.0\nClass-Path: lib/javassist-3.18.2-GA.jar .\nAgent-Class: com.yet.another.test.agent.CnAgent\nCreated-By: 1.8.0_11 (Oracle Corporation)\nCan-Retransform-Classes: true\n
Run Code Online (Sandbox Code Playgroud)\n\n

我通过以下命令创建 jar 球:

\n\n
jar cvfm CnAgent.jar META-INF/MENIFIEST.MF . lib\n
Run Code Online (Sandbox Code Playgroud)\n\n

当我使用 JVM 的 Attach API 加载代理时。\n错误打印:

\n\n
error when transform : javassist/ClassPool\njava.lang.NoClassDefFoundError: javassist/ClassPool\n
Run Code Online (Sandbox Code Playgroud)\n\n

这意味着代理代码无法找到 javassist 库。

\n\n

所以我的问题是:

\n\n
    \n
  1. 如何设置代理库的类路径让它找到依赖项?

  2. \n
  3. 为什么 MANIFEST.MF 中的 Class-Path 选项不起作用,它仅适用于直接在命令行中运行的 jar 吗?

  4. \n
\n\n

谢谢你的智慧:)

\n

小智 5

您可以使用选项 -Xbootclasspath: (设置路径)或 -Xbootclasspath/a: (将给定路径附加到现有的引导类路径)(请参阅oracle 中的文档)。但是,正如链接中所述,它是非标准的。

作为替代方案,您可以将丢失的 jar 文件复制到 %JAVA_HOME%/jre/lib/ext 目录中。


Nei*_*eil 5

根据上面Guido 的评论,您应该添加Boot-Class-Path到您的 agent 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>
Run Code Online (Sandbox Code Playgroud)

然后将 guice 和 guava jar 复制到我运行命令的目录,例如java -verbose:class -javaagent:poa.jar -jar ExampleProject.jar > loaded.txt

它还列出了所有已加载的类,以便您调试 Java 类加载器实际执行的操作。

威士忌蜘蛛的选项都不适合我的情况。