9 Replies Latest reply on Nov 8, 2004 10:56 AM by squeak

    NPE on redeploy (inside aspect library code)

    squeak Newbie

      I have a simple webapp that makes use of only the TX Apsect libraries for demarcation.

      I am using both the Annotation compiler and the AOPC compilier, packaging up the results in a WAR, and deploying to a JBoss 4.0 server. I have upgraded to FINAL code.

      My issues is that on startup, or first deployment of my WAR file, my code, and the TX interceptors work great. However, once I redploy my WAR file, I get a NullPointerException in my original method signature (which is now the new interceptor method).

      So, if I have a method called saveOrganization() that has been intercepted, after a redployment, I will get the following stacktrace:

      2:34:39,168 ERROR [org.osn.jext.framework.util.RequestInterceptor:124] java.lang.NullPointerException
       at org.osn.homefront.app.service.HomefrontService.saveOrganization(HomefrontService.java)
       at org.osn.homefront.app.OrgSignUp2.submit(OrgSignUp2.java:559)
       at org.osn.homefront.app.OrgSignUp2.pageMain(OrgSignUp2.java:63)
       at org.osn.jext.framework.JSPPageContent.runPageMain(JSPPageContent.java:45)
      


      As you can see, the line number is missing for where the NPE happens at, since it is the new instumented code.

      For shits & giggles, I decompiled that method and here is the code:

       public void saveOrganization(Organization organization)
       throws PersistenceException, BusinessValidationException
       {
       if(((Advisor) (aop$classAdvisor$aop)).doesHaveAspects || _instanceAdvisor != null && _instanceAdvisor.hasInstanceAspects)
       {
       org.jboss.aop.advice.Interceptor ainterceptor[] = aop$MethodInfo_saveOrganization5875559486684723374.interceptors;
       if(_instanceAdvisor != null)
       ainterceptor = _instanceAdvisor.getInterceptors(aop$MethodInfo_saveOrganization5875559486684723374.interceptors);
       HomefrontService_saveOrganization_5875559486684723374_OptimizedMethodInvocation homefrontservice_saveorganization_5875559486684723374_optimizedmethodinvocation =
      new HomefrontService_saveOrganization_5875559486684723374_OptimizedMethodInvocation(aop$MethodInfo_saveOrganization5875559486684723374, ainterceptor);
       homefrontservice_saveorganization_5875559486684723374_optimizedmethodinvocation.arg0 = organization;
       homefrontservice_saveorganization_5875559486684723374_optimizedmethodinvocation.setTargetObject(this);
       homefrontservice_saveorganization_5875559486684723374_optimizedmethodinvocation.typedTargetObject = this;
       homefrontservice_saveorganization_5875559486684723374_optimizedmethodinvocation.setAdvisor(aop$classAdvisor$aop);
       homefrontservice_saveorganization_5875559486684723374_optimizedmethodinvocation.invokeNext();
       } else
       {
       org$osn$homefront$app$service$HomefrontService$saveOrganization$aop(organization);
       }
       }
      


      Now, looking at that, I am not sure exactly where the NPE would be happening at, but the first suspect to me is the aop$classAdvisor$aop variable, since it is static. I wonder if it is getting blown away on the redploy and not set back up properly, since the static constructor might not get ran again?

      Thoughts?



        • 1. Re: NPE on redeploy (inside aspect library code)
          Bill Burke Master

          It does look like it is aop$classAdvisor$aop. Static initialization should always happen, not sure why it isn't in this case.

          would it be possible to put together a small test case we can reproduce the problem with?

          Apologies,

          Bill

          • 2. Re: NPE on redeploy (inside aspect library code)
            Bill Burke Master

            Another question:

            Are you using the precompiler? Or load time? or both?

            Bill

            • 3. Re: NPE on redeploy (inside aspect library code)
              squeak Newbie

              Bill,

              As I mentioned above, I am using the precompiler.

              Let me see what I can do about stripping out a significant amount of code and come up with a reproducable test case.

              Want me to send it via email?

              • 4. Re: NPE on redeploy (inside aspect library code)
                Bill Burke Master

                Yes, send it via email: bill@jboss.org

                FYI: hot deployment is a bitch.

                • 5. Re: NPE on redeploy (inside aspect library code)
                  squeak Newbie

                  I am working on it now...just as an FYI that might be the cause...I am doing scooped classloading inside the 'standard' config of JBoss 4.0.

                  Here is the contents of jboss-web.xml from the war:

                  <jboss-web>
                  <class-loading java2ClassLoadingCompliance="false">
                   <loader-repository>
                   My.war:loader= My.war
                   <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
                   </loader-repository>
                  </class-loading>
                  
                  </jboss-web>
                  


                  Not sure if that would ring any immediate bells

                  • 6. Re: NPE on redeploy (inside aspect library code)
                    Bill Burke Master

                    FYI, I have done ZERO testing with scoped classloading and JBoss AOP.

                    FYI2:

                    If you figure out this bug, and you want CVS access, you got it! I STILL have a hard time debugging hot deployment bugs whenever they come up.

                    Bill

                    • 7. Re: NPE on redeploy (inside aspect library code)
                      squeak Newbie

                      I will take a look at today.

                      I do want to give you an update on what I have found. It is definetly a classloading issue.

                      If in my scoped WAR File, I incldue the jboss-aop*.jar's, the issue does not happen. I can redeploy all day long. THat makes sense, because at that point I am using my scoped versions of the jar files, and a redeploy clears that out.

                      Doing a non-scoped WAR, regardless of including the jars or not, fails, since it is using the classloader for the aop jar files that have been deployed with the jboss-aop.deployer.

                      So, at this point, I am not sure if this is a real bug, or a configuration issue. Regadless, I would like to know why the NPE happens.

                      • 8. Re: NPE on redeploy (inside aspect library code)
                        squeak Newbie

                        I take that back....including the aop jar files does not solve the problem.

                        When incuding the jar files, the intercepted code is, for all purposes ignored.

                        It looks like when using your own scoped version of those jar files, either the aop$classAdvisor$aop or the _instanceAdvisor returns that there are no aspects to be run, and so it does not do the method invocation for the TX demarcation.

                        I am still playing with it, but it looks like you have to use the server's version of the classAdvisors, but a redeploy disconnects it.

                        I am also going to try to see what happens when I don't precompile it, but instead use the load time transformation.

                        • 9. Re: NPE on redeploy (inside aspect library code)
                          squeak Newbie

                          Just wanted to respond back to this thread what the problem is and potential resolutions, so it is useful to other people.

                          This problem with redeployment stems from the fact the the AspectManger inside of the AOP framework in certain cases can be loaded inside a different ClassLoader than the aspected classes it is servicing.

                          So, in my particular case, my deployment being scoped, causes my classes to be loaded, and unloaded on redeployment inside a different classloader than the AspectManager.

                          Now, why is that a problem? The AspectMangager keeps a cache of ClassAdvisors that have been inited (sets up invocations chains, interceptors, etc), that is keyed off the class name only. So, when the same class from a different ClassLoader is presented, the cached version of the ClassAdvisor is returned, and none of the initilization code is ran -- hence the NPE if the previous version of the class has been unloaded.

                          It is now a known issue, and hopfully will be fixed soon. As a workaround, if you scope the classloading of your deployment, and include the JBoss AOP jar files inside your deployment, this will cause the AspectManager to be scoped to your deployment, and hence will hand out accurate ClassAdvisors on redeployment.