13 Replies Latest reply on Nov 20, 2012 12:43 PM by kabirkhan

    Compile Time AOP in JBOSS

      Hi All,
      I am trying to use compile time AOP with JBOSS AS 5.1.


      However it seems to work only when I set enableLoadtimeWeaving to be true in conf/aop.xml and the related javaagent options in run.sh.

      I was under the impression that these are required only for loadtime weaving.

      Currently I am deploying the one EAR that contains

      ----------------------

      - A lib.aop that contains the aspect classes along with a jboss-aop.xml inside it (META-INF dir). Pre-compiled with AOPC

      - A mylib.jar with all my EJB classes and related POJOs in it. Pre-compiled with AOPC

      The EAR has a META-INF/application.xml that declares the .aop lib as a java lib and the EJB jar as an ejb module.

      ----------------------

      When I call the EJB via an external client - nothing happens (nothing is logged via my aop aspects - simple method invocation interceptors).

      However when I restart with the load time weaving and javaagent option it works ( I see all SOPs).

      Lastly I was under the impression that when the classes are pre-compiled then the load time would be less. Is this right. I don't see a difference today.


      Much appreciate any advise.

      Thanks
      Guna


        • 1. Re: Compile Time AOP in JBOSS
          kabirkhan

          Compile-time should work, but you still need to deploy your jboss-aop.xml file to populate the bindings at runtime

          • 2. Re: Compile Time AOP in JBOSS

            Hi Kabir,
            Thanks for the quick reply. I have a jboss-aop.xml inside the lib.aop (which itself is inside my ear). The lib.aop only contains the aspects. There is another jar with the EJBs and POJOs inside the same EAR.

            Now this jboss-aop.xml contains definitions for the interceptor class (present inside the lib.aop) and the bindings which target classes/packages/methods present in the JAR.

            My jboss-aop.xml looks like this

            <?xml version="1.0" encoding="UTF-8"?>










            <interceptor-ref name="com.XYZ.aop.AopLogger"/>




            <interceptor-ref name="com. XYZ.aop.ConstructorInterceptor"/>




            The AOP Logger, Constructor Interceptor and jboss-aop.xml are present in the lib.aop. The com.* target classes are all present in the mylb.jar. Both of these are in the ear. The application.xml in the EAR references the EJB jar as an ejb module and the AOP as a java module.

            Both the aspect classes and the target classes have been pre-compiled using the AOPC (referencing the same jboss-aop.xml - now packaged inside the lib.aop).

            Then I stick the EAR into the server/default/deploy dir.

            I have not done anything else. Am I missing a step.

            In addition do I need to have the jboss-aop.xml directly in the default/deploy directory?

            Do I need to do have the loadtimeweaving enabled even after the pre-compile? The only time I see the AOP kicking-in is when I have the above flag set and the javaagent part set in run.sh.

            When I remove those options the AOP interception is not happening. I even tried the EXAMPLES provided and I get the same result.

            So I feel I am missing a very simple (duh!) step :)

            Appreciate any help/advise on investigation direction since I am stumped at this point?


            Thanks a lot
            Guna

            • 3. Re: Compile Time AOP in JBOSS

              Sorry the XML did not seem to load properly. Trying again!

              <?xml version="1.0" encoding="UTF-8"?>










              <interceptor-ref name="com.XYZ.aop.AopLogger"/>




              <interceptor-ref name="com. XYZ.aop.ConstructorInterceptor"/>



              • 4. Re: Compile Time AOP in JBOSS

                Trying again (Sorry - should have tried preview!!) - I knocked off the XML tags this time.

                xml version="1.0" encoding="UTF-8"?

                aop xmlns="urn:jboss:aop-beans:1.0"

                interceptor class="com.XYZ.aop.AopLogger" scope="PER_VM"/>

                interceptor class="com.XYZ.aop.ConstructorInterceptor" scope="PER_VM"/>



                bind pointcut="execution(* com. XYZ.ejb.*->*(..)) "
                interceptor-ref name="com.XYZ.aop.AopLogger"
                /bind


                bind pointcut="execution(com. XYZ.ejb.*->new(..))"
                interceptor-ref name="com. XYZ.aop.ConstructorInterceptor"
                /bind

                /aop

                • 5. Re: Compile Time AOP in JBOSS
                  gebhardtj

                  Hi Guna,

                   

                  have you solved this problem? I'm experiencing exactly the same issue. If I place the *.aop file inside an EAR with the precompiled classes the aspects do not get called. However, if I take the same AOP File and place it side-by-side with the EAR  (and remove the AOP from the application.xml file) the aspects get called.

                   

                  Any hint is very much appeciated

                  Joern

                  • 6. Re: Compile Time AOP in JBOSS
                    kabirkhan

                    You used to need to list your .aop in application.xml http://docs.jboss.org/jbossaop/docs/2.0.0.GA/docs/aspect-framework/examples/injboss/aopInJbossPackaging.html (substitute @lib@ with xxx.aop) although that tutorial is from the old J2EE 1.4 days so your milage may vary. Also, note that JBoss AOP only works with JBoss AS 4.x-6.x, i.e. it will not work in AS 7.

                    • 7. Re: Compile Time AOP in JBOSS
                      gebhardtj

                      Hi Kabir,

                       

                      I have listed the .aop file in my application.xml file as java module. However, it seems that I have some classloader issues. My EAR has its own classloader (loader-repository in jboss-app.xml) defined. When deploying the EAR (that already contains the precompiled classes) I can see the following log message " [org.jboss.aop.deployment.AspectDeployer] AOP deployment is scoped using classloader". I also throw an exception in the method that should be surrounded by an aspect and the stacktrace shows that the instrumented "...$aop" method has been called, however not the aspect.

                       

                      Next I removed the EAR specific classloader in the jboss-app.xml and the aspect was perfectly executed.

                       

                      Is it possible that there is a classloader bug in version 1.5.6.GA of jboss-aop? My guess is that the byte code manipulated class does not look for the scoped classloader to find the matching aspects.

                       

                      Kind regards

                      Joern

                       

                      P.S.

                      I just looked a the decomplied code of my intrumented class and found the following line:

                      static { jdField_aop$classAdvisor$aop_of_type_OrgJbossAopClassAdvisor = AspectManager.instance().getAdvisor(Class.forName("com.oneandone.access.home.provisioning.termination.silent.jar.actions.ejb.tal.TerminateTalLineSilently")); }

                      I guess the AspectManager.instance() causes the problem as it does not provide the classloader of the actual class.

                      • 8. Re: Compile Time AOP in JBOSS
                        kabirkhan

                        It has been years since I or anybody last touched this, so apologies if what I say is a bit vague. As you mention, there are two steps involved in this:

                         

                        1) When deploying the .aop file as part of a classloader scoped ear that information should get added to a scoped AspectManager handling aspects for that classloader domain.

                        2) When populating the Advisor use the scoped classloader to find the scoped AspectManager.

                         

                        There were some slight changes in determining 1 in various app server versions but I don't think that is the problem here, rather as you say it is probably using the wrong classloader in 2). Originally we had this use the thread context classloader but later replaced it with an explicit AspectManager.instance(ClassLoader) method since TCL is not always deterministic.

                         

                        If you have support use the customer support portal for more help. If not, which version of JBoss AS are you using? You might be able to get around this problem by either trying to force the thread context classloader when your AspectManager.instance() method is called, or by building one of the versions at http://anonsvn.jboss.org/repos/jbossas/projects/aop/tags/ and upgrading your AS instance.

                        • 9. Re: Compile Time AOP in JBOSS
                          gebhardtj

                          Thanks for your quick responses.

                           

                          I'm using JBoss 4.2.3 and jboss-aop 1.5.6. Unfortunately I cannot upgrade the AOP version to >= 2.0.0

                           

                          I decompiled the AspectManager and the instance() method looks like this:

                           

                          public static synchronized AspectManager instance()

                          {

                            return instance(Thread.currentThread().getContextClassLoader());

                          }

                           

                          As I do not have any influence on my runtime environment I can only patch the ClassicInstrumentor at compile time and replace the following line

                          addStaticField(clazz, "aop$classAdvisor$aop", HELPER_CLASS_NAME, CtField.Initializer.byExpr(ASPECT_MANAGER_CLASS_NAME + ".instance().getAdvisor(java.lang.Class#forName(\"" + clazz.getName() + "\"))"));

                          by something else e.g.

                          addStaticField(clazz, "aop$classAdvisor$aop", HELPER_CLASS_NAME, CtField.Initializer.byExpr(ASPECT_MANAGER_CLASS_NAME + ".instance(java.lang.Class#forName(\"" + clazz.getName() + "\"))".getClassLoader()).getAdvisor(java.lang.Class#forName(\"" + clazz.getName() + "\"))"));

                           

                          Maybe the classloader of the advised class is the correct one.

                          • 10. Re: Compile Time AOP in JBOSS
                            kabirkhan

                            This actually seems to have been fixed in the 1.5 branch: http://anonsvn.jboss.org/repos/jbossas/branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/instrument/ClassicInstrumentor.java See addHelperField()

                             

                            [~]

                            $svn log --limit=3 http://anonsvn.jboss.org/repos/jbossas/branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/instrument/ClassicInstrumentor.java

                            ------------------------------------------------------------------------

                            r106068 | flavia.rainone@jboss.com | 2010-06-15 19:33:03 +0100 (Tue, 15 Jun 2010) | 1 line

                             

                             

                            [JBAOP-796] Add an instance(Class<?>) to AspectManager and make woven code use that method instead of instance()

                            ------------------------------------------------------------------------

                            r59554 | flavia.rainone | 2007-01-11 21:38:09 +0000 (Thu, 11 Jan 2007) | 1 line

                             

                             

                            Fixing Kabir's mistake

                            ------------------------------------------------------------------------

                            r59532 | flavia.rainone@jboss.com | 2007-01-11 16:29:27 +0000 (Thu, 11 Jan 2007) | 1 line

                             

                             

                            [JBAOP-317] Task done

                            ------------------------------------------------------------------------

                             

                            https://issues.jboss.org/browse/JBAOP-796

                             

                            Unfortunately there is no 1.5.7.GA release so you would need to build the branch yourself

                            • 11. Re: Compile Time AOP in JBOSS
                              kabirkhan

                              i.e. the fix is identical to what you suggest

                              • 12. Re: Compile Time AOP in JBOSS
                                gebhardtj

                                Thanks Kabir for your support. Its working now!

                                Jörn

                                • 13. Re: Compile Time AOP in JBOSS
                                  kabirkhan

                                  Great :-) If you had to do anything special to compile it, please post here