Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] WeavingAdapter - how to use it?

To Silviu Andrica and Andy Clement or whoever remembers this old thread:
http://dev.eclipse.org/mhonarc/lists/aspectj-users/msg11505.html

> If you add "-Xbootclasspath/p:<path_to_aspects.jar>" JVM option, then you can instrument inside the JDKs and also instrument already loaded classes.

I am interested in the second option (the former afterwards maybe). How do you use this class to instrument and replace an already loaded class? I mean do you have a code snippet showing which parameters you submit to "transform" and hoow to replace an already loaded class? Specifically:
  - Which loader do you use? A WeavingURLClassLoader or the
    loader the weaving target was initially loaded by?
  - Where does the byte array for the class to be woven come from?
    Can I get the class's bytes somehwere from memory or do I need
    to re-load the actual .class file from disk/URL/JAR/whatever?

Sorry, this is my first time being so deep into the internal LTW process.
-- 
Alexander Kriegisch


Silviu Andrica wrote in 2009:
> Hello,
> 
> I looked through AspectJ's Load Time Weaver and I combined it with your code suggestion.
> This is what I got out
> 
> import java.lang.instrument.ClassFileTransformer;
> import java.lang.instrument.IllegalClassFormatException;
> import java.security.ProtectionDomain;
> import java.util.ArrayList;
> import java.util.Arrays;
> import java.util.List;
> import java.util.Map;
> import java.util.concurrent.ConcurrentHashMap;
> 
> import org.aspectj.weaver.loadtime.Aj;
> import org.aspectj.weaver.loadtime.DefaultWeavingContext;
> import org.aspectj.weaver.loadtime.definition.Definition;
> import org.aspectj.weaver.tools.WeavingAdaptor;
> 
> public class AspectJLTW implements ClassFileTransformer {
> 
> 	private class MonitorWeavingContext extends DefaultWeavingContext {
> 
> 		public MonitorWeavingContext(ClassLoader loader) {
> 			super(loader);
> 		}
> 
> 		@Override
> 		public List getDefinitions(ClassLoader loader, WeavingAdaptor adaptor) {
> 			List definitions = new ArrayList();
> 			Definition d = new Definition();
> 			d.getAspectClassNames().add(aspectName);
> 			d.appendWeaverOptions("-Xjoinpoints:synchronization");
> 			definitions.add(d);
> 			return definitions;
> 		}
> 
> 	}
> 
> 	private final Map<ClassLoader, Aj> mapFromClassLoaderToAj;
> 	private final String aspectName;
> 
> 	public AspectJLTW(String aspectName) {
> 		try {
> 			mapFromClassLoaderToAj = new ConcurrentHashMap<ClassLoader, Aj>();
> 			this.aspectName = aspectName;
> 		} catch (Exception e) {
> 			throw new ExceptionInInitializerError(
> 					"could not initialize JSR163 preprocessor due to: "
> 							+ e.toString());
> 		}
> 	}
> 
> 	/**
> 	 * Weaving delegation
> 	 * 
> 	 * @param loader
> 	 *            the defining class loader
> 	 * @param className
> 	 *            the name of class beeing loaded
> 	 * @param classBeingRedefined
> 	 *            when hotswap is called
> 	 * @param protectionDomain
> 	 * @param bytes
> 	 *            the bytecode before weaving
> 	 * @return the weaved bytecode
> 	 */
> 	public byte[] transform(ClassLoader loader, String className,
> 			Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
> 			byte[] bytes) throws IllegalClassFormatException {
> 		if (className.replace("/", ".").equals(aspectName))
> 			return null;
> 		Aj aj = getInstrumenter(loader);
> 		byte[] b = aj.preProcess(className, bytes, loader);
> 		if (Arrays.equals(bytes, b))
> 			return null;
> 		return b;
> 	}
> 
> 	private Aj getInstrumenter(ClassLoader loader) {
> 		if (mapFromClassLoaderToAj.containsKey(loader)) {
> 			return mapFromClassLoaderToAj.get(loader);
> 		}
> 		Aj aj = new Aj(new MonitorWeavingContext(loader));
> 		mapFromClassLoaderToAj.put(loader, aj);
> 		return aj;
> 	}
> }
> 
> If you add "-Xbootclasspath/p:<path_to_aspects.jar>" JVM option, then you can instrument inside the JDKs and also instrument already loaded classes.
> I tried it on Java 1.6.0_15 on Mac OSX.
> 
> One little note: JVM complains about java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the schema (add/remove fields). I suspect t has something to do with AspectJ adding extra fields. Is there a way to force inlining of the aspects?


Back to the top