aboutsummaryrefslogtreecommitdiffstats
path: root/loadtime
diff options
context:
space:
mode:
authoraclement <aclement>2011-05-02 18:38:42 +0000
committeraclement <aclement>2011-05-02 18:38:42 +0000
commitdf8d0534cd22effae9dfadc68f7c4bd553f9bb24 (patch)
treefd8fde84efc1030eba8b060eae8bb478bb4ee103 /loadtime
parent901c3192a53d8b97e47f8d9846c61304eb4f0526 (diff)
downloadaspectj-df8d0534cd22effae9dfadc68f7c4bd553f9bb24.tar.gz
aspectj-df8d0534cd22effae9dfadc68f7c4bd553f9bb24.zip
328099
Diffstat (limited to 'loadtime')
-rw-r--r--loadtime/src/org/aspectj/weaver/loadtime/Aj.java18
-rw-r--r--loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java54
-rw-r--r--loadtime/src/org/aspectj/weaver/loadtime/ClassPreProcessor.java35
-rw-r--r--loadtime/src/org/aspectj/weaver/loadtime/JRockitAgent.java54
4 files changed, 106 insertions, 55 deletions
diff --git a/loadtime/src/org/aspectj/weaver/loadtime/Aj.java b/loadtime/src/org/aspectj/weaver/loadtime/Aj.java
index db5337e38..3582da871 100644
--- a/loadtime/src/org/aspectj/weaver/loadtime/Aj.java
+++ b/loadtime/src/org/aspectj/weaver/loadtime/Aj.java
@@ -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 */
diff --git a/loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java b/loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java
index 13d2bccbb..cf3229035 100644
--- a/loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java
+++ b/loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java
@@ -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());
diff --git a/loadtime/src/org/aspectj/weaver/loadtime/ClassPreProcessor.java b/loadtime/src/org/aspectj/weaver/loadtime/ClassPreProcessor.java
index d50f59549..12e620215 100644
--- a/loadtime/src/org/aspectj/weaver/loadtime/ClassPreProcessor.java
+++ b/loadtime/src/org/aspectj/weaver/loadtime/ClassPreProcessor.java
@@ -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);
} \ No newline at end of file
diff --git a/loadtime/src/org/aspectj/weaver/loadtime/JRockitAgent.java b/loadtime/src/org/aspectj/weaver/loadtime/JRockitAgent.java
index 667b74e04..56ad0e958 100644
--- a/loadtime/src/org/aspectj/weaver/loadtime/JRockitAgent.java
+++ b/loadtime/src/org/aspectj/weaver/loadtime/JRockitAgent.java
@@ -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();
}