You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ti...@apache.org on 2012/02/02 10:22:22 UTC
svn commit: r1239498 [1/2] - in /aries/trunk/proxy/proxy-impl/src:
main/java/org/apache/aries/proxy/impl/
main/java/org/apache/aries/proxy/impl/common/
main/java/org/apache/aries/proxy/impl/interfaces/
main/java/org/apache/aries/proxy/impl/weaving/ tes...
Author: timothyjward
Date: Thu Feb 2 09:22:21 2012
New Revision: 1239498
URL: http://svn.apache.org/viewvc?rev=1239498&view=rev
Log:
ARIES-821: Allow woven subclasses to subclass non-woven types
Added:
aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/MethodCopyingClassAdapter.java
- copied, changed from r1239088, aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/MethodCopyingClassAdapter.java
aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/WovenProxyAbstractMethodAdapter.java
- copied, changed from r1239088, aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceUsingWovenProxyMethodAdapter.java
aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/WovenProxyConcreteMethodAdapter.java
- copied, changed from r1239088, aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/WovenProxyMethodAdapter.java
aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxyTestClassGeneralWithNoDefaultOrProtectedAccess.java (with props)
aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxyTestClassSuperWithNoDefaultOrProtectedAccess.java (with props)
aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenProxyPlusSubclassGeneratorTest.java (with props)
aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenSubclassGeneratorTest.java (with props)
Removed:
aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceUsingWovenProxyMethodAdapter.java
aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/MethodCopyingClassAdapter.java
aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/WovenProxyMethodAdapter.java
Modified:
aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/AsmProxyManager.java
aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/AbstractWovenProxyAdapter.java
aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/AbstractWovenProxyMethodAdapter.java
aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceCombiningClassAdapter.java
aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceProxyGenerator.java
aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceUsingWovenProxyAdapter.java
aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/ProxyClassLoader.java
aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/WovenProxyAdapter.java
aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/AbstractProxyTest.java
aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxySubclassGeneratorTest.java
aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenProxyGeneratorTest.java
Modified: aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/AsmProxyManager.java
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/AsmProxyManager.java?rev=1239498&r1=1239497&r2=1239498&view=diff
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/AsmProxyManager.java (original)
+++ aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/AsmProxyManager.java Thu Feb 2 09:22:21 2012
@@ -96,7 +96,7 @@ public final class AsmProxyManager exten
" and is final. This means that we cannot create a proxy for both the class and all of the requested interfaces.");
}
proxyObject = InterfaceProxyGenerator.getProxyInstance(clientBundle,
- (Class<? extends WovenProxy>)classToProxy, interfaces, dispatcher, listener);
+ classToProxy, interfaces, dispatcher, listener);
}
}
if(proxyObject == null){
Modified: aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/AbstractWovenProxyAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/AbstractWovenProxyAdapter.java?rev=1239498&r1=1239497&r2=1239498&view=diff
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/AbstractWovenProxyAdapter.java (original)
+++ aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/AbstractWovenProxyAdapter.java Thu Feb 2 09:22:21 2012
@@ -182,6 +182,10 @@ public abstract class AbstractWovenProxy
* where the method is actually written.
*/
private int staticInitMethodFlags = ACC_SYNTHETIC | ACC_PRIVATE | ACC_STATIC;
+
+ protected Type currentMethodDeclaringType;
+
+ protected boolean currentMethodDeclaringTypeIsInterface;
public static final int JAVA_CLASS_VERSION = new BigDecimal(System.getProperty("java.class.version")).intValue();
public static final boolean IS_AT_LEAST_JAVA_6 = JAVA_CLASS_VERSION >= Opcodes.V1_6;
@@ -200,6 +204,9 @@ public abstract class AbstractWovenProxy
ClassLoader loader) {
super(Opcodes.ASM4, writer);
typeBeingWoven = Type.getType("L" + className.replace('.', '/') + ";");
+ //By default we expect to see methods from a concrete class
+ currentMethodDeclaringType = typeBeingWoven;
+ currentMethodDeclaringTypeIsInterface = false;
this.loader = loader;
}
@@ -324,7 +331,7 @@ public abstract class AbstractWovenProxy
// Only weave "real" instance methods. Not constructors, initializers or
// compiler generated ones.
- if ((access & (ACC_STATIC | ACC_PRIVATE | ACC_SYNTHETIC | ACC_ABSTRACT
+ if ((access & (ACC_STATIC | ACC_PRIVATE | ACC_SYNTHETIC
| ACC_NATIVE | ACC_BRIDGE)) == 0 && !!!name.equals("<init>") &&
!!!name.equals("<clinit>")) {
@@ -333,11 +340,12 @@ public abstract class AbstractWovenProxy
//Create a field name and store it for later
String methodStaticFieldName = "methodField" + getSanitizedUUIDString();
transformedMethods.put(methodStaticFieldName, new TypeMethod(
- getDeclaringTypeForCurrentMethod(), currentMethod));
+ currentMethodDeclaringType, currentMethod));
// Surround the MethodVisitor with our weaver so we can manipulate the code
methodVisitorToReturn = getWeavingMethodVisitor(access, name, desc,
- signature, exceptions, currentMethod, methodStaticFieldName);
+ signature, exceptions, currentMethod, methodStaticFieldName,
+ currentMethodDeclaringType, currentMethodDeclaringTypeIsInterface);
} else if (name.equals("<clinit>")){
//there is an existing clinit method, change the fields we use
//to write our init code to static_init_UUID instead
@@ -372,6 +380,16 @@ public abstract class AbstractWovenProxy
public void visitEnd() {
LOGGER.debug(Constants.LOG_ENTRY, "visitEnd");
+ for(Class<?> c : nonObjectSupers) {
+ setCurrentMethodDeclaringType(Type.getType(c), false);
+ try {
+ readClass(c, new MethodCopyingClassAdapter(this, loader, c, typeBeingWoven,
+ getKnownMethods(), transformedMethods));
+ } catch (IOException e) {
+ // This should never happen! <= famous last words (not)
+ throw new RuntimeException(NLS.MESSAGES.getMessage("unexpected.error.processing.class", c.getName(), typeBeingWoven.getClassName()), e);
+ }
+ }
// If we need to implement woven proxy in this class then write the methods
if (implementWovenProxy) {
writeFinalWovenProxyMethods();
@@ -408,15 +426,9 @@ public abstract class AbstractWovenProxy
*/
protected abstract MethodVisitor getWeavingMethodVisitor(int access, String name,
String desc, String signature, String[] exceptions, Method currentMethod,
- String methodStaticFieldName);
+ String methodStaticFieldName, Type currentMethodDeclaringType,
+ boolean currentMethodDeclaringTypeIsInterface);
- /**
- * Get the Type which declares the method being currently processed. For class
- * weaving this will be the {@link #typeBeingWoven}, for dynamic interface
- * implementation this will be the interface type.
- * @return
- */
- protected abstract Type getDeclaringTypeForCurrentMethod();
/**
* Write the methods we need for wovenProxies on the highest supertype
@@ -694,4 +706,9 @@ public abstract class AbstractWovenProxy
ga.visitCode();
return ga;
}
+
+ public final void setCurrentMethodDeclaringType(Type type, boolean isInterface) {
+ currentMethodDeclaringType = type;
+ currentMethodDeclaringTypeIsInterface = isInterface;
+ }
}
\ No newline at end of file
Modified: aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/AbstractWovenProxyMethodAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/AbstractWovenProxyMethodAdapter.java?rev=1239498&r1=1239497&r2=1239498&view=diff
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/AbstractWovenProxyMethodAdapter.java (original)
+++ aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/AbstractWovenProxyMethodAdapter.java Thu Feb 2 09:22:21 2012
@@ -42,8 +42,8 @@ import org.objectweb.asm.commons.Generat
import org.objectweb.asm.commons.Method;
/**
* This class weaves dispatch and listener code into a method, there are two known
- * subclasses {@link WovenProxyMethodAdapter} is used for weaving instance methods
- * {@link InterfaceUsingWovenProxyMethodAdapter} is used to provide a delegating
+ * subclasses {@link WovenProxyConcreteMethodAdapter} is used for weaving instance methods
+ * {@link WovenProxyAbstractMethodAdapter} is used to provide a delegating
* implementation of an interface method.
*
* Roughly (but not exactly because it's easier to write working bytecode
@@ -158,6 +158,10 @@ public abstract class AbstractWovenProxy
/** The return type of this method */
private final Type returnType;
+ private final Type methodDeclaringType;
+
+ private final boolean isMethodDeclaringTypeInterface;
+
/**
* Construct a new method adapter
* @param mv - the method visitor to write to
@@ -171,7 +175,8 @@ public abstract class AbstractWovenProxy
* @param proxyType - the type being woven that contains this method
*/
public AbstractWovenProxyMethodAdapter(MethodVisitor mv, int access, String name, String desc,
- String methodStaticFieldName, Method currentTransformMethod, Type typeBeingWoven)
+ String methodStaticFieldName, Method currentTransformMethod, Type typeBeingWoven,
+ Type methodDeclaringType, boolean isMethodDeclaringTypeInterface)
{
super(mv, access, name, desc);
this.methodStaticFieldName = methodStaticFieldName;
@@ -179,6 +184,8 @@ public abstract class AbstractWovenProxy
returnType = currentTransformMethod.getReturnType();
isVoid = returnType.getSort() == Type.VOID;
this.typeBeingWoven = typeBeingWoven;
+ this.methodDeclaringType = methodDeclaringType;
+ this.isMethodDeclaringTypeInterface = isMethodDeclaringTypeInterface;
}
@Override
@@ -214,12 +221,12 @@ public abstract class AbstractWovenProxy
//Dispatch the method and store the result (null for void)
loadLocal(dispatchTarget);
- checkCast(getTypeToCastTo());
+ checkCast(methodDeclaringType);
loadArgs();
- if(isTypeToCastToInterface()) {
- invokeInterface(getTypeToCastTo(), currentTransformMethod);
+ if(isMethodDeclaringTypeInterface) {
+ invokeInterface(methodDeclaringType, currentTransformMethod);
} else {
- invokeVirtual(getTypeToCastTo(), currentTransformMethod);
+ invokeVirtual(methodDeclaringType, currentTransformMethod);
}
if(isVoid) {
visitInsn(ACONST_NULL);
@@ -243,14 +250,6 @@ public abstract class AbstractWovenProxy
}
/**
- * Get the type to which the class should be cast for delegation
- * @return
- */
- protected abstract Type getTypeToCastTo();
-
- protected abstract boolean isTypeToCastToInterface();
-
- /**
* Setup the normalResult, inNormalMethod, preInvokeReturnedToken and
* dispatch target locals.
*/
Copied: aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/MethodCopyingClassAdapter.java (from r1239088, aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/MethodCopyingClassAdapter.java)
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/MethodCopyingClassAdapter.java?p2=aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/MethodCopyingClassAdapter.java&p1=aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/MethodCopyingClassAdapter.java&r1=1239088&r2=1239498&rev=1239498&view=diff
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/MethodCopyingClassAdapter.java (original)
+++ aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/MethodCopyingClassAdapter.java Thu Feb 2 09:22:21 2012
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.aries.proxy.impl.weaving;
+package org.apache.aries.proxy.impl.common;
import java.util.Map;
import java.util.Set;
@@ -24,8 +24,6 @@ import java.util.Set;
import org.apache.aries.proxy.FinalModifierException;
import org.apache.aries.proxy.UnableToProxyException;
import org.apache.aries.proxy.impl.NLS;
-import org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter;
-import org.apache.aries.proxy.impl.common.TypeMethod;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
@@ -33,18 +31,17 @@ import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
/**
- * This class is used to copy methods from a super-class into a sub-class, but
- * then delegate up to the super-class implementation. We expect to be called
+ * This class is used to copy concrete methods from a super-class into a sub-class,
+ * but then delegate up to the super-class implementation. We expect to be called
* with {@link ClassReader#SKIP_CODE}. This class is used when we can't weave
* all the way up the Class hierarchy and need to override methods on the first
* subclass we can weave.
*/
final class MethodCopyingClassAdapter extends ClassVisitor implements Opcodes {
- /** The sub-class visitor to write to */
- private final ClassVisitor cv;
/** The super-class to copy from */
private final Class<?> superToCopy;
/** Is the sub-class in the same package as the super */
@@ -61,23 +58,36 @@ final class MethodCopyingClassAdapter ex
*/
private final Map<String, TypeMethod> transformedMethods;
- public MethodCopyingClassAdapter(ClassVisitor cv, Class<?> superToCopy,
- Type overridingClassType, Set<Method> knownMethods,
+ private final AbstractWovenProxyAdapter wovenProxyAdapter;
+
+ public MethodCopyingClassAdapter(AbstractWovenProxyAdapter awpa, ClassLoader definingLoader,
+ Class<?> superToCopy, Type overridingClassType, Set<Method> knownMethods,
Map<String, TypeMethod> transformedMethods) {
super(Opcodes.ASM4);
- this.cv = cv;
+ this.wovenProxyAdapter = awpa;
this.superToCopy = superToCopy;
this.overridingClassType = overridingClassType;
this.knownMethods = knownMethods;
this.transformedMethods = transformedMethods;
- String overridingClassName = overridingClassType.getClassName();
- int lastIndex1 = superToCopy.getName().lastIndexOf('.');
- int lastIndex2 = overridingClassName.lastIndexOf('.');
-
- samePackage = (lastIndex1 == lastIndex2) &&
- superToCopy.getName().substring(0, (lastIndex1 == -1)? 1 : lastIndex1)
- .equals(overridingClassName.substring(0, (lastIndex2 == -1)? 1 : lastIndex2));
+ //To be in the same package they must be loaded by the same classloader and be in the same package!
+ if(definingLoader != superToCopy.getClassLoader()) {
+ samePackage = false;
+ } else {
+
+ String overridingClassName = overridingClassType.getClassName();
+ int lastIndex1 = superToCopy.getName().lastIndexOf('.');
+ int lastIndex2 = overridingClassName.lastIndexOf('.');
+
+ if(lastIndex1 != lastIndex2) {
+ samePackage = false;
+ } else if (lastIndex1 == -1) {
+ samePackage = true;
+ } else {
+ samePackage = superToCopy.getName().substring(0, lastIndex1)
+ .equals(overridingClassName.substring(0, lastIndex2));
+ }
+ }
}
@Override
@@ -85,7 +95,8 @@ final class MethodCopyingClassAdapter ex
String sig, String[] exceptions) {
MethodVisitor mv = null;
- //As in WovenProxyAdapter, we only care about "real" methods.
+ //As in WovenProxyAdapter, we only care about "real" methods, but also not
+ //abstract ones!.
if (!!!name.equals("<init>") && !!!name.equals("<clinit>")
&& (access & (ACC_STATIC | ACC_PRIVATE | ACC_SYNTHETIC | ACC_ABSTRACT
| ACC_NATIVE | ACC_BRIDGE)) == 0) {
@@ -101,7 +112,7 @@ final class MethodCopyingClassAdapter ex
if((access & ACC_FINAL) != 0)
throw new RuntimeException(new FinalModifierException(
superToCopy, name));
- // We can't call up to a package protected method if we aren't in the same
+ // We can't call up to a default access method if we aren't in the same
// package
if((access & (ACC_PUBLIC | ACC_PROTECTED | ACC_PRIVATE)) == 0) {
if(!!!samePackage)
@@ -118,10 +129,27 @@ final class MethodCopyingClassAdapter ex
//Remember we need to copy the fake method *and* weave it, use a
//WovenProxyMethodAdapter as well as a CopyingMethodAdapter
- mv = new CopyingMethodAdapter(new WovenProxyMethodAdapter(cv.visitMethod(
- access, name, desc, sig, exceptions), access, name, desc, exceptions,
- methodStaticFieldName, currentTransformMethod, overridingClassType),
- superType, currentTransformMethod);
+
+ MethodVisitor weaver = wovenProxyAdapter.getWeavingMethodVisitor(
+ access, name, desc, sig, exceptions, currentTransformMethod,
+ methodStaticFieldName, superType, false);
+
+ if(weaver instanceof AbstractWovenProxyMethodAdapter) {
+ //If we are weaving this method then we might have a problem. If it's a protected method and we
+ //aren't in the same package then we can't dispatch the call to another object. This may sound
+ //odd, but if class Super has a protected method foo(), then class Sub, that extends Super, cannot
+ //call ((Super)o).foo() in code (it can call super.foo()). If we are in the same package then this
+ //gets around the problem, but if not the class will fail verification.
+ if(!samePackage && (access & ACC_PROTECTED) != 0)
+ throw new RuntimeException(NLS.MESSAGES.getMessage("method.from.superclass.is.hidden", name, superToCopy.getName(), overridingClassType.getClassName()),
+ new UnableToProxyException(superToCopy));
+ mv = new CopyingMethodAdapter((GeneratorAdapter) weaver, superType, currentTransformMethod);
+ }
+ else {
+ //For whatever reason we aren't weaving this method. The call to super.xxx() will always work
+ mv = new CopyingMethodAdapter(new GeneratorAdapter(access, currentTransformMethod, mv),
+ superType, currentTransformMethod);
+ }
}
return mv;
@@ -134,13 +162,13 @@ final class MethodCopyingClassAdapter ex
*/
private static final class CopyingMethodAdapter extends MethodVisitor {
/** The visitor to delegate to */
- private final MethodVisitor mv;
+ private final GeneratorAdapter mv;
/** The type that declares this method (not the one that will override it) */
private final Type superType;
/** The method we are weaving */
private final Method currentTransformMethod;
- public CopyingMethodAdapter(MethodVisitor mv, Type superType,
+ public CopyingMethodAdapter(GeneratorAdapter mv, Type superType,
Method currentTransformMethod) {
super(Opcodes.ASM4);
this.mv = mv;
@@ -177,69 +205,16 @@ final class MethodCopyingClassAdapter ex
@Override
public final void visitEnd() {
mv.visitCode();
- writeBody();
- mv.visitMaxs(currentTransformMethod.getArgumentTypes().length + 1, 0);
- mv.visitEnd();
- }
-
- /**
- * This method loads this, any args, then invokes the super version of this
- */
- private final void writeBody() {
- mv.visitVarInsn(ALOAD, 0);
-
- int nargs = currentTransformMethod.getArgumentTypes().length;
-
- for(int i = 1 ; i <= nargs ; i++) {
- switch(currentTransformMethod.
- getArgumentTypes()[i - 1].getSort()) {
- case (Type.BOOLEAN) :
- case (Type.BYTE) :
- case (Type.CHAR) :
- case (Type.SHORT) :
- case (Type.INT) :
- mv.visitVarInsn(ILOAD, i);
- break;
- case (Type.FLOAT) :
- mv.visitVarInsn(FLOAD, i);
- break;
- case (Type.DOUBLE) :
- mv.visitVarInsn(DLOAD, i);
- break;
- case (Type.LONG) :
- mv.visitVarInsn(LLOAD, i);
- break;
- default :
- mv.visitVarInsn(ALOAD, i);
- }
- }
- mv.visitMethodInsn(INVOKESPECIAL, superType.getInternalName(),
- currentTransformMethod.getName(), currentTransformMethod.getDescriptor());
-
- switch(currentTransformMethod.getReturnType().getSort()) {
- case (Type.BOOLEAN) :
- case (Type.BYTE) :
- case (Type.CHAR) :
- case (Type.SHORT) :
- case (Type.INT) :
- mv.visitInsn(IRETURN);
- break;
- case (Type.VOID) :
- mv.visitInsn(RETURN);
- break;
- case (Type.FLOAT) :
- mv.visitInsn(FRETURN);
- break;
- case (Type.DOUBLE) :
- mv.visitInsn(DRETURN);
- break;
- case (Type.LONG) :
- mv.visitInsn(LRETURN);
- break;
- default :
- mv.visitInsn(ARETURN);
- }
+ //Equivalent to return super.method(args);
+ mv.loadThis();
+ mv.loadArgs();
+ mv.visitMethodInsn(INVOKESPECIAL, superType.getInternalName(),
+ currentTransformMethod.getName(), currentTransformMethod.getDescriptor());
+ mv.returnValue();
+
+ mv.visitMaxs(currentTransformMethod.getArgumentTypes().length + 1, 0);
+ mv.visitEnd();
}
}
}
\ No newline at end of file
Copied: aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/WovenProxyAbstractMethodAdapter.java (from r1239088, aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceUsingWovenProxyMethodAdapter.java)
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/WovenProxyAbstractMethodAdapter.java?p2=aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/WovenProxyAbstractMethodAdapter.java&p1=aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceUsingWovenProxyMethodAdapter.java&r1=1239088&r2=1239498&rev=1239498&view=diff
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceUsingWovenProxyMethodAdapter.java (original)
+++ aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/WovenProxyAbstractMethodAdapter.java Thu Feb 2 09:22:21 2012
@@ -16,11 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.aries.proxy.impl.interfaces;
+package org.apache.aries.proxy.impl.common;
import static org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.OBJECT_TYPE;
-import org.apache.aries.proxy.impl.common.AbstractWovenProxyMethodAdapter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method;
@@ -28,19 +27,13 @@ import org.objectweb.asm.commons.Method;
/**
* Used to create a delegating method implementation for methods with no body
*/
-final class InterfaceUsingWovenProxyMethodAdapter extends AbstractWovenProxyMethodAdapter {
-
- private final Type typeToCastTo;
-
- private final boolean istypeToCastToInterface;
-
- public InterfaceUsingWovenProxyMethodAdapter(MethodVisitor mv, int access, String name,
+public final class WovenProxyAbstractMethodAdapter extends AbstractWovenProxyMethodAdapter {
+
+ public WovenProxyAbstractMethodAdapter(MethodVisitor mv, int access, String name,
String desc, String methodStaticFieldName, Method currentTransformMethod,
Type typeBeingWoven, Type methodDeclaringType, boolean isMethodDeclaringTypeInterface) {
super(mv, access, name, desc, methodStaticFieldName, currentTransformMethod,
- typeBeingWoven);
- this.typeToCastTo = methodDeclaringType;
- this.istypeToCastToInterface = isMethodDeclaringTypeInterface;
+ typeBeingWoven, methodDeclaringType, isMethodDeclaringTypeInterface);
}
/**
@@ -77,14 +70,4 @@ final class InterfaceUsingWovenProxyMeth
visitMaxs(0, 0);
mv.visitEnd();
}
-
- @Override
- protected final Type getTypeToCastTo() {
- return typeToCastTo;
- }
-
- @Override
- protected final boolean isTypeToCastToInterface() {
- return istypeToCastToInterface;
- }
}
Copied: aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/WovenProxyConcreteMethodAdapter.java (from r1239088, aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/WovenProxyMethodAdapter.java)
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/WovenProxyConcreteMethodAdapter.java?p2=aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/WovenProxyConcreteMethodAdapter.java&p1=aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/WovenProxyMethodAdapter.java&r1=1239088&r2=1239498&rev=1239498&view=diff
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/WovenProxyMethodAdapter.java (original)
+++ aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/common/WovenProxyConcreteMethodAdapter.java Thu Feb 2 09:22:21 2012
@@ -16,29 +16,29 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.aries.proxy.impl.weaving;
+package org.apache.aries.proxy.impl.common;
import static org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.DISPATCHER_FIELD;
import static org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.DISPATCHER_TYPE;
import static org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.OBJECT_TYPE;
-import org.apache.aries.proxy.impl.common.AbstractWovenProxyMethodAdapter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method;
-final class WovenProxyMethodAdapter extends AbstractWovenProxyMethodAdapter {
+public final class WovenProxyConcreteMethodAdapter extends AbstractWovenProxyMethodAdapter {
/** Jump here to start executing the original method body **/
private final Label executeDispatch = new Label();
- public WovenProxyMethodAdapter(MethodVisitor mv, int access, String name,
+ public WovenProxyConcreteMethodAdapter(MethodVisitor mv, int access, String name,
String desc, String[] exceptions, String methodStaticFieldName, Method currentTransformMethod,
- Type typeBeingWoven) {
+ Type typeBeingWoven, Type methodDeclaringType) {
//If we're running on Java 6+ We need to inline any JSR instructions because we're computing stack frames.
//otherwise we can save the overhead
- super(mv, access, name, desc, methodStaticFieldName, currentTransformMethod, typeBeingWoven);
+ super(mv, access, name, desc, methodStaticFieldName, currentTransformMethod, typeBeingWoven,
+ methodDeclaringType, false);
}
/**
@@ -75,14 +75,4 @@ final class WovenProxyMethodAdapter exte
writeDispatcher();
mv.visitMaxs(stack, locals);
}
-
- @Override
- protected final Type getTypeToCastTo() {
- return typeBeingWoven;
- }
-
- @Override
- protected final boolean isTypeToCastToInterface() {
- return false;
- }
}
\ No newline at end of file
Modified: aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceCombiningClassAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceCombiningClassAdapter.java?rev=1239498&r1=1239497&r2=1239498&view=diff
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceCombiningClassAdapter.java (original)
+++ aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceCombiningClassAdapter.java Thu Feb 2 09:22:21 2012
@@ -28,7 +28,6 @@ import org.apache.aries.proxy.UnableToPr
import org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter;
import org.apache.aries.proxy.impl.common.OSGiFriendlyClassVisitor;
import org.apache.aries.proxy.impl.common.OSGiFriendlyClassWriter;
-import org.apache.aries.proxy.weaving.WovenProxy;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
@@ -42,13 +41,13 @@ import org.objectweb.asm.commons.Method;
final class InterfaceCombiningClassAdapter extends ClassVisitor implements Opcodes {
/** The superclass we should use */
- private final Class<? extends WovenProxy> superclass;
+ private final Class<?> superclass;
/** The interfaces we need to implement */
private final Collection<Class<?>> interfaces;
/** The {@link ClassWriter} we use to write our class */
private final ClassWriter writer;
/** The adapter we use to weave in our method implementations */
- private final InterfaceUsingWovenProxyAdapter adapter;
+ private final AbstractWovenProxyAdapter adapter;
/** Whether we have already written the class bytes */
private boolean done = false;
@@ -60,7 +59,7 @@ final class InterfaceCombiningClassAdapt
* @param interfaces
*/
InterfaceCombiningClassAdapter(String className,
- ClassLoader loader, Class<? extends WovenProxy> superclass, Collection<Class<?>> interfaces) {
+ ClassLoader loader, Class<?> superclass, Collection<Class<?>> interfaces) {
super(Opcodes.ASM4);
writer = new OSGiFriendlyClassWriter(ClassWriter.COMPUTE_FRAMES, loader, className, (superclass!=null)? superclass.getName(): null);
ClassVisitor cv = new OSGiFriendlyClassVisitor(writer, ClassWriter.COMPUTE_FRAMES);
@@ -92,7 +91,7 @@ final class InterfaceCombiningClassAdapt
"<clinit>".equals(name))
return null;
else {//We're going to implement this method, so make it non abstract!
- return adapter.visitMethod(access & ~ACC_ABSTRACT, name, desc, null, arg4);
+ return adapter.visitMethod(access, name, desc, null, arg4);
}
}
@@ -119,13 +118,14 @@ final class InterfaceCombiningClassAdapt
visitAbstractMethods(clazz);
clazz = clazz.getSuperclass();
}
-
- adapter.setCurrentMethodDeclaringType(Type.getType(Object.class), false);
+
+ adapter.setCurrentMethodDeclaringType(AbstractWovenProxyAdapter.OBJECT_TYPE, false);
visitObjectMethods();
adapter.visitEnd();
done = true;
}
+
return writer.toByteArray();
}
@@ -150,13 +150,13 @@ final class InterfaceCombiningClassAdapt
* even if they are not on any of the interfaces
*/
private void visitObjectMethods() {
- MethodVisitor visitor = visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
- if (visitor != null) visitor.visitEnd();
-
- visitor = visitMethod(ACC_PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null);
- if (visitor != null) visitor.visitEnd();
+ MethodVisitor visitor = visitMethod(ACC_PUBLIC | ACC_ABSTRACT, "toString", "()Ljava/lang/String;", null, null);
+ if (visitor != null) visitor.visitEnd();
+
+ visitor = visitMethod(ACC_PUBLIC | ACC_ABSTRACT, "equals", "(Ljava/lang/Object;)Z", null, null);
+ if (visitor != null) visitor.visitEnd();
- visitor = visitMethod(ACC_PUBLIC, "hashCode", "()I", null, null);
- if (visitor != null) visitor.visitEnd();
+ visitor = visitMethod(ACC_PUBLIC | ACC_ABSTRACT, "hashCode", "()I", null, null);
+ if (visitor != null) visitor.visitEnd();
}
}
\ No newline at end of file
Modified: aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceProxyGenerator.java
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceProxyGenerator.java?rev=1239498&r1=1239497&r2=1239498&view=diff
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceProxyGenerator.java (original)
+++ aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceProxyGenerator.java Thu Feb 2 09:22:21 2012
@@ -20,6 +20,7 @@ package org.apache.aries.proxy.impl.inte
import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
@@ -29,9 +30,9 @@ import java.util.TreeSet;
import java.util.WeakHashMap;
import java.util.concurrent.Callable;
+import org.apache.aries.proxy.FinalModifierException;
import org.apache.aries.proxy.InvocationListener;
import org.apache.aries.proxy.UnableToProxyException;
-import org.apache.aries.proxy.weaving.WovenProxy;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
import org.osgi.framework.Bundle;
@@ -64,9 +65,12 @@ public final class InterfaceProxyGenerat
* @return
* @throws UnableToProxyException
*/
- public static final Object getProxyInstance(Bundle client, Class<? extends WovenProxy> superclass,
+ public static final Object getProxyInstance(Bundle client, Class<?> superclass,
Collection<Class<?>> ifaces, Callable<Object> dispatcher, InvocationListener listener) throws UnableToProxyException{
+ if(superclass != null && (superclass.getModifiers() & Modifier.FINAL) != 0)
+ throw new FinalModifierException(superclass);
+
ProxyClassLoader pcl = null;
SortedSet<Class<?>> interfaces = createSet(ifaces);
Modified: aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceUsingWovenProxyAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceUsingWovenProxyAdapter.java?rev=1239498&r1=1239497&r2=1239498&view=diff
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceUsingWovenProxyAdapter.java (original)
+++ aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceUsingWovenProxyAdapter.java Thu Feb 2 09:22:21 2012
@@ -19,6 +19,9 @@
package org.apache.aries.proxy.impl.interfaces;
import org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter;
+import org.apache.aries.proxy.impl.common.AbstractWovenProxyMethodAdapter;
+import org.apache.aries.proxy.impl.common.WovenProxyAbstractMethodAdapter;
+import org.apache.aries.proxy.impl.common.WovenProxyConcreteMethodAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
@@ -29,33 +32,32 @@ import org.objectweb.asm.commons.Method;
*/
final class InterfaceUsingWovenProxyAdapter extends AbstractWovenProxyAdapter {
- private Type currentMethodDeclaringType;
- private boolean currentMethodDeclaringTypeIsInterface;
-
public InterfaceUsingWovenProxyAdapter(ClassVisitor writer, String className,
ClassLoader loader) {
super(writer, className, loader);
}
- public final void setCurrentMethodDeclaringType(Type type, boolean isInterface) {
- currentMethodDeclaringType = type;
- currentMethodDeclaringTypeIsInterface = isInterface;
- }
-
/**
- * Return a {@link MethodVisitor} that copes with interfaces
+ * Return a {@link MethodVisitor} that provides basic implementations for all
+ * methods - the easiest thing to do for methods that aren't abstract is to
+ * pretend that they are, but drive the adapter ourselves
*/
- protected final MethodVisitor getWeavingMethodVisitor(int access, String name,
+ protected final AbstractWovenProxyMethodAdapter getWeavingMethodVisitor(int access, String name,
String desc, String signature, String[] exceptions, Method currentMethod,
- String methodStaticFieldName) {
- return new InterfaceUsingWovenProxyMethodAdapter(cv.visitMethod(
- access, name, desc, signature, exceptions), access, name, desc,
- methodStaticFieldName, currentMethod, typeBeingWoven,
- currentMethodDeclaringType, currentMethodDeclaringTypeIsInterface);
- }
-
- @Override
- protected final Type getDeclaringTypeForCurrentMethod() {
- return currentMethodDeclaringType;
+ String methodStaticFieldName, Type currentMethodDeclaringType,
+ boolean currentMethodDeclaringTypeIsInterface) {
+
+ if ((access & ACC_ABSTRACT) != 0) {
+ access &= ~ACC_ABSTRACT;
+ return new WovenProxyAbstractMethodAdapter(cv.visitMethod(
+ access, name, desc, signature, exceptions), access, name, desc,
+ methodStaticFieldName, currentMethod, typeBeingWoven,
+ currentMethodDeclaringType, currentMethodDeclaringTypeIsInterface);
+ } else {
+ return new WovenProxyConcreteMethodAdapter(cv.visitMethod(
+ access, name, desc, signature, exceptions), access, name, desc, exceptions,
+ methodStaticFieldName, currentMethod, typeBeingWoven,
+ currentMethodDeclaringType);
+ }
}
}
Modified: aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/ProxyClassLoader.java
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/ProxyClassLoader.java?rev=1239498&r1=1239497&r2=1239498&view=diff
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/ProxyClassLoader.java (original)
+++ aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/ProxyClassLoader.java Thu Feb 2 09:22:21 2012
@@ -116,7 +116,7 @@ final class ProxyClassLoader extends Cla
return false;
}
- public Class<?> createProxyClass(Class<? extends WovenProxy> superclass, SortedSet<Class<?>> interfaces) throws UnableToProxyException {
+ public Class<?> createProxyClass(Class<?> superclass, SortedSet<Class<?>> interfaces) throws UnableToProxyException {
LinkedHashSet<Class<?>> createSet = new LinkedHashSet<Class<?>>(interfaces);
//Even a null superclass helps with key uniqueness
Modified: aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/WovenProxyAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/WovenProxyAdapter.java?rev=1239498&r1=1239497&r2=1239498&view=diff
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/WovenProxyAdapter.java (original)
+++ aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/weaving/WovenProxyAdapter.java Thu Feb 2 09:22:21 2012
@@ -18,10 +18,8 @@
*/
package org.apache.aries.proxy.impl.weaving;
-import java.io.IOException;
-
-import org.apache.aries.proxy.impl.NLS;
import org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter;
+import org.apache.aries.proxy.impl.common.WovenProxyConcreteMethodAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
@@ -41,22 +39,24 @@ final class WovenProxyAdapter extends Ab
}
/**
- * Get the weaving visitor used to weave instance methods
+ * Get the weaving visitor used to weave instance methods, or just copy abstract ones
*/
protected final MethodVisitor getWeavingMethodVisitor(int access, String name,
String desc, String signature, String[] exceptions, Method currentMethod,
- String methodStaticFieldName) {
+ String methodStaticFieldName, Type currentMethodDeclaringType,
+ boolean currentMethodDeclaringTypeIsInterface) {
MethodVisitor methodVisitorToReturn;
- methodVisitorToReturn = new WovenProxyMethodAdapter(cv.visitMethod(
- access, name, desc, signature, exceptions), access, name, desc,
- exceptions, methodStaticFieldName, currentMethod, typeBeingWoven);
+ if((access & ACC_ABSTRACT) == 0) {
+ methodVisitorToReturn = new WovenProxyConcreteMethodAdapter(cv.visitMethod(
+ access, name, desc, signature, exceptions), access, name, desc,
+ exceptions, methodStaticFieldName, currentMethod, typeBeingWoven,
+ currentMethodDeclaringType);
+ } else {
+ methodVisitorToReturn = cv.visitMethod(access, name, desc, signature, exceptions);
+ }
return methodVisitorToReturn;
}
-
- @Override
- protected final Type getDeclaringTypeForCurrentMethod() {
- return typeBeingWoven;
- }
+
@Override
public FieldVisitor visitField(int access, String name, String arg2,
@@ -75,22 +75,6 @@ final class WovenProxyAdapter extends Ab
return super.visitField(access, name, arg2, arg3, arg4);
}
- @Override
- public void visitEnd() {
- //first we need to override all the methods that were on non-object parents
- for(Class<?> c : nonObjectSupers) {
- try {
- readClass(c, new MethodCopyingClassAdapter(cv,
- c, typeBeingWoven, getKnownMethods(), transformedMethods));
- } catch (IOException e) {
- // This should never happen! <= famous last words (not)
- throw new RuntimeException(NLS.MESSAGES.getMessage("unexpected.error.processing.class", c.getName(), typeBeingWoven.getClassName()), e);
- }
- }
- //Now run the normal visitEnd
- super.visitEnd();
- }
-
public void setSVUIDGenerated(boolean b) {
sVUIDGenerated = b;
}
Modified: aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/AbstractProxyTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/AbstractProxyTest.java?rev=1239498&r1=1239497&r2=1239498&view=diff
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/AbstractProxyTest.java (original)
+++ aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/AbstractProxyTest.java Thu Feb 2 09:22:21 2012
@@ -24,7 +24,6 @@ import static org.junit.Assert.assertNot
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
@@ -83,16 +82,23 @@ public abstract class AbstractProxyTest
}
}
- protected static final Class<?> TEST_CLASS = ProxyTestClassGeneral.class;
-
protected abstract Object getProxyInstance(Class<?> proxyClass);
protected abstract Object getProxyInstance(Class<?> proxyClass, InvocationListener listener);
protected abstract Class<?> getProxyClass(Class<?> clazz);
protected abstract Object setDelegate(Object proxy, Callable<Object> dispatcher);
- /**
+ protected Class<?> getTestClass() {
+ return ProxyTestClassGeneral.class;
+ }
+
+ protected Method getDeclaredMethod(Class<?> testClass, String name,
+ Class<?>... classes) throws Exception {
+ return getProxyClass(testClass).getDeclaredMethod(name, classes);
+ }
+
+/**
* This test uses the ProxySubclassGenerator to generate and load a subclass
- * of the specified TEST_CLASS.
+ * of the specified getTestClass().
*
* Once the subclass is generated we check that it wasn't null. We check
* that the InvocationHandler constructor doesn't return a null object
@@ -105,18 +111,18 @@ public abstract class AbstractProxyTest
@Test
public void testGenerateAndLoadProxy() throws Exception
{
- assertNotNull("Generated proxy subclass was null", getProxyClass(TEST_CLASS));
- assertNotNull("Generated proxy subclass instance was null", getProxyInstance(getProxyClass(TEST_CLASS)));
+ assertNotNull("Generated proxy subclass was null", getProxyClass(getTestClass()));
+ assertNotNull("Generated proxy subclass instance was null", getProxyInstance(getProxyClass(getTestClass())));
}
/**
* Test a basic method invocation on the proxy subclass
*/
@Test
public void testMethodInvocation() throws Exception {
- Method m = getProxyClass(TEST_CLASS).getDeclaredMethod("testMethod", new Class[] { String.class,
- int.class, Object.class });
+ Method m = getDeclaredMethod(getTestClass(), "testMethod", String.class,
+ int.class, Object.class);
String x = "x";
- String returned = (String) m.invoke(getProxyInstance(getProxyClass(TEST_CLASS)), x, 1, new Object());
+ String returned = (String) m.invoke(getProxyInstance(getProxyClass(getTestClass())), x, 1, new Object());
assertEquals("Object returned from invocation was not correct.", x, returned);
}
@@ -126,11 +132,11 @@ public abstract class AbstractProxyTest
@Test
public void testMethodArgs() throws Exception
{
- Method m = getProxyClass(TEST_CLASS).getDeclaredMethod("testArgs", new Class[] { double.class,
- short.class, long.class, char.class, byte.class, boolean.class });
+ Method m = getDeclaredMethod(getTestClass(), "testArgs", double.class,
+ short.class, long.class, char.class, byte.class, boolean.class);
Character xc = Character.valueOf('x');
String x = xc.toString();
- String returned = (String) m.invoke(getProxyInstance(getProxyClass(TEST_CLASS)), Double.MAX_VALUE, Short.MIN_VALUE, Long.MAX_VALUE, xc
+ String returned = (String) m.invoke(getProxyInstance(getProxyClass(getTestClass())), Double.MAX_VALUE, Short.MIN_VALUE, Long.MAX_VALUE, xc
.charValue(), Byte.MIN_VALUE, false);
assertEquals("Object returned from invocation was not correct.", x, returned);
}
@@ -141,11 +147,11 @@ public abstract class AbstractProxyTest
@Test
public void testReturnVoid() throws Exception
{
- Method m = getProxyClass(TEST_CLASS).getDeclaredMethod("testReturnVoid", new Class[] {});
+ Method m = getDeclaredMethod(getTestClass(), "testReturnVoid");
//for these weaving tests we are loading the woven test classes on a different classloader
//to this class so we need to set the method accessible
m.setAccessible(true);
- m.invoke(getProxyInstance(getProxyClass(TEST_CLASS)));
+ m.invoke(getProxyInstance(getProxyClass(getTestClass())));
}
/**
@@ -154,11 +160,11 @@ public abstract class AbstractProxyTest
@Test
public void testReturnInt() throws Exception
{
- Method m = getProxyClass(TEST_CLASS).getDeclaredMethod("testReturnInt", new Class[] {});
+ Method m = getDeclaredMethod(getTestClass(), "testReturnInt");
//for these weaving tests we are loading the woven test classes on a different classloader
//to this class so we need to set the method accessible
m.setAccessible(true);
- Integer returned = (Integer) m.invoke(getProxyInstance(getProxyClass(TEST_CLASS)));
+ Integer returned = (Integer) m.invoke(getProxyInstance(getProxyClass(getTestClass())));
assertEquals("Expected object was not returned from invocation", Integer.valueOf(17), returned);
}
@@ -168,8 +174,8 @@ public abstract class AbstractProxyTest
@Test
public void testReturnInteger() throws Exception
{
- Method m = getProxyClass(TEST_CLASS).getDeclaredMethod("testReturnInteger", new Class[] {});
- Integer returned = (Integer) m.invoke(getProxyInstance(getProxyClass(TEST_CLASS)));
+ Method m = getDeclaredMethod(getTestClass(), "testReturnInteger");
+ Integer returned = (Integer) m.invoke(getProxyInstance(getProxyClass(getTestClass())));
assertEquals("Expected object was not returned from invocation", Integer.valueOf(1), returned);
}
@@ -181,11 +187,11 @@ public abstract class AbstractProxyTest
{
Method m = null;
try {
- m = getProxyClass(TEST_CLASS).getDeclaredMethod("bMethod", new Class[] {});
+ m = getDeclaredMethod(getTestClass(), "bMethod");
} catch (NoSuchMethodException nsme) {
- m = getProxyClass(TEST_CLASS).getSuperclass().getDeclaredMethod("bMethod", new Class[] {});
+ m = getProxyClass(getTestClass()).getSuperclass().getDeclaredMethod("bMethod");
}
- m.invoke(getProxyInstance(getProxyClass(TEST_CLASS)));
+ m.invoke(getProxyInstance(getProxyClass(getTestClass())));
}
/**
@@ -196,14 +202,14 @@ public abstract class AbstractProxyTest
{
Method m = null;
try {
- m = getProxyClass(TEST_CLASS).getDeclaredMethod("bProMethod", new Class[] {});
+ m = getDeclaredMethod(getTestClass(), "bProMethod");
} catch (NoSuchMethodException nsme) {
- m = getProxyClass(TEST_CLASS).getSuperclass().getDeclaredMethod("bProMethod", new Class[] {});
+ m = getProxyClass(getTestClass()).getSuperclass().getDeclaredMethod("bProMethod");
}
//for these weaving tests we are loading the woven test classes on a different classloader
//to this class so we need to set the method accessible
m.setAccessible(true);
- m.invoke(getProxyInstance(getProxyClass(TEST_CLASS)));
+ m.invoke(getProxyInstance(getProxyClass(getTestClass())));
}
/**
@@ -214,14 +220,14 @@ public abstract class AbstractProxyTest
{
Method m = null;
try {
- m = getProxyClass(TEST_CLASS).getDeclaredMethod("bDefMethod", new Class[] {});
+ m = getDeclaredMethod(getTestClass(), "bDefMethod");
} catch (NoSuchMethodException nsme) {
- m = getProxyClass(TEST_CLASS).getSuperclass().getDeclaredMethod("bDefMethod", new Class[] {});
+ m = getProxyClass(getTestClass()).getSuperclass().getDeclaredMethod("bDefMethod", new Class[] {});
}
//for these weaving tests we are loading the woven test classes on a different classloader
//to this class so we need to set the method accessible
m.setAccessible(true);
- m.invoke(getProxyInstance(getProxyClass(TEST_CLASS)));
+ m.invoke(getProxyInstance(getProxyClass(getTestClass())));
}
/**
@@ -232,7 +238,7 @@ public abstract class AbstractProxyTest
{
Class<?> proxy = getProxyClass(ProxyTestClassCovariantOverride.class);
- Method m = proxy.getDeclaredMethod("getCovariant", new Class[] {});
+ Method m = getDeclaredMethod(ProxyTestClassCovariantOverride.class, "getCovariant");
Object returned = m.invoke(getProxyInstance(proxy));
assertTrue("Object was of wrong type: " + returned.getClass().getSimpleName(),
proxy.isInstance(returned));
@@ -247,15 +253,14 @@ public abstract class AbstractProxyTest
Class<?> proxy = getProxyClass(ProxyTestClassGeneric.class);
Object o = getProxyInstance(proxy);
- Method m = proxy.getDeclaredMethod("setSomething",
- new Class[] { String.class });
+ Method m = getDeclaredMethod(ProxyTestClassGeneric.class, "setSomething", String.class);
m.invoke(o, "aString");
- try {
- m = proxy.getDeclaredMethod("getSomething", new Class[] {});
- } catch (NoSuchMethodException nsme) {
- m = proxy.getSuperclass().getDeclaredMethod("getSomething", new Class[] {});
- }
+ if(getClass() == WovenProxyGeneratorTest.class)
+ m = getDeclaredMethod(ProxyTestClassGeneric.class.getSuperclass(), "getSomething");
+ else
+ m = getDeclaredMethod(ProxyTestClassGeneric.class, "getSomething");
+
Object returned = m.invoke(o);
assertTrue("Object was of wrong type", String.class.isInstance(returned));
assertEquals("String had wrong value", "aString", returned);
@@ -267,16 +272,16 @@ public abstract class AbstractProxyTest
@Test
public void testRetrieveClass() throws Exception
{
- Class<?> retrieved = getProxyClass(TEST_CLASS);
+ Class<?> retrieved = getProxyClass(getTestClass());
assertNotNull("The new class was null", retrieved);
- assertEquals("The same class was not returned", retrieved, getProxyClass(TEST_CLASS));
+ assertEquals("The same class was not returned", retrieved, getProxyClass(getTestClass()));
}
@Test
- public void testEquals() throws IllegalAccessException, InstantiationException {
- Object p1 = getProxyInstance(getProxyClass(TEST_CLASS));
- Object p2 = getProxyInstance(getProxyClass(TEST_CLASS));
+ public void testEquals() throws Exception {
+ Object p1 = getProxyInstance(getProxyClass(getTestClass()));
+ Object p2 = getProxyInstance(getProxyClass(getTestClass()));
assertFalse("Should not be equal", p1.equals(p2));
@@ -287,8 +292,8 @@ public abstract class AbstractProxyTest
assertTrue("Should be equal", p1.equals(p2));
- Object p4 = getProxyInstance(getProxyClass(TEST_CLASS));
- Object p5 = getProxyInstance(getProxyClass(TEST_CLASS));
+ Object p4 = getProxyInstance(getProxyClass(getTestClass()));
+ Object p5 = getProxyInstance(getProxyClass(getTestClass()));
p4 = setDelegate(p4, new SingleInstanceDispatcher(p1));
p5 = setDelegate(p5, new SingleInstanceDispatcher(p2));
@@ -296,17 +301,17 @@ public abstract class AbstractProxyTest
assertTrue("Should be equal", p4.equals(p5));
}
- protected abstract Object getP3();
+ protected abstract Object getP3() throws Exception;
@Test
public void testInterception() throws Throwable {
TestListener tl = new TestListener();
- Object obj = getProxyInstance(getProxyClass(TEST_CLASS), tl);
+ Object obj = getProxyInstance(getProxyClass(getTestClass()), tl);
assertCalled(tl, false, false, false);
- Method m = getProxyClass(TEST_CLASS).getDeclaredMethod("testReturnInteger", new Class[] {});
+ Method m = getDeclaredMethod(getTestClass(), "testReturnInteger", new Class[] {});
m.invoke(obj);
assertCalled(tl, true, true, false);
@@ -314,7 +319,7 @@ public abstract class AbstractProxyTest
tl.clear();
assertCalled(tl, false, false, false);
- m = getProxyClass(TEST_CLASS).getDeclaredMethod("testException", new Class[] {});
+ m = getDeclaredMethod(getTestClass(), "testException", new Class[] {});
try {
m.invoke(obj);
fail("Should throw an exception");
@@ -327,7 +332,7 @@ public abstract class AbstractProxyTest
tl.clear();
assertCalled(tl, false, false, false);
- m = getProxyClass(TEST_CLASS).getDeclaredMethod("testInternallyCaughtException", new Class[] {});
+ m = getDeclaredMethod(getTestClass(), "testInternallyCaughtException", new Class[] {});
try {
m.invoke(obj);
} finally {
Modified: aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxySubclassGeneratorTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxySubclassGeneratorTest.java?rev=1239498&r1=1239497&r2=1239498&view=diff
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxySubclassGeneratorTest.java (original)
+++ aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxySubclassGeneratorTest.java Thu Feb 2 09:22:21 2012
@@ -65,7 +65,7 @@ public class ProxySubclassGeneratorTest
public void setUp() throws Exception
{
ih = new FakeInvocationHandler();
- ((FakeInvocationHandler)ih).setDelegate(TEST_CLASS.newInstance());
+ ((FakeInvocationHandler)ih).setDelegate(getTestClass().newInstance());
generatedProxySubclass = getGeneratedSubclass();
o = getProxyInstance(generatedProxySubclass);
}
@@ -78,7 +78,7 @@ public class ProxySubclassGeneratorTest
@Test
public void testExpectedMethods() throws Exception
{
- Class<?> superclass = TEST_CLASS;
+ Class<?> superclass = getTestClass();
do {
Method[] declaredMethods = superclass.getDeclaredMethods();
@@ -89,7 +89,7 @@ public class ProxySubclassGeneratorTest
// private or final don't get added
} else if (!(Modifier.isPublic(i) || Modifier.isPrivate(i) || Modifier.isProtected(i))) {
// the method is default visibility, check the package
- if (m.getDeclaringClass().getPackage().equals(TEST_CLASS.getPackage())) {
+ if (m.getDeclaringClass().getPackage().equals(getTestClass().getPackage())) {
// default vis with same package gets added
listOfDeclaredMethods.add(m);
}
@@ -178,13 +178,13 @@ public class ProxySubclassGeneratorTest
// @Test
// public void testObjectEquality() throws Exception
// {
-// Object delegate = TEST_CLASS.newInstance();
+// Object delegate = getTestClass().newInstance();
// InvocationHandler collaborator = new Collaborator(null, null, AsmInterceptorWrapper.passThrough(delegate));
-// Object o = ProxySubclassGenerator.newProxySubclassInstance(TEST_CLASS, collaborator);
+// Object o = ProxySubclassGenerator.newProxySubclassInstance(getTestClass(), collaborator);
// //Calling equals on the proxy with an arg of the unwrapped object should be true
// assertTrue("The proxy object should be equal to its delegate",o.equals(delegate));
// InvocationHandler collaborator2 = new Collaborator(null, null, AsmInterceptorWrapper.passThrough(delegate));
-// Object o2 = ProxySubclassGenerator.newProxySubclassInstance(TEST_CLASS, collaborator2);
+// Object o2 = ProxySubclassGenerator.newProxySubclassInstance(getTestClass(), collaborator2);
// //The proxy of a delegate should equal another proxy of the same delegate
// assertTrue("The proxy object should be equal to another proxy instance of the same delegate", o2.equals(o));
// }
@@ -239,7 +239,7 @@ public class ProxySubclassGeneratorTest
private Class<?> getGeneratedSubclass() throws Exception
{
- return getProxyClass(TEST_CLASS);
+ return getProxyClass(getTestClass());
}
private class FakeInvocationHandler implements InvocationHandler
@@ -255,7 +255,7 @@ public class ProxySubclassGeneratorTest
{
try {
Object result = (delegate instanceof Callable) ?
- method.invoke(((Callable)delegate).call(), args) :
+ method.invoke(((Callable<?>)delegate).call(), args) :
method.invoke(delegate, args) ;
return result;
} catch (InvocationTargetException ite) {
Added: aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxyTestClassGeneralWithNoDefaultOrProtectedAccess.java
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxyTestClassGeneralWithNoDefaultOrProtectedAccess.java?rev=1239498&view=auto
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxyTestClassGeneralWithNoDefaultOrProtectedAccess.java (added)
+++ aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxyTestClassGeneralWithNoDefaultOrProtectedAccess.java Thu Feb 2 09:22:21 2012
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.blueprint.proxy;
+
+public class ProxyTestClassGeneralWithNoDefaultOrProtectedAccess extends ProxyTestClassSuperWithNoDefaultOrProtectedAccess
+{
+
+ public String testMethod(String x, int y, Object z)
+ {
+ somePrivateMethod();
+ return x;
+ }
+
+ public String testArgs(double a, short b, long c, char d, byte e, boolean f)
+ {
+ return Character.toString(d);
+ }
+
+ public void testReturnVoid()
+ {
+ }
+
+ public int testReturnInt()
+ {
+ return 17;
+ }
+
+ public Integer testReturnInteger()
+ {
+ return Integer.valueOf(1);
+ }
+
+ private void somePrivateMethod()
+ {
+
+ }
+
+ public boolean equals(Object o) {
+ return o == this;
+ }
+
+ public void testException() {
+ throw new RuntimeException();
+ }
+
+ public void testInternallyCaughtException() {
+ try {
+ try {
+ throw new RuntimeException();
+ } catch (RuntimeException re) {
+ // no op
+ }
+ } catch (Exception e) {
+
+ }
+ }
+}
Propchange: aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxyTestClassGeneralWithNoDefaultOrProtectedAccess.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxyTestClassSuperWithNoDefaultOrProtectedAccess.java
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxyTestClassSuperWithNoDefaultOrProtectedAccess.java?rev=1239498&view=auto
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxyTestClassSuperWithNoDefaultOrProtectedAccess.java (added)
+++ aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxyTestClassSuperWithNoDefaultOrProtectedAccess.java Thu Feb 2 09:22:21 2012
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.blueprint.proxy;
+
+public class ProxyTestClassSuperWithNoDefaultOrProtectedAccess
+{
+ static {
+ System.out.println("The time is: " + System.currentTimeMillis());
+ }
+
+ public void bMethod()
+ {
+ aPrivateMethod();
+ }
+
+ public void bProMethod()
+ {
+
+ }
+
+ public void bDefMethod()
+ {
+
+ }
+
+ private void aPrivateMethod()
+ {
+
+ }
+
+ public Object getTargetObject() {
+ return null;
+ }
+
+ private void doTarget() {
+ Object o = getTargetObject();
+ if(this != o)
+ ((ProxyTestClassSuperWithNoDefaultOrProtectedAccess)o).doTarget();
+ }
+
+}
Propchange: aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxyTestClassSuperWithNoDefaultOrProtectedAccess.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenProxyGeneratorTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenProxyGeneratorTest.java?rev=1239498&r1=1239497&r2=1239498&view=diff
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenProxyGeneratorTest.java (original)
+++ aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenProxyGeneratorTest.java Thu Feb 2 09:22:21 2012
@@ -77,7 +77,7 @@ public class WovenProxyGeneratorTest ext
}
/** An array of classes that will be woven - note no UnweavableParents should be in here! */
- private static final List<Class<?>> CLASSES = Arrays.asList(new Class<?>[]{TEST_CLASS, ProxyTestClassSuper.class,
+ private static final List<Class<?>> CLASSES = Arrays.asList(new Class<?>[]{ProxyTestClassGeneral.class, ProxyTestClassSuper.class,
ProxyTestClassFinalMethod.class, ProxyTestClassFinal.class, ProxyTestClassGeneric.class,
ProxyTestClassGenericSuper.class, ProxyTestClassCovariant.class, ProxyTestClassCovariantOverride.class,
ProxyTestClassUnweavableChild.class, ProxyTestClassUnweavableSibling.class, ProxyTestClassInner.class,
@@ -89,11 +89,12 @@ public class WovenProxyGeneratorTest ext
ProxyTestClassStaticInitOfChild.class, ProxyTestClassAbstract.class});
/** An array of classes that are loaded by the WeavingLoader, but not actually woven **/
- private static final List<Class<?>> OTHER_CLASSES = Arrays.asList(new Class<?>[] {ProxyTestClassStaticInitOfChildParent.class, ProxyTestClassChildOfAbstract.class});
+ private static final List<Class<?>> OTHER_CLASSES = Arrays.asList(new Class<?>[] {ProxyTestClassUnweavableSuper.class,
+ ProxyTestClassStaticInitOfChildParent.class, ProxyTestClassChildOfAbstract.class});
private static final Map<String, byte[]> rawClasses = new HashMap<String, byte[]>();
- private static final ClassLoader weavingLoader = new ClassLoader() {
+ protected static final ClassLoader weavingLoader = new ClassLoader() {
public Class<?> loadClass(String className) throws ClassNotFoundException
{
return loadClass(className, false);
@@ -158,7 +159,7 @@ public class WovenProxyGeneratorTest ext
}
/**
- * This test uses the WovenProxyGenerator to generate and load the specified TEST_CLASS.
+ * This test uses the WovenProxyGenerator to generate and load the specified getTestClass().
*
* Once the subclass is generated we check that it wasn't null.
*
@@ -169,7 +170,7 @@ public class WovenProxyGeneratorTest ext
public void testGenerateAndLoadProxy() throws Exception
{
super.testGenerateAndLoadProxy();
- assertTrue("Should be a WovenProxy", WovenProxy.class.isAssignableFrom(getProxyClass(TEST_CLASS)));
+ assertTrue("Should be a WovenProxy", WovenProxy.class.isAssignableFrom(getProxyClass(getTestClass())));
}
/**
@@ -179,10 +180,10 @@ public class WovenProxyGeneratorTest ext
@Test
public void testExpectedMethods() throws Exception
{
- ProxySubclassMethodHashSet<String> originalMethods = getMethods(TEST_CLASS);
+ ProxySubclassMethodHashSet<String> originalMethods = getMethods(getTestClass());
ProxySubclassMethodHashSet<String> generatedMethods = getMethods(weavingLoader.
- loadClass(TEST_CLASS.getName()));
+ loadClass(getTestClass().getName()));
// check that all the methods we have generated were expected
for (String gen : generatedMethods) {
@@ -261,21 +262,31 @@ public class WovenProxyGeneratorTest ext
assertNotNull(getProxyInstance(woven));
TestListener tl = new TestListener();
- ProxyTestClassUnweavableSuper ptcuc = (ProxyTestClassUnweavableSuper) getProxyInstance(woven, tl);
+ Object ptcuc = getProxyInstance(woven, tl);
assertCalled(tl, false, false, false);
- assertEquals("Hi!", ptcuc.doStuff());
+ Method m = ptcuc.getClass().getMethod("doStuff");
+
+ assertEquals("Hi!", m.invoke(ptcuc));
assertCalled(tl, true, true, false);
assertEquals(ProxyTestClassUnweavableGrandParent.class.getMethod("doStuff"),
tl.getLastMethod());
+ tl.clear();
//Because default access works on the package, and we are defined on a different classloader
- //we can only check that the method exists, not that it is callable *sigh*
+ //we have to call setAccessible...
+
+ m = getDeclaredMethod(ProxyTestClassUnweavableChild.class, "doStuff2");
+ m.setAccessible(true);
+ assertEquals("Hello!", m.invoke(ptcuc));
+
+ assertCalled(tl, true, true, false);
- assertNotNull(ProxyTestClassUnweavableSuper.class.getDeclaredMethod("doStuff2"));
+ assertEquals(weavingLoader.loadClass(ProxyTestClassUnweavableSuper.class.getName()).getDeclaredMethod("doStuff2"),
+ tl.getLastMethod());
}
@Test
@@ -341,7 +352,7 @@ public class WovenProxyGeneratorTest ext
@Test(expected=NoSuchFieldException.class)
public void testNonSerializableClassHasNoGeneratedSerialVersionUID() throws Exception {
- Class<?> woven = getProxyClass(TEST_CLASS);
+ Class<?> woven = getProxyClass(getTestClass());
woven.getDeclaredField("serialVersionUID");
}
@@ -464,7 +475,7 @@ public class WovenProxyGeneratorTest ext
}
protected Object getP3() {
- return getProxyInstance(getProxyClass(TEST_CLASS));
+ return getProxyInstance(getProxyClass(getTestClass()));
}
/**
Added: aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenProxyPlusSubclassGeneratorTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenProxyPlusSubclassGeneratorTest.java?rev=1239498&view=auto
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenProxyPlusSubclassGeneratorTest.java (added)
+++ aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenProxyPlusSubclassGeneratorTest.java Thu Feb 2 09:22:21 2012
@@ -0,0 +1,307 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.blueprint.proxy;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import org.apache.aries.proxy.FinalModifierException;
+import org.apache.aries.proxy.InvocationListener;
+import org.apache.aries.proxy.UnableToProxyException;
+import org.apache.aries.proxy.impl.SingleInstanceDispatcher;
+import org.apache.aries.proxy.impl.gen.ProxySubclassGenerator;
+import org.apache.aries.proxy.impl.gen.ProxySubclassMethodHashSet;
+import org.apache.aries.proxy.impl.interfaces.InterfaceProxyGenerator;
+import org.apache.aries.proxy.weaving.WovenProxy;
+import org.apache.aries.unittest.mocks.MethodCall;
+import org.apache.aries.unittest.mocks.Skeleton;
+import org.apache.aries.util.ClassLoaderProxy;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+
+/**
+ * This class uses the {@link ProxySubclassGenerator} to test
+ */
+public class WovenProxyPlusSubclassGeneratorTest extends WovenProxyGeneratorTest
+{
+ private static final Class<?> FINAL_METHOD_CLASS = ProxyTestClassFinalMethod.class;
+ private static final Class<?> FINAL_CLASS = ProxyTestClassFinal.class;
+ private static final Class<?> GENERIC_CLASS = ProxyTestClassGeneric.class;
+ private static final Class<?> COVARIANT_CLASS = ProxyTestClassCovariantOverride.class;
+ private static ProxySubclassMethodHashSet<String> expectedMethods = new ProxySubclassMethodHashSet<String>(
+ 12);
+ private Callable<Object> testCallable = null;
+
+ private static Bundle testBundle;
+
+ @BeforeClass
+ public static void createTestBundle() {
+ testBundle = (Bundle) Skeleton.newMock(new Class<?>[] {Bundle.class, ClassLoaderProxy.class});
+
+ Skeleton.getSkeleton(testBundle).setReturnValue(new MethodCall(
+ ClassLoaderProxy.class, "getClassLoader"), weavingLoader);
+ }
+
+ //Avoid running four weaving tests that don't apply to us
+ public void testUnweavableSuperWithNoNoargsAllTheWay() {}
+ public void testUnweavableSuperWithFinalMethod() {}
+ public void testUnweavableSuperWithDefaultMethodInWrongPackage() {}
+ public void testInnerWithNoParentNoArgs() {}
+
+
+ @Test(expected=NoSuchFieldException.class)
+ public void testGeneratedSVUIDisSynthetic() throws Exception {
+ super.testGeneratedSVUIDisSynthetic();
+ }
+
+
+//
+// /**
+// * Test that the methods found declared on the generated proxy subclass are
+// * the ones that we expect.
+// */
+// @Test
+// public void testExpectedMethods() throws Exception
+// {
+// Class<?> superclass = getTestClass();
+//
+// do {
+// Method[] declaredMethods = superclass.getDeclaredMethods();
+// List<Method> listOfDeclaredMethods = new ArrayList<Method>();
+// for (Method m : declaredMethods) {
+//
+// if(m.getName().equals("clone") || m.getName().equals("finalize"))
+// continue;
+//
+// int i = m.getModifiers();
+// if (Modifier.isPrivate(i) || Modifier.isFinal(i)) {
+// // private or final don't get added
+// } else if (!(Modifier.isPublic(i) || Modifier.isPrivate(i) || Modifier.isProtected(i))) {
+// // the method is default visibility, check the package
+// if (m.getDeclaringClass().getPackage().equals(getTestClass().getPackage())) {
+// // default vis with same package gets added
+// listOfDeclaredMethods.add(m);
+// }
+// } else {
+// listOfDeclaredMethods.add(m);
+// }
+// }
+//
+// declaredMethods = listOfDeclaredMethods.toArray(new Method[] {});
+// ProxySubclassMethodHashSet<String> foundMethods = new ProxySubclassMethodHashSet<String>(
+// declaredMethods.length);
+// foundMethods.addMethodArray(declaredMethods);
+// // as we are using a set we shouldn't get duplicates
+// expectedMethods.addAll(foundMethods);
+// superclass = superclass.getSuperclass();
+// } while (superclass != null);
+//
+//
+//
+// Method[] subclassMethods = getProxyClass(getTestClass()).getDeclaredMethods();
+// List<Method> listOfDeclaredMethods = new ArrayList<Method>();
+// for (Method m : subclassMethods) {
+// if(m.getName().startsWith(WovenProxy.class.getName().replace('.', '_')))
+// continue;
+//
+// listOfDeclaredMethods.add(m);
+// }
+// subclassMethods = listOfDeclaredMethods.toArray(new Method[] {});
+//
+// ProxySubclassMethodHashSet<String> generatedMethods = new ProxySubclassMethodHashSet<String>(
+// subclassMethods.length);
+// generatedMethods.addMethodArray(subclassMethods);
+//
+// // check that all the methods we have generated were expected
+// for (String gen : generatedMethods) {
+// assertTrue("Unexpected method: " + gen, expectedMethods.contains(gen));
+// }
+// // check that all the expected methods were generated
+// for (String exp : expectedMethods) {
+// assertTrue("Method was not generated: " + exp, generatedMethods.contains(exp));
+// }
+// // check the sets were the same
+// assertEquals("Sets were not the same", expectedMethods, generatedMethods);
+//
+// }
+//
+
+
+ /**
+ * Test a covariant override method
+ */
+ @Test
+ public void testCovariant() throws Exception
+ {
+ Class<?> proxy = getProxyClass(ProxyTestClassCovariantOverride.class);
+
+ Method m = getDeclaredMethod(ProxyTestClassCovariantOverride.class, "getCovariant", new Class[] {});
+ Object returned = m.invoke(getProxyInstance(proxy));
+ assertTrue("Object was of wrong type: " + returned.getClass().getSimpleName(),
+ proxy.getSuperclass().isInstance(returned));
+ }
+
+ /**
+ * Test a method marked final
+ */
+ @Test
+ public void testFinalMethod() throws Exception
+ {
+ try {
+ InterfaceProxyGenerator.getProxyInstance(null, FINAL_METHOD_CLASS, Collections.EMPTY_SET,
+ new Callable<Object>() {
+ public Object call() throws Exception {
+ return null;
+ }} , null).getClass();
+ } catch (RuntimeException re) {
+ FinalModifierException e = (FinalModifierException) re.getCause();
+ assertFalse("Should have found final method not final class", e.isFinalClass());
+ }
+ }
+
+ /**
+ * Test a class marked final
+ */
+ @Test
+ public void testFinalClass() throws Exception
+ {
+ try {
+ InterfaceProxyGenerator.getProxyInstance(null, FINAL_CLASS, Collections.EMPTY_SET,
+ new Callable() {
+ public Object call() throws Exception {
+ return null;
+ }} , null).getClass();
+ } catch (FinalModifierException e) {
+ assertTrue("Should have found final class", e.isFinalClass());
+ }
+ }
+
+
+
+ @Test
+ public void testAddingInterfacesToClass() throws Exception {
+ Object proxy = InterfaceProxyGenerator.getProxyInstance(testBundle, super.getProxyClass(getTestClass()), Arrays.asList(Map.class, Iterable.class), new Callable<Object>() {
+
+ int calls = 0;
+ private Map<String, String> map = new HashMap<String, String>();
+
+ {
+ map.put("key", "value");
+ }
+
+ public Object call() throws Exception {
+ switch(++calls) {
+ case 1 :
+ return WovenProxyPlusSubclassGeneratorTest.super.getProxyInstance(weavingLoader.loadClass(getTestClass().getName()));
+ case 2 :
+ return map;
+ default :
+ return map.values();
+ }
+ }
+
+ }, null);
+
+ Method m = weavingLoader.loadClass(ProxyTestClassGeneral.class.getName()).getDeclaredMethod("testReturnInt");
+ m.setAccessible(true);
+ assertEquals(17, m.invoke(proxy));
+ assertEquals("value", ((Map<String, String>)proxy).put("key", "value2"));
+ Iterator<?> it = ((Iterable<?>)proxy).iterator();
+ assertEquals("value2", it.next());
+ assertFalse(it.hasNext());
+
+ }
+
+
+
+
+ @Override
+ protected Method getDeclaredMethod(Class<?> testClass, String name,
+ Class<?>... classes) {
+
+ Class<?> proxy = getProxyClass(testClass);
+
+ while(proxy != null) {
+ try {
+ return proxy.getDeclaredMethod(name, classes);
+ } catch (Exception e) {
+ proxy = proxy.getSuperclass();
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected Object getProxyInstance(Class<?> proxyClass) {
+
+ if(proxyClass == ProxyTestClassChildOfAbstract.class) {
+ return super.getProxyInstance(super.getProxyClass(proxyClass));
+ }
+
+ try {
+ Constructor<?> con = proxyClass.getDeclaredConstructor(Callable.class, InvocationListener.class);
+ con.setAccessible(true);
+ return con.newInstance((testCallable == null) ? new SingleInstanceDispatcher(super.getProxyInstance(proxyClass.getSuperclass())) : testCallable, null);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ @Override
+ protected Class<?> getProxyClass(Class<?> clazz) {
+ try {
+ return InterfaceProxyGenerator.getProxyInstance(testBundle, super.getProxyClass(clazz), Collections.EMPTY_SET,
+ new Callable<Object>() {
+ public Object call() throws Exception {
+ return null;
+ }} , null).getClass();
+ } catch (UnableToProxyException e) {
+ return null;
+ } catch (RuntimeException re) {
+ if(re.getCause() instanceof UnableToProxyException)
+ return null;
+ else
+ throw re;
+ }
+ }
+
+ @Override
+ protected Object getProxyInstance(Class<?> proxyClass,
+ InvocationListener listener) {
+ WovenProxy proxy = (WovenProxy) getProxyInstance(proxyClass);
+ proxy = proxy.org_apache_aries_proxy_weaving_WovenProxy_createNewProxyInstance(
+ new SingleInstanceDispatcher(proxy), listener);
+ return proxy;
+ }
+}
\ No newline at end of file
Propchange: aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenProxyPlusSubclassGeneratorTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain