views:

564

answers:

1

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.

A: 

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.

VonC
Yes I am following all instructions as mentioned in above link. Specifically(1) Premain-Class is specified in manifest (premain method is also invoked)(2) My agent is very minimal and doesn't have any dependancy with any other jar(3) Can-Redefine-Classes and Can-Retransform-Classes are set true
Rejeev Divakaran
Strange. It usually boils down to an incorrect MANIFEST file, but if this not the case, other tests are needed. Can you make the example in the article work (the profiling Transformer) ? That would indicate whether the issue is in your code or in your JDK/JRE configuration.
VonC
Got it! I was using classBeingRedefined.getName() to print the classname. classBeingRedefined is null when it is loaded first time.The bottom line is if there is uncaught exceptino in transform method. it will be silently eaten up.Thanks for all your help.
Rejeev Divakaran