3 Replies Latest reply: Jan 26, 2010 8:41 AM by Darryl Burke RSS

    java.lang.instrument and class hierarchy

    843798
      Hi all,

      I have a problem I am not able to solve. Let's assume we have the following two classes and an inheritance relationship:

      public class A {

      }

      public class B extends A {

      public void foo() {
      // do nothing
      }

      }

      I want to instrument additional code such that it looks as follows:

      public class A {

      public void print() {
      ...
      }

      }

      public class B extends A {

      public void foo() {
      super.print();
      }

      }

      In order to achieve this goal, I based my implementation on the java.lang.instrument package, using an Agent with my own class file transformer. Piece of cake so far.
      Now, my test method does the following:

      B b = new B();
      b.foo();

      This does not work due to the following restriction in the instrumentation package: when calling new B(), the instrumentation starts with class B and ends up in a compilation error when loading its bytecode in the VM as the super class A has no print() method yet! The question arises if and how I can trigger the instrumentation of class A before class B. The transform() method of my classfiletransformer should be invoked with class A explicitly! So I started reading and bumped into this:

      The java.lang.instrument.ClassFileTransformer.transform()'s javadoc says:
      The transformer will be called for every new class definition and every class redefinition. The request for a new class definition is made with ClassLoader.defineClass. The request for a class redefinition is made with Instrumentation.redefineClasses or its native equivalents.

      The transform method comes along with a class loader instance, so I thought, why not calling the defineClass method myself with class A when the instrumentation of B has started.
      In order to be able to call the protected redefine method, I made use of reflection: I changed the modifier to public (accessible) and called the method. I expected that the instrument method will be called as a result but sadly this was not the case. Instead the class A was loaded without instrumentation.

      Any ideas, how to solve this problem?

      Thanks a lot!
        • 1. Re: java.lang.instrument and class hierarchy
          843798
          Unfortunately, I wasn't able to figure out a solution for this problem. I was hoping that I could at least find out why it is not possible to load another class through an agent while being in the instrumentation process of the same agent.

          Do u see a reason why this should not be possible?

          cheers
          Christoph
          • 2. Re: java.lang.instrument and class hierarchy
            843798
            I have similar issue related to instrumenting a class's constructor ( or method) which accept another user-defined class as argument. The user-defined class is not loaded yet when my ClassFileTransformer.transform() method is called for the Target class. As a result, my instrumenting code (using Javassist) cannot compile the target class.

            For example:

            public class Target {
            public Target(UserDefinedType type) {
            ...
            }

            ...
            }

            If UserDefinedType is not loaded when I instrument Target, the Javassist call throws an CannotCompileException when calling CtConstructor.insertBeforeBody() for the class Target.

            I think the solution would be related to changing the order the Jvm loads the classes and make sure UserDefinedType is loaded before Target. Anybody has any idea how to do this?

            Edited by: alec_lee_yl on Jan 26, 2010 3:14 PM
            • 3. Re: java.lang.instrument and class hierarchy
              Darryl Burke
              alec_lee_yl, please don't post in threads that are long dead. When you have a question, start your own topic. Feel free to provide a link to an old post that may be relevant to your problem.

              I'm locking this thread now.

              db