11 Replies Latest reply: Dec 27, 2004 10:54 AM by Tom Jensen RSS

jboss aop on websphere

Tom Jensen Newbie

Has anyone used jboss aop at loadtime in websphere? I've been trying to get it to work with no luck. I tried setting the classloader at startup with:

-Djava.system.class.loader=org.jboss.aop.standalone.SystemClassLoader


but WebSphere just bombs out and won't even start up. I also tried to switch the classloader just before the class is loaded that I want the aspect on with:

Thread.currentThread().setContextClassLoader(new SystemClassLoader(Thread.currentThread().getContextClassLoader()));
AspectManager.instance();


This seems to work, and when I put jboss.aop.verbose=true in the system properties it shows that it successfully loaded up the aspect. However, when it starts getting into determining whether to apply the aspect to particular classes something seems to go wrong and it bombs out, not on the JBoss AOP side, but on the IBM side. Seems like because of the classloader it is unable to load up some configuration stuff that it needs.

I'd be happy to post what was logged, but it is kind of verbose. I'm ultimately wanting to apply some aspects to IBM's code to gather some information (not in a production system but in development). Since I don't have access to the source of the classes I want to apply the aspects to I'm assuming I need to do this at loadtime.

Thanks,

Tom

  • 1. jboss aop on websphere
    Tom Jensen Newbie

    Has anyone used jboss aop at loadtime in websphere? I've been trying to get it to work with no luck. I tried setting the classloader at startup with:

    -Djava.system.class.loader=org.jboss.aop.standalone.SystemClassLoader


    but WebSphere just bombs out and won't even start up. I also tried to switch the classloader just before the class is loaded that I want the aspect on with:

    Thread.currentThread().setContextClassLoader(new SystemClassLoader(Thread.currentThread().getContextClassLoader()));
    AspectManager.instance();


    This seems to work, and when I put jboss.aop.verbose=true in the system properties it shows that it successfully loaded up the aspect. However, when it starts getting into determining whether to apply the aspect to particular classes something seems to go wrong and it bombs out, not on the JBoss AOP side, but on the IBM side. Seems like because of the classloader it is unable to load up some configuration stuff that it needs.

    I'd be happy to post what was logged, but it is kind of verbose. I'm ultimately wanting to apply some aspects to IBM's code to gather some information (not in a production system but in development). Since I don't have access to the source of the classes I want to apply the aspects to I'm assuming I need to do this at loadtime.

    Thanks,

    Tom

  • 2. Re: The Unified classloader a little too unified?
    Tom Jensen Newbie

     

    "erikreut" wrote:
    I thought you guys were trying to get close to the J2EE spec with JBoss...

    This way of dealing with classloaders will cause a slew of problems with enterprise-deployed servers, where applications (homegrown and 3rdparty) will have to play nicely together.

    The problems really arises when you have alot of applications sharing the same jars (e.g. JDOM, Struts, POI etc..) and you don't wanna continously upgrade each and everyone of these just because, say, I want to use a newer version of Struts in a new project.

    The default behaviour should be the J2EE classloading scheme, this will help ensure portability between the other vendor's appserver's and give developers (like myself) a uniform way of developing J2EE apps.

    I read:

    http://members.capmac.org/~orb/blog.cgi/tech/java/jboss_ucl.html

    and couldn't agree more on the points made.



  • 3. Re: jboss aop on websphere
    Bill Burke Master

    Did you try this?

    http://docs.jboss.org/aop/aspect-framework/reference/en/html/running.html#d0e2599

    You may be forced to use the precompiler as I've only tested JBoss AOP on JBoss application server and in standalone plain java programs.

    Also,

    If you get this to work, can you create a WIKI page on this here? I'd still be happy to help.

    http://www.jboss.org/wiki/Wiki.jsp?page=JBossAOP

    THanks,

    Bill

  • 4. Re: jboss aop on websphere
    Tom Jensen Newbie

    I hadn't tried the alternate way of using loadtime, thanks for pointing that out. I think that might be at least part of the solution, but now I'm running into visibility issues with different classes.

    I was looking over the code that creates the new java.lang.ClassLoader (AspectManager.getInstrumentedClassLoader()), and I'm having trouble understanding what it is doing. It looks like it is completely replacing the private native defineClass0 method on the classloader with its own. It looks like it is for doing bytecode manipulation to instrument newly defined classes as the classloader pulls them up. Is that correct? The thing I guess I'm wondering is if it is replacing that native (JNI) method, how does that probably necessary native call occur?

    IBM's JVM has a similar defineClass0 method that also makes a native call, but I'm wondering if there is a difference between the two.

    It seems like since I'm running in WebSphere this is a classloader issue. I'm wondering if I shouldn't be focusing on trying to get the app level classloader instrumented correctly instead of the system level classloader. Any thoughts on that? Were there similar issues integrating JBoss-AOP into JBoss-AS, since it probably is working with multiple classloaders and scopes?

    If I'm able to get this running, I'm definitely more than happy to post whatever I find on the wiki... I just need to figure out how to get it to work first.

    Thanks,

    Tom

  • 5. Re: jboss aop on websphere
    KevinConner Newbie

     

    It looks like it is completely replacing the private native defineClass0 method on the classloader

    It's not replacing the call, just allowing the AspectManager to transform the loaded bytes before calling defineClass0.

    IBM's JVM has a similar defineClass0 method that also makes a native call

    I don't have a version of WebSphere to hand but, if I remember correctly, the arguments are different from the Sun ClassLoader. It should be a simple change to the code to make it work with their VM.

    Getting loadtime transformations to work in WebSphere is a different matter.

    I haven't looked at the code lately but it used to rely on the javassist classloading to mirror the classloading policy within the VM. I wasn't convinced that this worked properly in JBoss AS and, as my idea would break the 1.5 support I haven't yet gone ahead with it. That and time constraints from work ;-)

    It is now looking unlikely that I will have the time to revisit this until the middle of January but it may already be in hand, have been done, or be totally unnecessary :-).

    If you want to get the classloader modifications working for the IBM VM then give me a shout.

    Kev


  • 6. Re: jboss aop on websphere
    Tom Jensen Newbie

    Yeah you're right about the IBM VM, there are two extra args on their version of the method (a java.security.cert.Certificate and byte[]). It looks like those are related to extra security things that IBM is doing.

    Kevin, from your comments and looking into it more seems like the issue I'm having is in working with WebShpere and the multiple classloaders. I think the java.lang.ClassLoader that is created from the GenerateInstrumentedClassLoader works fine for a simple app. If you think otherwise I'd be interested in what I could do to fix it at that level before trying to get into a WebSphere fix.

    I haven't looked at the code lately but it used to rely on the javassist classloading to mirror the classloading policy within the VM.


    Generating the java.lang.ClassLoader from the GenerateInstrumentedClassLoader I don't think does this. Where would I find the code that would do something like this? Also, I'd be happy to do what I could to get something like this working in WebSphere (assuming that the same implementation may not work in both JBoss AS and WebSphere).

    Thanks,

    Tom

  • 7. Re: jboss aop on websphere
    KevinConner Newbie

    There are two parts to this, getting the classloader to intercept the calls to defineClass0 and getting AOP to work with any classloader setup.

    The first one is easy, just a simple modification to the code that instruments the classloader should do it.

    The second one involves a change to the way that the AOP code uses javassist, requiring recursive calls to the classloader (and therefore instrumentation). This will not work with the 1.5 instrumentation as it filters out recursive calls, a very restrictive decision on Sun's part (IMHO). The AOP code actually has a thread local flag added so that the instrumented classloader works the same way as the 1.5 instrumentation, preventing recursive calls.

    The following is based on my current understanding and could be wrong!

    The code currently works by intercepting a classloader call to instrument a class and, from that point on, the instrumentation classloading hierarchy is driven by javassist. The AOP code uses javassist to load the class information for superclasses, interfaces etc. based on what javassist believes the hierarchy to be. A mismatch in this and things could possibly go wrong. What I would like to do is throw this back to the calling classloader and allow it to dictate the hierarchy, obviously involving a recursive call to the classloader :-(.

    I will make the classloader instrumentation change to allow you to use it with the IBM VM, you could try and see if it is sufficient to let you get something working. Which java version are you using?

    Kev

  • 8. Re: jboss aop on websphere
    Tom Jensen Newbie

    I'm using 1.4.1 of the IBM VM. We're pretty much tied to WebSphere on this project, so even if we did upgrade to 6.0 in the near term (which we won't) we'd still only be on 1.4.2.

    I tried altering the following part of the replace call in AspectManager.getInstrumentedClassLoader():

    + " $_ = $proceed($1, newBytes, 0, newBytes.length, $5) ;"


    with

    + " $_ = $proceed($1, newBytes, 0, newBytes.length, $5, $6, $7) ;"


    Just like before when I set jboss.aop.verbose to true it chatters on about trying to transform certain objects and determining what methods should be aspectized. That seems to indicate that the AspectManager is being called at the correct time before the defineClass0 method is called, and that classes are successfully being loaded to some degree.

    Ultimately it dies at the same place as before. It still throws the same exception, stating that it is unable to aspectize a class because it is unable to find another class that it references.

    Not sure if the above fix is the fix you were envisioning or not, but I thought I'd give it a try from what I understand about the code.

    As far as the recursive classloading techniques, I'd be interested in trying that out, would I need to dig into javassist? I'll start there and see what I can find, but please feel free to give any directions you might find helpful (I understand that you're pretty strapped for time).

    Thanks for the help,

    Tom

  • 9. Re: jboss aop on websphere
    Bill Burke Master

    Tom, thanks for all your patience here...

    Did you ever try just using the precompiler? (AOPC)

  • 10. Re: jboss aop on websphere
    KevinConner Newbie

     

    I tried altering the following part of the replace call in AspectManager.getInstrumentedClassLoader():


    Yes, I would have added another test based on the number of parameters but it would have resulted in the same. I downloaded the 1.4.2 JDK over the weekend and that appears to have a different method name and signature (from cursory inspection).

    Ultimately it dies at the same place as before. It still throws the same exception, stating that it is unable to aspectize a class because it is unable to find another class that it references.


    I have seen this happen when a class contains references to other classes that do not exist on the classpath (or at least not that javassist can find). Javassist seems to be very strict in this requirement.

    As far as the recursive classloading techniques, I'd be interested in trying that out, would I need to dig into javassist? I'll start there and see what I can find, but please feel free to give any directions you might find helpful (I understand that you're pretty strapped for time).


    The change to the classloading will probably not help with the previous problem unless webSphere has the classes somewhere that cannot be resolved by Javassist. I'll dig through javassist later this evening and see if I can find a fix for the problem, it has been an issue that I have been ignoring until now :-).

    I have a hard deadline of 18th January and should be able to look at the classloading shortly afterwards. The changes will have to go via Bill and Kabir though as they will break the 1.5 mechanism.

    Kev


  • 11. Re: jboss aop on websphere
    Tom Jensen Newbie

    Thanks Kevin for your assistance, I appreciate it. Please keep me posted.