how to specify class path for java agent
Asked Answered
E

2

5

I am write a Java Agent to instrument a target Method of a target Class.

I use the javassist library to do instrument.

So the java agent (let named CnAgent.class) need its dependency : javassist library to run.

The directory hierarchy is :

.
├── META-INF
│   └── MANIFEST.MF
├── com
│   └── yet
│       └── another
│           └── test
│               └── agent
│                   ├── CnAgent.class
│                   └── CnTransformer.class
└── lib
    └── javassist-3.18.2-GA.jar

and the MANIFEST.MF file content is :

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

I create jar ball by following command:

jar cvfm CnAgent.jar META-INF/MENIFIEST.MF . lib

when I load the Agent with Attach API of JVM. the error prints :

error when transform : javassist/ClassPool
java.lang.NoClassDefFoundError: javassist/ClassPool

which means the javassist library cannot be found by agent code.

So my question is :

  1. How to set Agent library's class path letting it find the dependencies?

  2. Why the Class-Path option in MANIFEST.MF not works , does it only for jar directly ran in command line ?

Thanks your wisdom :)

Em answered 9/10, 2014 at 13:59 Comment(2)
Try using Boot-Class-Path instead of Class-Path (without the dot .).Nelsen
WARNING: javassist-3.18.2-GA.jar not added to bootstrap class loader search: Illegal argument or not JAR fileEm
I
5

You can use the option -Xbootclasspath: (sets the path) or -Xbootclasspath/a: (appends the given path to the existing boot class path) (refer to doc from oracle). But, as described in the link, it is non-standard.

As an alternative, you can copy the missing jar file in the %JAVA_HOME%/jre/lib/ext directory.

Igenia answered 12/12, 2014 at 21:52 Comment(0)
A
5

Per Guido's comment above, you should add Boot-Class-Path to your agent MANIFEST.MF.

See these java.lang.instrumentation docs (Manifest Attributes section)

In my case, I have this in Ant's 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>

and then copy the guice and guava jars to the directory I run the command from e.g. java -verbose:class -javaagent:poa.jar -jar ExampleProject.jar > loaded.txt

This also lists all the classes loaded to allow you to debug what Java class loader is actually doing.

Neither option from whiskeyspider worked for my case.

Alamein answered 14/6, 2017 at 14:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.