Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] staticinitialization and target class

Although AspectJ tries to create code that decompiles cleanly, there
are some situations where it does not.  The code is fine (otherwise
you'd get a verifyerror), it is just the decompiler that cannot cope -
I don't use them, I just read the bytecode :)  Decompilers usually
match on patterns and if you stray from a common pattern produced by
javac, the decompiler will not understand.

You still didn't mention how it fails....  do you get an error or is
it just not running the advice?

You could register the type by name rather than class reference if
that makes any difference...

Andy

On 28 April 2010 10:14, Mohammad Norouzi <mnrz57@xxxxxxxxx> wrote:
> Thank you Simone and Andy
> Both pointcut and advice are exactly the same you suggested, at first I
> thought there is a problem in advice which makes static block so, and yes I
> am using JD to decompile the code and as you found perhaps that //ERROR// is
> decompiler issue, if it is so, then my static block doesn't work...
>
> Well... As I understand you mean that if I load the class manually say using
> Class.forName() it will be ok however I will give it a try tomorrow but I
> think there are some issues.... first, this class is a EJB session bean and
> since it is a managed object by app server I am not sure if I can load it
> manually second... at deploy time, app server will load it, isn't that
> enough?
>
> thank you for spending your time
>
> On 4/28/10, Simone Gianni <simoneg@xxxxxxxxxx> wrote:
>>
>> Hi Mohammad,
>> I've found this page : http://java.decompiler.free.fr/?q=node/118 , it
>> seems that JD produces the raw bytecode commented when it is not able to
>> decompile it properly, which means that it is JD giving the error, not the
>> code itself in error. I haven't been using JD lately, so I can't remember
>> how to configure it properly, but the bytecode seems correct, so the problem
>> must be somewhere else.
>> Simone
>>
>> 2010/4/28 Simone Gianni <simoneg@xxxxxxxxxx>
>>>
>>> Hi Mohammad,
>>> mmm ... the decompiled bytecode seems correct : it creates a joinpoint
>>> static part, then executes the previous static initializer (which is empty),
>>> and then calls the after advice both when an exception is raised and when no
>>> exception is raised.
>>> Bytecode, AFAIK, cannot be commented out, is that the output of javap, dj
>>> or which other tool?
>>> Obviously, static initializer is executed only when the class is loaded
>>> for the first time in the JVM, if it is not loaded it will not be called and
>>> the class not be registered. Java lacks a serious "service discovery"
>>> system, cause for backward compatibility with applets classloaders does not
>>> have a method for "listing" the classpath, not to mention to list which
>>> classes are annotated with a specific annotations. Apt is the tool that can
>>> ease this pain, creating a text file from classes annotated with a specific
>>> annotation, but unfortunately it works at compile time, not at runtime,
>>> that's why there is still the need for files like persistence.xml in JPA and
>>> web.xml in jars.
>>> To make a long story short, as Andy did in his code, somewhere you must
>>> still call "new ClassUnderObservation()" or at least
>>> Class.forName("com.foo.ClassUnderObservation") or access a static field or
>>> method of that class to get it loaded by the jvm, otherwise no static init,
>>> no registration in the aspect.
>>> Simone
>>>
>>> 2010/4/28 Andy Clement <andrew.clement@xxxxxxxxx>
>>>>
>>>> You didn't mention how it fails??  Here is Simones code in a real
>>>> program, appears to work.  What is different about your code or that
>>>> particular type?  Perhaps narrow your pointcut to a specific type to
>>>> test the registration logic is working before expanding it to cover
>>>> more types?
>>>>
>>>> === A.aj ===
>>>> package com.foo;
>>>>
>>>> import java.lang.annotation.Retention;
>>>> import java.lang.annotation.RetentionPolicy;
>>>> import java.util.*;
>>>>
>>>> import org.aspectj.lang.reflect.InitializerSignature;
>>>>
>>>> @Retention(RetentionPolicy.RUNTIME)
>>>> @interface Observer {}
>>>>
>>>> aspect A {
>>>>        public static void main(String[] args) {
>>>>                new C();new D(); new E();
>>>>        }
>>>>
>>>>   static List<Class> registry = new ArrayList<Class>();
>>>>
>>>>   pointcut observerKlasses(): staticinitialization(@Observer com..*);
>>>>
>>>>        after(): observerKlasses() {
>>>>            InitializerSignature initsig =
>>>> (InitializerSignature)thisJoinPointStaticPart.getSignature();
>>>>            Class klass = initsig.getDeclaringType();
>>>>            registry.add(klass);
>>>>            System.out.println("Registering "+klass);
>>>>        }
>>>>
>>>> }
>>>>
>>>> @Observer
>>>> class C {}
>>>>
>>>> class D{}
>>>>
>>>> @Observer
>>>> class E {}
>>>> ===
>>>> ajc A.aj
>>>> java A
>>>> Registering class com.foo.C
>>>> Registering class com.foo.E
>>>>
>>>> cheers,
>>>> Andy
>>>>
>>>> On 28 April 2010 00:30, Mohammad Norouzi <mnrz57@xxxxxxxxx> wrote:
>>>> > Hi Simone,
>>>> > Thanks... I did what you said but there is a problem. During the
>>>> > compile
>>>> > there is no error but it seems the static block doesn't work. I tried
>>>> > to
>>>> > decompile the target class to see what changes AspectJ has applied and
>>>> > I can
>>>> > see a static block has been created but it is commented as follow:
>>>> >
>>>> >
>>>> >   // ERROR //
>>>> >   static
>>>> >   {
>>>> >     // Byte code:
>>>> >     //   0: new 87    org/aspectj/runtime/reflect/Factory
>>>> >     //   3: dup
>>>> >     //   4: ldc 88
>>>> >     //   6: ldc 90
>>>> >     //   8: invokestatic 96    java/lang/Class:forName
>>>> > (Ljava/lang/String;)Ljava/lang/Class;
>>>> >     //   11: invokespecial 99
>>>> > org/aspectj/runtime/reflect/Factory:<init>
>>>> > (Ljava/lang/String;Ljava/lang/Class;)V
>>>> >     //   14: astore_0
>>>> >     //   15: aload_0
>>>> >     //   16: ldc 101
>>>> >     //   18: aload_0
>>>> >     //   19: ldc 103
>>>> >     //   21: ldc 90
>>>> >     //   23: invokevirtual 107
>>>> > org/aspectj/runtime/reflect/Factory:makeInitializerSig
>>>> >
>>>> > (Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/InitializerSignature;
>>>> >     //   26: iconst_0
>>>> >     //   27: invokevirtual 111
>>>> > org/aspectj/runtime/reflect/Factory:makeSJP
>>>> >
>>>> > (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart;
>>>> >     //   30: putstatic 79    com/foo/listener/MyListener1:ajc$tjp_0
>>>> > Lorg/aspectj/lang/JoinPoint$StaticPart;
>>>> >     //   33: goto +28 -> 61
>>>> >     //   36: astore_0
>>>> >     //   37: aload_0
>>>> >     //   38: instanceof 71
>>>> >     //   41: ifeq +8 -> 49
>>>> >     //   44: aload_0
>>>> >     //   45: checkcast 71    java/lang/ExceptionInInitializerError
>>>> >     //   48: athrow
>>>> >     //   49: nop
>>>> >     //   50: invokestatic 77
>>>> > com/foo/aspect/EventDispatcherAspect:aspectOf
>>>> > ()Lcom/foo/aspect/EventDispatcherAspect;
>>>> >     //   53: getstatic 79    com/foo/listener/MyListener1:ajc$tjp_0
>>>> > Lorg/aspectj/lang/JoinPoint$StaticPart;
>>>> >     //   56: invokevirtual 83
>>>> >
>>>> > com/foo/aspect/EventDispatcherAspect:ajc$after$com_foo_aspect_EventDispatcherAspect$1$5b3bc9fd
>>>> > (Lorg/aspectj/lang/JoinPoint$StaticPart;)V
>>>> >     //   59: aload_0
>>>> >     //   60: athrow
>>>> >     //   61: invokestatic 77
>>>> > com/foo/aspect/EventDispatcherAspect:aspectOf
>>>> > ()Lcom/foo/aspect/EventDispatcherAspect;
>>>> >     //   64: getstatic 79    com/foo/listener/MyListener1:ajc$tjp_0
>>>> > Lorg/aspectj/lang/JoinPoint$StaticPart;
>>>> >     //   67: invokevirtual 83
>>>> >
>>>> > com/foo/aspect/EventDispatcherAspect:ajc$after$com_foo_aspect_EventDispatcherAspect$1$5b3bc9fd
>>>> > (Lorg/aspectj/lang/JoinPoint$StaticPart;)V
>>>> >     //   70: return
>>>> >     //
>>>> >     // Exception table:
>>>> >     //   from    to    target    type
>>>> >     //   33    36    36    java/lang/Throwable
>>>> >   }
>>>> >
>>>> > Regards,
>>>> > Mohammad
>>>> > --------------------------
>>>> > Sun Certified Web Developer
>>>> > ExpertsExchange Certified, Master:
>>>> > http://www.experts-exchange.com/M_1938796.html
>>>> > Have a look at some pictures @ http://pixelshot.wordpress.com/
>>>> > Do you like to read, see http://brainable.blogspot.com/
>>>> > For the Persians see http://fekre-motefavet.blogspot.com/
>>>> > English
>>>> >
>>>> > Forum:http://n2.nabble.com/English-Phrase-Finder-For-Persians-f3274251.html
>>>> >
>>>> >
>>>> >
>>>> >
>>>> > On Tue, Apr 27, 2010 at 7:33 PM, Simone Gianni <simoneg@xxxxxxxxxx>
>>>> > wrote:
>>>> >>
>>>> >> Hi Mohammad,
>>>> >> staticinitialization has no target object because when a class is
>>>> >> initialized there is no instance yet. Probably you can obtain the
>>>> >> class and
>>>> >> other informations using ThisJoinPointStaticPart inside your advice.
>>>> >>
>>>> >>     pointcut observerMethods():
>>>> >>         staticinitialization(@Observer com..*);
>>>> >>
>>>> >>    after(): observerMethods() {
>>>> >>         InitializerSignature initsig =
>>>> >> (InitializerSignature)ThisJoinPointStaticPart.getSignature();
>>>> >>         Class klass = initsig.getDeclaringType();
>>>> >>         // adding 'klass' into Registry
>>>> >>    }
>>>> >>
>>>> >> See
>>>> >> http://www.eclipse.org/aspectj/doc/released/runtime-api/index.html for
>>>> >> more info.
>>>> >>
>>>> >> Simone
>>>> >>
>>>> >> 2010/4/27 Mohammad Norouzi <mnrz57@xxxxxxxxx>
>>>> >>>
>>>> >>> Hello
>>>> >>> I want to register those classes annotated with @Observer in a
>>>> >>> Registry
>>>> >>> class... I want this occurs in a static block of such classes:
>>>> >>>
>>>> >>>     pointcut observerMethods(Class klass):
>>>> >>>         staticinitialization(@Observer com..*)
>>>> >>>         && target(klass);
>>>> >>>
>>>> >>>    after(Class klass): observerMethods(klass) {
>>>> >>>         // adding 'klass' into Registry
>>>> >>>
>>>> >>>    }
>>>> >>>
>>>> >>> but as I read in manual it is said staticinitialization has no
>>>> >>> target
>>>> >>> object... is this right? if yes, how can I obtain the Class of those
>>>> >>> classes. Can I declare a static-block for matching classes?
>>>> >>>
>>>> >>> thanks
>>>> >>>
>>>> >>> Regards,
>>>> >>> Mohammad
>>>> >>> --------------------------
>>>> >>> Sun Certified Web Developer
>>>> >>> Have a look at some pictures @ http://pixelshot.wordpress.com/
>>>> >>>
>>>> >>>
>>>> >>>
>>>> >>> _______________________________________________
>>>> >>> aspectj-users mailing list
>>>> >>> aspectj-users@xxxxxxxxxxx
>>>> >>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>>> >>>
>>>> >>
>>>> >>
>>>> >> _______________________________________________
>>>> >> aspectj-users mailing list
>>>> >> aspectj-users@xxxxxxxxxxx
>>>> >> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>>> >>
>>>> >
>>>> >
>>>> > _______________________________________________
>>>> > aspectj-users mailing list
>>>> > aspectj-users@xxxxxxxxxxx
>>>> > https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>>> >
>>>> >
>>>> _______________________________________________
>>>> aspectj-users mailing list
>>>> aspectj-users@xxxxxxxxxxx
>>>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>>
>>
>>
>> _______________________________________________
>> aspectj-users mailing list
>> aspectj-users@xxxxxxxxxxx
>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>
>
>
>
> --
> Regards,
> Mohammad
> --------------------------
> Sun Certified Web Developer
> ExpertsExchange Certified, Master:
> http://www.experts-exchange.com/M_1938796.html
> Have a look at some pictures @ http://pixelshot.wordpress.com/
> Do you like to read, see http://brainable.blogspot.com/
> For the Persians see http://fekre-motefavet.blogspot.com/
> English
> Forum:http://n2.nabble.com/English-Phrase-Finder-For-Persians-f3274251.html
>
>
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>
>


Back to the top