Bug 111027 - Contribution: Loadtime Weaving Agent for WebSphere
Summary: Contribution: Loadtime Weaving Agent for WebSphere
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Windows XP
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Adrian Colyer CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-09-28 23:40 EDT by Ron Bodkin CLA
Modified: 2009-04-06 17:59 EDT (History)
3 users (show)

See Also:


Attachments
prebuilt plugin jar (976 bytes, application/x-zip-compressed)
2005-09-28 23:52 EDT, Ron Bodkin CLA
no flags Details
Updated source code with recursion protection (1.87 KB, application/octet-stream)
2006-06-30 14:05 EDT, Ron Bodkin CLA
no flags Details
Updated prebuilt jar with recursion protection (1.50 KB, application/java-archive)
2006-06-30 14:06 EDT, Ron Bodkin CLA
no flags Details
Updated pre-built jar. (5.81 KB, application/x-jar)
2007-03-22 03:18 EDT, Ron Bodkin CLA
no flags Details
Source code with tests for the plugin. (14.07 KB, application/zip)
2007-03-22 03:20 EDT, Ron Bodkin CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ron Bodkin CLA 2005-09-28 23:40:02 EDT
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!
Comment 1 Ron Bodkin CLA 2005-09-28 23:52:01 EDT
Created attachment 27659 [details]
prebuilt plugin jar
Comment 2 Ron Bodkin CLA 2006-06-30 14:05:23 EDT
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).
Comment 3 Ron Bodkin CLA 2006-06-30 14:06:51 EDT
Created attachment 45611 [details]
Updated prebuilt jar with recursion protection
Comment 4 Ron Bodkin CLA 2006-06-30 14:08:06 EDT
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.
Comment 5 Ron Bodkin CLA 2006-06-30 14:08:55 EDT
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.
Comment 6 Ron Bodkin CLA 2007-03-22 03:18:02 EDT
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.
Comment 7 Ron Bodkin CLA 2007-03-22 03:20:27 EDT
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.
Comment 8 Hermod Opstvedt CLA 2007-12-10 04:56:53 EST
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))
....
Comment 9 Sebastien Tardif CLA 2008-03-17 17:52:57 EDT
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)
Comment 10 Ankur Kapadia CLA 2009-03-13 13:28:14 EDT
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
Comment 11 Sebastien Tardif CLA 2009-03-13 13:35:05 EDT
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.
Comment 12 Ron Bodkin CLA 2009-04-06 17:59:42 EDT
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).