Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bytecode instrumentation using ClassFileTransformer.transform

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.

like image 884
Rejeev Divakaran Avatar asked Apr 08 '09 10:04

Rejeev Divakaran


People also ask

What is bytecode instrumentation?

Bytecode instrumentation is a process where new function- ality is added to a program by modifying the bytecode of a set of classes before they are loaded by the virtual machine. This paper will look into the details of bytecode instrumen- tation in Java: the tools, APIs and real-life applications.

What is ClassFileTransformer?

public interface ClassFileTransformer. A transformer of class files. An agent registers an implementation of this interface using the addTransformer method so that the transformer's transform method is invoked when classes are loaded, redefined , or retransformed .

What is instrumentation API?

API instrumentation identifies the time that elapsed during application activities. It is used for applications and products that use the IBM Spectrum Protect API. By default, instrumentation data is automatically collected by the API during backup or restore processing.

What is instrumentation API in Java?

Instrumentation is the addition of byte-codes to methods for the purpose of gathering data to be utilized by tools. Since the changes are purely additive, these tools do not modify application state or behavior.


1 Answers

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.

like image 199
VonC Avatar answered Oct 22 '22 16:10

VonC