Browse Source

328099

tags/V1_6_12M1
aclement 13 years ago
parent
commit
df8d0534cd

+ 12
- 6
loadtime/src/org/aspectj/weaver/loadtime/Aj.java View File



import java.lang.ref.ReferenceQueue; import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.security.ProtectionDomain;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
* @param loader * @param loader
* @return weaved bytes * @return weaved bytes
*/ */
public byte[] preProcess(String className, byte[] bytes, ClassLoader loader) {
public byte[] preProcess(String className, byte[] bytes, ClassLoader loader, ProtectionDomain protectionDomain) {
// TODO AV needs to doc that // TODO AV needs to doc that
if (loader == null || className == null || loader.getClass().getName().equals(deleLoader)) { if (loader == null || className == null || loader.getClass().getName().equals(deleLoader)) {
// skip boot loader, null classes (hibernate), or those from a reflection loader // skip boot loader, null classes (hibernate), or those from a reflection loader
trace.exit("preProcess"); trace.exit("preProcess");
return bytes; return bytes;
} }
byte[] newBytes = weavingAdaptor.weaveClass(className, bytes, false);
Dump.dumpOnExit(weavingAdaptor.getMessageHolder(), true);
if (trace.isTraceEnabled())
trace.exit("preProcess", newBytes);
return newBytes;
try {
weavingAdaptor.setActiveProtectionDomain(protectionDomain);
byte[] newBytes = weavingAdaptor.weaveClass(className, bytes, false);
Dump.dumpOnExit(weavingAdaptor.getMessageHolder(), true);
if (trace.isTraceEnabled())
trace.exit("preProcess", newBytes);
return newBytes;
} finally {
weavingAdaptor.setActiveProtectionDomain(null);
}
} }


/* Don't like to do this but JVMTI swallows all exceptions */ /* Don't like to do this but JVMTI swallows all exceptions */

+ 48
- 6
loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java View File

import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.security.ProtectionDomain;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
} catch (Throwable throwable) { } catch (Throwable throwable) {
throwable.printStackTrace(); throwable.printStackTrace();
} }
if (activeProtectionDomain != null) {
defineClass(loaderRef.getClassLoader(), name, bytes, activeProtectionDomain);
} else {
defineClass(loaderRef.getClassLoader(), name, bytes); // could be done lazily using the hook


defineClass(loaderRef.getClassLoader(), name, bytes); // could be done lazily using the hook
}
} }
} }


generatedClasses = new HashMap(); generatedClasses = new HashMap();
} }


private Method defineClassMethod;
private Method defineClassWithProtectionDomainMethod;

private void defineClass(ClassLoader loader, String name, byte[] bytes) { private void defineClass(ClassLoader loader, String name, byte[] bytes) {
if (trace.isTraceEnabled()) { if (trace.isTraceEnabled()) {
trace.enter("defineClass", this, new Object[] { loader, name, bytes }); trace.enter("defineClass", this, new Object[] { loader, name, bytes });
debug("generating class '" + name + "'"); debug("generating class '" + name + "'");


try { try {
// TODO av protection domain, and optimize
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", new Class[] { String.class, bytes.getClass(),
int.class, int.class });
defineClass.setAccessible(true);
clazz = defineClass.invoke(loader, new Object[] { name, bytes, new Integer(0), new Integer(bytes.length) });
if (defineClassMethod == null) {
defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass", new Class[] { String.class,
bytes.getClass(), int.class, int.class });
}
defineClassMethod.setAccessible(true);
clazz = defineClassMethod.invoke(loader, new Object[] { name, bytes, new Integer(0), new Integer(bytes.length) });
} catch (InvocationTargetException e) {
if (e.getTargetException() instanceof LinkageError) {
warn("define generated class failed", e.getTargetException());
// is already defined (happens for X$ajcMightHaveAspect interfaces since aspects are reweaved)
// TODO maw I don't think this is OK and
} else {
warn("define generated class failed", e.getTargetException());
}
} catch (Exception e) {
warn("define generated class failed", e);
}

if (trace.isTraceEnabled()) {
trace.exit("defineClass", clazz);
}
}

