[
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?