Community
Participate
Working Groups
Here is the code for a load-time weaving agent for WebSphere using its built in ClassLoader API, and that works on the included Java VM's. I wrote this and have used it successfully to weave with AspectJ 5 built from 9/23/05 sources with a 1.4 javac compiler. I have tested it in WebSphere 6.0 but I believe this API has been around since at least WebSphere 4.x. To use it: Change your server startup config (either server.xml or use the admin console): 1) Add a Java VM environment variable <systemProperties xmi:id="Property_1127324365995" name="com.ibm.websphere.classloader.plugin" value="aj.weaver.WasWeavingPlugin" required="true"/> 2) Add the aspectjweaver and a jar with this plugin to your classpath, e.g., <classpath>path/WasWeavingPlugin.jar;path/aspectjweaver.jar</classpath> 3) Optionally add the jars to your server's RMI codebase with another environment variable (I did this based on public documentation for other API's and believe it is needed for distributed calls, but haven't tested without having it in there): <systemProperties xmi:id="Property_9927324365996" name="java.rmi.server.codebase" value="file://C:/devel/.../path/WasWeavingPlugin.jar file://C:/devel/projects/bunge/WAS6POC1/SimplePlugin/aspectjweaver.jar" required="true"/> 4) With WebSphere 6.0, make sure you rename the aspectjrt.jar in $WAS_HOME/lib to aspectjrt.bak and install the aspectjrt.jar from the same version as your aspectjweaver.jar came from. Now here's the actual load-time weaving agent's source code and have attached a built jar (building or running requires the WAS libraries, of course): package aj.weaver; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import org.aspectj.weaver.loadtime.Aj; import com.ibm.websphere.classloader.ClassLoaderPlugin; /** * @author Ron Bodkin * */ public class WasWeavingPlugin implements ClassLoaderPlugin { private Aj aj = new Aj(); /* (non-Javadoc) * @see com.ibm.websphere.classloader.ClassLoaderPlugin#preDefineApplicationClass (java.lang.String, byte[]) */ public byte[] preDefineApplicationClass(String className, byte[] bytes) { ClassLoader loader = Thread.currentThread ().getContextClassLoader(); return aj.preProcess(className, bytes, loader); } /* (non-Javadoc) * @see com.ibm.websphere.classloader.ClassLoaderPlugin#preDefineRuntimeClass (java.lang.String, byte[]) */ public byte[] preDefineRuntimeClass(String className, byte[] bytes) { return bytes; } } That's it? That's it!
Created attachment 27659 [details] prebuilt plugin jar
Created attachment 45610 [details] Updated source code with recursion protection The previous version of the plugin could fail on startup because it would try to weave classes that were loaded while initializing the weaver. This is updated source code that adds recursion protection (similar to how Matthew Webster did it for JRockIt but just using an int[] instead of keeping a stack).
Created attachment 45611 [details] Updated prebuilt jar with recursion protection
Note that there is a bug in at least some versions of WebSphere 6.0.x whereby the context ClassLoader is mis-set to the bootstrap loader instead of the application's loader. This can cause problems when using the plugin to 1) define application-specific aspects because the bootstrap loader won't see the aspect types nor application-specific types used by it. 2) I am attempting to investigate and resolve this WebSphere issue. See also bug #148880 for more information about this.
Note that there is a bug in at least some versions of WebSphere 6.0.x whereby the context ClassLoader is mis-set to the bootstrap loader instead of the application's loader. This can cause problems when using the plugin to 1) define application-specific aspects because the bootstrap loader won't see the aspect types nor application-specific types used by it. 2) use around advice (because the generated closure gets defined in the wrong loader and currently AspectJ LTW won't inline around advice until the defining aspect is woven - see bug #148880). I am attempting to investigate and resolve this WebSphere issue. See also bug #148880 for more information about this.
Created attachment 61647 [details] Updated pre-built jar. This jar uses the new tracing facility (with a tracing aspect) and is intended to work with AspectJ 1.5.3 or later.
Created attachment 61648 [details] Source code with tests for the plugin. This zip includes the source and Eclipse setup for two standalone modules used to build and test the plugin within an AspectJ workspace.
I am having trouble getting it to work with the WAS AdminApplication installed on the server. If I take out the aAdminApplication it starts ok. If I leave in the AdminApplication it hangs with the following last entry in the logs (I have added output to the event method in WasWeavingPlugin.aj): System.err : new defining class: com.ibm.ws.console.core.event.impl.WSAdminNotificationImpl System.out : [adminconsole] [/admin] [Servlet.LOG]: action: init A stackdump shows the following: 3XMTHREADINFO "Thread-0" (TID:0x100A3FE8, sys_thread_t:0x1DFFCA0, state:CW, native ID:0x93C) prio=5 4XESTACKTRACE at org.aspectj.weaver.loadtime.Aj.preProcess(Aj.java:69) 4XESTACKTRACE at aj.weaver.WasWeavingPlugin.preDefineApplicationClass(WasWeavingPlugin.aj:50) 4XESTACKTRACE at com.ibm.ws.classloader.CompoundClassLoader.findClass(CompoundClassLoader.java:404) 4XESTACKTRACE at com.ibm.ws.classloader.CompoundClassLoader.loadClass(CompoundClassLoader.java:314) 4XESTACKTRACE at java.lang.ClassLoader.loadClass(ClassLoader.java(Compiled Code)) ....
We have a similar problem. Using Launch StackTrace from: http://www.adaptj.com/main/tracehowtos 1LKDEADLOCK Deadlock detected !!! NULL --------------------- NULL 2LKDEADLOCKTHR Thread "server.startup : 0" (0x25CFA500) 3LKDEADLOCKWTR is waiting for: 4LKDEADLOCKMON sys_mon_t:0x00508508 infl_mon_t: 0x00508548: 4LKDEADLOCKOBJ com/ibm/ws/classloader/CompoundClassLoader@029AE4E0/029AE4EC: 3LKDEADLOCKOWN which is owned by: 2LKDEADLOCKTHR Thread "com.saic.ct.sys.framework.audit.AuditRecordThread" (0x2900C200) 3LKDEADLOCKWTR which is waiting for: 4LKDEADLOCKMON sys_mon_t:0x00507380 infl_mon_t: 0x005073C0: 4LKDEADLOCKOBJ com/ibm/ws/classloader/CompoundClassLoader@029A63F8/029A6404: 3LKDEADLOCKOWN which is owned by: 2LKDEADLOCKTHR Thread "server.startup : 0" (0x25CFA500) 3XMTHREADINFO "com.saic.ct.sys.framework.audit.AuditRecordThread" (TID:0x2900C200, sys_thread_t:0x250B4238, state:B, native ID:0x0000077C) prio=5 4XESTACKTRACE at java/lang/ClassLoader.loadClass(ClassLoader.java:595(Compiled Code)) 4XESTACKTRACE at com/ibm/ws/classloader/CompoundClassLoader.loadClass(CompoundClassLoader.java:394(Compiled Code)) 4XESTACKTRACE at java/lang/ClassLoader.loadClass(ClassLoader.java:595(Compiled Code)) 4XESTACKTRACE at com/ibm/ws/rsadapter/DSConfigurationHelper$3.run(DSConfigurationHelper.java:1474) 4XESTACKTRACE at com/ibm/ws/security/util/AccessController.doPrivileged(AccessController.java:118(Compiled Code)) 3XMTHREADINFO "server.startup : 0" (TID:0x25CFA500, sys_thread_t:0x250DD104, state:B, native ID:0x00000CBC) prio=5 4XESTACKTRACE at org/aspectj/weaver/loadtime/Aj.preProcess(Aj.java:72) 4XESTACKTRACE at aj/weaver/WasWeavingPlugin.preDefineApplicationClass(WasWeavingPlugin.aj:44) 4XESTACKTRACE at com/ibm/ws/classloader/CompoundClassLoader.findClass(CompoundClassLoader.java:488(Compiled Code)) 4XESTACKTRACE at com/ibm/ws/classloader/CompoundClassLoader.loadClass(CompoundClassLoader.java:389(Compiled Code)) 4XESTACKTRACE at java/lang/ClassLoader.loadClass(ClassLoader.java:595(Compiled Code)) 4XESTACKTRACE at org/apache/commons/logging/LogFactory.getFactory(LogFactory.java:218) 4XESTACKTRACE at org/apache/commons/logging/LogFactory.getLog(LogFactory.java:351) 4XESTACKTRACE at org/apache/struts/action/ActionServlet.<clinit>(ActionServlet.java:226) 4XESTACKTRACE at java/lang/J9VMInternals.initializeImpl(Native Method) 4XESTACKTRACE at java/lang/J9VMInternals.initialize(J9VMInternals.java:194(Compiled Code)) 4XESTACKTRACE at java/lang/Class.newInstanceImpl(Native Method) 4XESTACKTRACE at java/lang/Class.newInstance(Class.java:1300(Compiled Code)) 4XESTACKTRACE at java/beans/Beans.instantiate(Beans.java:219) 4XESTACKTRACE at java/beans/Beans.instantiate(Beans.java:63) 4XESTACKTRACE at com/ibm/ws/webcontainer/servlet/ServletWrapper$1.run(ServletWrapper.java:1226)
hey Sebastien Tardif , Have you figured a way around this problem you had. I have a similar problem where the WAS 6 Server stops loading right after this [3/13/09 10:21:45:697 PDT] 0000000a ServletWrappe A SRVE0242I: [adminconsole] [/ibm/console] [action]: Initialization successful. I believe something about "SecureCleanup" [3/13/09 10:21:45:744 PDT] 0000000a ServletWrappe A SRVE0242I: [adminconsole] [/ibm/console] [SecureCleanup]: Initialization successful. is throwing it off. Please advise thanks
I have give-up trying this. We prefer Eclipse plug-ins in dev, and ant integration for build. I just see this to be useful if dev environment cannot handle weaving integration directly.
I think the limitations in the WebSphere environment are too severe, if you need load-time weaving in Java 1.4 and below, better to use a patched ClassLoader like AspectWerkz creates (Glassbox distributes an open source verion of these that works with current AspectJ releases, updating the blog entry that Alex Vasseur posted. See www.glassbox.com for information on downloading).