private void defineClass(ClassLoader loader, String name, byte[] bytes, ProtectionDomain protectionDomain) {
if (trace.isTraceEnabled()) {
trace.enter("defineClass", this, new Object[] { loader, name, bytes, protectionDomain });
}
Object clazz = null;
debug("generating class '" + name + "'");

try {
// System.out.println(">> Defining with protection domain " + name + " pd=" + protectionDomain);
if (defineClassWithProtectionDomainMethod == null) {
defineClassWithProtectionDomainMethod = ClassLoader.class.getDeclaredMethod("defineClass", new Class[] {
String.class, bytes.getClass(), int.class, int.class, ProtectionDomain.class });
}
defineClassWithProtectionDomainMethod.setAccessible(true);
clazz = defineClassWithProtectionDomainMethod.invoke(loader, new Object[] { name, bytes, new Integer(0),
new Integer(bytes.length), protectionDomain });
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
if (e.getTargetException() instanceof LinkageError) { if (e.getTargetException() instanceof LinkageError) {
warn("define generated class failed", e.getTargetException()); warn("define generated class failed", e.getTargetException());

+ 19
- 16
loadtime/src/org/aspectj/weaver/loadtime/ClassPreProcessor.java View File

*******************************************************************************/ *******************************************************************************/
package org.aspectj.weaver.loadtime; package org.aspectj.weaver.loadtime;


import java.security.ProtectionDomain;

/** /**
* Generic class pre processor interface that allows to separate the AspectJ 5 load time weaving
* from Java 5 JVMTI interfaces for further use on Java 1.3 / 1.4
*
* Generic class pre processor interface that allows to separate the AspectJ 5 load time weaving from Java 5 JVMTI interfaces for
* further use on Java 1.3 / 1.4
*
* @author Alexandre Vasseur * @author Alexandre Vasseur
*/ */
public interface ClassPreProcessor { public interface ClassPreProcessor {


/**
* Post constructor initialization, usually empty
*/
void initialize();
/**
* Post constructor initialization, usually empty
*/
void initialize();


/**
* Weave
*
* @param className
* @param bytes
* @param classLoader
* @return
*/
byte[] preProcess(String className, byte[] bytes, ClassLoader classLoader);
/**
* Weave
*
* @param className
* @param bytes
* @param classLoader
* @param a protection domain that may be used for defining extraneous classes generated as part of modifying the one passed in
* @return
*/
byte[] preProcess(String className, byte[] bytes, ClassLoader classLoader, ProtectionDomain protectionDomain);
} }

+ 27
- 27
loadtime/src/org/aspectj/weaver/loadtime/JRockitAgent.java View File

import com.bea.jvm.JVMFactory; import com.bea.jvm.JVMFactory;


/** /**
* BEA JRocket JMAPI agent.
* BEA JRocket JMAPI agent.
* *
* Use "-Xmanagement:class=org.aspectj.weaver.loadtime.JRockitAgent" * Use "-Xmanagement:class=org.aspectj.weaver.loadtime.JRockitAgent"
*/ */
public class JRockitAgent implements com.bea.jvm.ClassPreProcessor { public class JRockitAgent implements com.bea.jvm.ClassPreProcessor {


private ClassPreProcessor preProcessor; private ClassPreProcessor preProcessor;
/* /*
* This is used to implement the recursion protection offered by JVMTI
* but not by JRockit JMAPI. I we are called to preProcess a class while
* already preProcessing another we will return immediately
* This is used to implement the recursion protection offered by JVMTI but not by JRockit JMAPI. I we are called to preProcess a
* class while already preProcessing another we will return immediately
*/ */
private static ThreadLocalStack stack = new ThreadLocalStack(); private static ThreadLocalStack stack = new ThreadLocalStack();
public JRockitAgent () {

public JRockitAgent() {
this.preProcessor = new Aj(); this.preProcessor = new Aj();
ClassLibrary cl = JVMFactory.getJVM().getClassLibrary();
cl.setClassPreProcessor(this);
ClassLibrary cl = JVMFactory.getJVM().getClassLibrary();
cl.setClassPreProcessor(this);
} }
public byte[] preProcess(ClassLoader loader, String className, byte[] bytes) { public byte[] preProcess(ClassLoader loader, String className, byte[] bytes) {
byte[] newBytes = bytes; byte[] newBytes = bytes;


if (stack.empty()) { if (stack.empty()) {
stack.push(className); stack.push(className);
newBytes = preProcessor.preProcess(className, bytes, loader);
newBytes = preProcessor.preProcess(className, bytes, loader, null);
stack.pop(); stack.pop();
} }
return newBytes; return newBytes;
} }


private static class ThreadLocalStack extends ThreadLocal { private static class ThreadLocalStack extends ThreadLocal {


public boolean empty () {
Stack stack = (Stack)get();
public boolean empty() {
Stack stack = (Stack) get();
return stack.empty(); return stack.empty();
} }


public Object peek () {
public Object peek() {
Object obj = null; Object obj = null;
Stack stack = (Stack)get();
if (!stack.empty()) obj = stack.peek();
Stack stack = (Stack) get();
if (!stack.empty())
obj = stack.peek();
return obj; return obj;
} }
public void push (Object obj) {
Stack stack = (Stack)get();
if (!stack.empty() && obj == stack.peek()) throw new RuntimeException(obj.toString());

public void push(Object obj) {
Stack stack = (Stack) get();
if (!stack.empty() && obj == stack.peek())
throw new RuntimeException(obj.toString());
stack.push(obj); stack.push(obj);
} }
public Object pop () {
Stack stack = (Stack)get();
public Object pop() {
Stack stack = (Stack) get();
return stack.pop(); return stack.pop();
} }
protected Object initialValue() { protected Object initialValue() {
return new Stack(); return new Stack();
} }

Loading…
Cancel
Save