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