Question

I have written a Class with premain method and inside that method I have added a ClassFileTransformer to Instrumentation (Instrumentation.addTransformer()).

I have invoked a application using

java -javaagent:<path_to_agnet.jar> <application>

However ClassFileTransformer.transform() method is not being invoked.
I have observed that premain is being invoked.
I have also observed that if I call Instrumentation.retransformClasses(), then ClassFileTransformer.transform() is being invoked.
On first definition (Classloader.defineClass()), transform() method is not being invoked.

Any clue what could be wrong?

Note: I can post the source code if that is of any help.

Regards, Rejeev.

Was it helpful?

Solution

Possible causes

.

Incorrect MANIFEST

Did you follow all the steps required to define an Instrumentation class ?

Especially the "packaging" step, which involve specifing a slightly different set of attributes in the JAR’s manifest:

  • Instead of Main-Class, you must specify a Premain-Class attribute that gives the full class-name of the class that implements premain() in your agent.
Premain-Class: my.package.MyAgentClass
  • If your agent uses any class-libraries, then you should specify the Boot-Class-Path attribute, since your instrumentation agent will need its libraries to be visible from the bootstrap classloader.
    If you don’t do this, you will probably have to use the wacky -Xbootclasspath/a:... argument to the JVM.
    The command-line argument is a decent way to get things going, but you want to use this attribute in the long-run, because the command-line is already growing from having to specify the Java instrumentation agent. Might as well keep it as simple as possible.

  • Finally, there is the Can-Redefine-Classes attribute.
    If it is set to true, then the Java instrumentation agent is able to redefine the classes that the agent itself uses.
    This is a pretty odd circumstance, and certainly won’t arise much.

.

Silent Exception

(Rejeev Divakaran got that one).

I was using classBeingRedefined.getName() to print the class name.
classBeingRedefined is null when it is loaded first time.

The bottom line is if there is uncaught exception in transform method.
It will be silently eaten up.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top