Fwd: Re: subclass and superclass transformation question

Peter Veentjer <[email protected]>
Newsgroups gmane.comp.java.objectweb.asm
Message-ID <[email protected]>
Hi Tronje,

I'm still strugling with the same issues, but I have one answer to
your questions.

It is about adding new classes to the classloader, I use the following
code for that:

 private final static Method defineClassMethod;

   static {
       try {
           defineClassMethod = ClassLoader.class.getDeclaredMethod(
                   "defineClass",
                   String.class,
                   byte[].class,
                   int.class,
                   int.class);
           defineClassMethod.setAccessible(true);
       } catch (NoSuchMethodException e) {
           throw new RuntimeException(e);
       }
   }

   public static Class defineClass(ClassLoader classLoader, String
className, byte[] bytecode) {
       //System.out.println("definingClass: "+className);
       try {
           return (Class) defineClassMethod.invoke(
                   classLoader,
                   className.replace("/", "."),
                   bytecode,
                   0,
                   bytecode.length);
       } catch (IllegalAccessException e) {
           throw new RuntimeException(format("A problem occurred
while defining class '%s'", className), e);
       } catch (InvocationTargetException e) {
           throw new RuntimeException(format("A problem occurred
while defining class '%s'", className), e);
       }
   }

This works for me. This code can be called from your Javaagent when it
wants to create additional classes.

This is good enough for IDE support.. I'm also working on a
compiletime instrumentation
for production environments.

On Thu, Feb 25, 2010 at 12:23 AM, Tronje Krop <[email protected]> wrote:
> Hi all,
>
> thanks for the advice from all of you. This discussion has cleared
> up a view questions I had for some time:
>
> In my current rewriter that is directly linked to the class loader,
> I load all classes by getResourceAsStream. I have managed to do load,
> analyse, and define all classes in the right order, which was as I
> must admit quite tricky ... problems with cyclic class loading etc ...
> but however, in the end it worked.
>
> Making it work in parallel will be a challenge, as I have to protect
> the analysis information on class level in the right way. In addition
> I have to block multiple requests on the same class until the rewrit-
> ten and defined class is available - right?
>
> The advantage here is, I can test this with the conventional class
> loader pattern.
>
> Now, when I switch to the agent concept, I have to wait for each
> class until the bytecode is provided to the transformer before I
> returning the rewritten bytecode. Anyhow, I'm allowed to load all
> resources needed for analysis from the class loader using
> getResourceAsStream().
>
> The big questions remaining are:
>
> (1) How am I supposed to introduce new classes on the fly in the
> agent concept - may be be defineClass() of the class loader?
>
> (2) When it is allowed to use defineClass() of the class loader,
> what is the difference against loading a class using getResource-
> AsStream() and defining it in the class loader?
>
> (3) Wouldn't the getResourceAsStream() concept fail, if another
> transformer modifies a class before it is provided to my transformer?
>
> Any suggestions how this is best handled?
>
> CU Tronje
>
> Marcel Patzlaff wrote:
>> Just load the parent classes/interfaces as resources and analyse them
>> with ASM. If you have to perform modifications, you should do what
>> Eugene suggested: Prepare the transformations virtually and apply them
>> if the classloader eventually loads the parent classes/interfaces.
>>
>> Regards,
>> Marcel
>>
>> Tronje Krop schrieb:
>>> I'm currently not using the java agent, but I like to do son in
>>> future.
>>>
>>> My problem concerning the order of class loading is, that I need
>>> at least to analyse parent classes and interfaces before trans-
>>> forming the subclasses.
>>>
>>> But how can I do this without forcing the class loader to load
>>> interfaces and parent classes. Any suggestion?
>>>
>>> CU Tronje
>>>
>>> Eugene Kuleshov wrote:
>>>
>>>>   I wouldn't advise loading classes from the agent. Instead you should
>>>> be able to prepare required transformations "virtually" when
>>>> analyzing/loading subclasses, save some state and do the actual
>>>> transformation when parent is actually loaded by JVM.
>>>>
>>>>   regards,
>>>>   Eugene
>>>>
>>>>
>>>> On Tue, Feb 23, 2010 at 10:01 AM, Rémi Forax <[email protected]> wrote:
>>>>
>>>>> Hi Peter,
>>>>>
>>>>> Le 23/02/2010 14:49, Peter Veentjer a écrit :
>>>>>
>>>>>> I have a question about the details of superclass/subclass
>>>>>> transformations using a Java agent.
>>>>>>
>>>>>> If there is a class Fruit and a subclass Apple, and if a new Apple is
>>>>>> created before the Fruit class is used in the JVM.
>>>>>> What is the exact order of classes loaded in the Java agent?
>>>>>>
>>>>>> My experience is that the Apple class is transformed before the Fruit
>>>>>> class is transformed. Is this correct?
>>>>>>
>>>>>>
>>>>> Yes, the VM read the transformed class, find the super class and load it,
>>>>> so superclass are loaded after class if there aren't loaded before.
>>>>>
>>>>> But you can load the superclass in the agent :)
>>>>> you have the classloader and you can find the superclass in the classfile.
>>>>> Just be careful about synchronisation, jdk7 classloading is done in
>>>>> parallele.
>>>>>
>>>>>
>>>>>
>>>>>> And is there any way to force to load the super class (Fruit) is
>>>>>> transformed before the subclass Apple is transformed?
>>>>>>
>>>>>> I have the impression that the Java agent technology is very limited
>>>>>> and that the only way to solve these issues is
>>>>>> to do a static transformation. The big problem is that it makes the
>>>>>> system much harder to work with from an IDE; normally
>>>>>> you only need to register some javaagent and you are done. But adding
>>>>>> a postcompilation step is much harder.
>>>>>>
>>>>>>
>>>>> Rémi
>>>>>
>>>>>
>>>>> --
>>>>> You receive this message as a subscriber of the [email protected] mailing list.
>>>>> To unsubscribe: mailto:[email protected]
>>>>> For general help: mailto:[email protected]?subject=help
>>>>> OW2 mailing lists service home page: http://www.ow2.org/wws
>>>>>
>>>>>
>>>>>
>>>
>>
>
>
> --
> You receive this message as a subscriber of the [email protected] mailing list.
> To unsubscribe: mailto:[email protected]
> For general help: mailto:[email protected]?subject=help
> OW2 mailing lists service home page: http://www.ow2.org/wws
>
>
message-footer.txt (text/plain, 238 B)
-- 
You receive this message as a subscriber of the [email protected] mailing list.
To unsubscribe: mailto:[email protected]
For general help: mailto:[email protected]?subject=help
OW2 mailing lists service home page: http://www.ow2.org/wws
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.