Bläddra i källkod

328099

tags/V1_6_12M1
aclement 13 år sedan
förälder
incheckning
df8d0534cd

+ 12
- 6
loadtime/src/org/aspectj/weaver/loadtime/Aj.java Visa fil

@@ -13,6 +13,7 @@ package org.aspectj.weaver.loadtime;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.security.ProtectionDomain;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
@@ -73,7 +74,7 @@ public class Aj implements ClassPreProcessor {
* @param loader
* @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
if (loader == null || className == null || loader.getClass().getName().equals(deleLoader)) {
// skip boot loader, null classes (hibernate), or those from a reflection loader
@@ -93,11 +94,16 @@ public class Aj implements ClassPreProcessor {
trace.exit("preProcess");
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 */

+ 48
- 6
loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java Visa fil

@@ -19,6 +19,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
@@ -137,8 +138,12 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor {
} catch (Throwable throwable) {
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
}
}
}

@@ -977,6 +982,9 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor {
generatedClasses = new HashMap();
}

private Method defineClassMethod;
private Method defineClassWithProtectionDomainMethod;

private void defineClass(ClassLoader loader, String name, byte[] bytes) {
if (trace.isTraceEnabled()) {
trace.enter("defineClass", this, new Object[] { loader, name, bytes });
@@ -985,11 +993,45 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor {
debug("generating class '" + name + "'");

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) {
if (e.getTargetException() instanceof LinkageError) {
warn("define generated class failed", e.getTargetException());

+ 19
- 16
loadtime/src/org/aspectj/weaver/loadtime/ClassPreProcessor.java Visa fil

@@ -11,26 +11,29 @@
*******************************************************************************/
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
*/
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 Visa fil

@@ -16,66 +16,66 @@ import com.bea.jvm.ClassLibrary;
import com.bea.jvm.JVMFactory;

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

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();
public JRockitAgent () {

public JRockitAgent() {
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) {
byte[] newBytes = bytes;

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

private static class ThreadLocalStack extends ThreadLocal {

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

public Object peek () {
public Object peek() {
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;
}
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);
}
public Object pop () {
Stack stack = (Stack)get();
public Object pop() {
Stack stack = (Stack) get();
return stack.pop();
}
protected Object initialValue() {
return new Stack();
}

Laddar…
Avbryt
Spara