[jboss-user] [JBoss AOP] - Re: Multiple ClassLoaders problem?

fr0w do-not-reply at jboss.com
Wed Jun 25 23:54:47 EDT 2008

Ok, Flavia, I tried what you suggested and it seemed to work, but turns out that developing with eclipse (and using it's compiler) together with AopC isn't a good idea, because everytime I change a single char using eclipse it recompiles the class so it will loose all code that was once inserted by AopC.  But that wasn't the only problem, I also had some other problems that I can't recall now. So I visited the official site and saw that there was an upgrade available (I was using CR8) so I grabbed it and replaced the JARs.

After upgrading I decided to give load-time weaving a second chance and it also worked! But in order to make it work I had to do some Thread.currentThread().setContextClassLoader() in some places... But that wasn't enough to make errors happen.

First of all, let me try to explain the "boot" procedure of a JPF application.
- The main class of the application is called org.java.plugin.boot.Boot
- This Boot class check the system properties looking for a property called 'org.java.plugin.boot.applicationPlugin'. This property has a classname which is later resolved to a Class and the have a method boot() called (so this boot() method works like our old main())

Introducing a Java Agent causes this process to get a little more complex.
- premain() -> Boot.main() -> MyClass.boot()

premain() and Boot.main() uses the default ClassLoader to load the necessary class in order to be able to call MyClass.boot() that includes JbossAOP libraries (since the AspectManager is loaded by in the premain() method).

After premain() and Boot.main(), JPF creates its own ClassLoading architecture based on some XML files and its configuration (plugin dependency, for example). A simple example of how the ClassLoading works in JPF can be the following:

- 'pluginB' depends on 'pluginA' so the ClassLoader used to load 'pluginB' classes' is also able to "see" 'pluginA' classes.

But now let's say I added a interceptor to a method in 'pluginB', but due to JPF way of handling things, the premain() / Boot.main() class loader is not able to "see" 'pluginB' classes', causing the exception bellow:

  | Exception generating org.drftpd.vfs.JoinPoint_toString6853976482757027775_8: org.drftpd.vfs.index.lucene.SimpleInterceptor
  | java.lang.ClassNotFoundException: org.drftpd.vfs.index.lucene.SimpleInterceptor
  | 	at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
  | 	at java.security.AccessController.doPrivileged(Native Method)
  | 	at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
  | 	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
  | 	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
  | 	at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
  | 	at org.jboss.aop.instrument.JoinPointGenerator$AdviceSetup.<init>(JoinPointGenerator.java:1405)
  | 	at org.jboss.aop.instrument.JoinPointGenerator.initialiseAdviceInfosAndAddFields(JoinPointGenerator.java:526)
  | 	at org.jboss.aop.instrument.JoinPointGenerator.generateJoinpointClass(JoinPointGenerator.java:367)
  | 	at org.jboss.aop.instrument.JoinPointGenerator.doGenerateJoinPointClass(JoinPointGenerator.java:285)
  | 	at org.jboss.aop.instrument.JoinPointGenerator.access$300(JoinPointGenerator.java:77)
  | 	at org.jboss.aop.instrument.JoinPointGenerator$GenerateJoinPointClassAction$2.generateJoinPointClass(JoinPointGenerator.java:1729)
  | 	at org.jboss.aop.instrument.JoinPointGenerator.generateJoinPointClass(JoinPointGenerator.java:250)
  | 	at org.jboss.aop.GeneratedClassAdvisor.generateJoinPointClass(GeneratedClassAdvisor.java:1042)
  | 	at org.drftpd.vfs.InodeHandle$InodeHandleAdvisor.toString6853976482757027775(InodeHandle$InodeHandleAdvisor.java)
  | 	at org.drftpd.vfs.InodeHandle.toString(InodeHandle.java)
  | 	at java.lang.String.valueOf(String.java:2827)
  | 	at java.lang.StringBuilder.append(StringBuilder.java:115)
  | 	at org.drftpd.commands.list.LIST.list(LIST.java:364)
  | 	at org.drftpd.commands.list.LIST.doLIST(LIST.java:406)
  | 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  | 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  | 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  | 	at java.lang.reflect.Method.invoke(Method.java:597)
  | 	at org.drftpd.commandmanager.StandardCommandManager.execute(StandardCommandManager.java:238)
  | 	at org.drftpd.master.BaseFtpConnection$CommandThread.run(BaseFtpConnection.java:634)
  | 	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
  | 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
  | 	at java.lang.Thread.run(Thread.java:619)
generator.generateJoinPointClass(this.getClass().getClassLoader(), info);
The above piece of code is, at least for me, the cause of my problems. since the ClassLoader that loaded JointPointGenerator cannot "see" JPF's ClassLoader.

Dunno if that's a limitation or a not handled case or a bug.

Thanks in advance for you help.

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4160721#4160721

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4160721

More information about the jboss-user mailing list