1 Reply Latest reply on May 4, 2013 4:07 AM by user11436730

    BytecodeInstrumentation : agent hooking seems not working.

      Requirement :
      Want to hook agent statically( as of now ) and attach the custome classfiletransformer to it so that can manipulate the byte code the object, if needed.

      Problem Statement :
      Currently premain method is getting executed and I have added the transformer instance with the instrumentation instance provided as argument in the method but still the transform() method is not getting called for the subsequent loading objects.

      Following is my code structure :
      MyObject.java - Pojo to check the bytecode instrumentation, test purpose only
      HookAgent.java - Java Agent Class
      MyClassTransformer.java - Customer Class Transformer
      MANIFEST.MF - Manifest file of the jar archive

      Code :
      package com.test.object;
      public class MyObject {
           public String getInfo() {
                return toString();
           public String toString() {
                return "MyObject:"+hashCode();
      package com.test;
      import java.lang.instrument.Instrumentation;
      public class HookAgent {
           private static Instrumentation _inst;
           public static void premain(String args,Instrumentation inst) throws Exception {
                System.out.println("Inside premain() : Args : " + args + ", Instrumentation : " + inst);
                _inst = inst;
                _inst.addTransformer(new MyClassTransformer());
           public static void agentmain(String args,Instrumentation inst) {
                System.out.println("Inside agentmain() : Args : " + args + ", Instrumentation : " + inst);
                _inst = inst;
                _inst.addTransformer(new MyClassTransformer());
      package com.test;
      import java.lang.instrument.ClassFileTransformer;
      import java.lang.instrument.IllegalClassFormatException;
      import java.security.ProtectionDomain;
      public class MyClassTransformer implements ClassFileTransformer {
           public MyClassTransformer() {
                System.out.println("MyClassTransformer() ... starting construction...");
           public byte[] transform(ClassLoader arg0, String arg1, Class<?> arg2,
                     ProtectionDomain arg3, byte[] arg4)
                     throws IllegalClassFormatException {
                System.out.println("Inside transform() : ClassLoader : " + arg0 + 
                          "Arg1 : " + arg1 +
                          "Class : " + arg2.getName() +
                          "ProtectedDomain : " + arg3 + 
                          "byte : " + arg4) ;
                return null;
      Main-Class: com.test.main.MainClass
      Agent-Class: com.test.HookAgent
      Can-Redefine-Classes: true
      Can-Retransform-Classes: true
      Premain-Class: com.test.HookAgent
      package com.test.main;
      import com.test.object.MyObject;
      public class MainClass {
           public static void main(String[] args) {
                System.out.println("Main started....");
                System.out.println("Args : " + args.length);
                System.out.println(new MyObject().getInfo());
                System.out.println("Main completed...");
      Current Output :
      $ java -javaagent:../myjar.jar com.test.main.MainClass test test1 test2

      Inside premain() : Args : null, Instrumentation : sun.instrument.InstrumentationImpl@7587b2
      MyClassTransformer() ... starting construction...
      Main started....
      Args : 3
      Main completed...

      I expected that the arguments (run time to main) would also appear in first argument of premain() method but that's not the case and also, there is no call to the transform() method that takes place when MyObject or even MainClass is loaded.

      Appreciate any help on this.
      Thanks in advance.

      Edited by: user11436730 on May 3, 2013 11:11 PM
        • 1. Re: BytecodeInstrumentation : agent hooking seems not working.
          I have found the problem and understood the behavior.

          Problem 1: The args were not received by the premain() method as received by the main() method.
          Reason : The argument is not passed implicitly to the premain() method once passed to the main method, instead the argument needs to be passed explicitly while invoking the java program. For example :

          java -javaagent:../myjar.jar=testargs com.test.main.MainClass testargs

          Problem 2 : tranform() in MyClassTranformer is not invoked for the subsequently loading classes.
          Reason : The method was getting invoked but due the sysout given the transform() method was throwing exception as classname argument was null and .getName() was invoked on that,after removing the method is getting invoked in proper flow.