Index: vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/implementation/TypeVariableImpl.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/implementation/TypeVariableImpl.java (revision 590105) +++ vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/implementation/TypeVariableImpl.java (working copy) @@ -53,7 +53,7 @@ while (klass != null) { // TODO: it should be revised to provide the correct classloader for resolving. - AuxiliaryLoader.ersatzLoader.resolve(klass); + AuxiliaryLoader.resolve(klass); klass = klass.getDeclaringClass(); } @@ -116,7 +116,8 @@ bounds[0] = (Type) pType; } else if (pTypeParameter.classBound instanceof InterimClassType) { try { - bounds[0] = (Type) AuxiliaryLoader.ersatzLoader.findClass(((InterimClassType)pTypeParameter.classBound).classTypeName.substring(1).replace('/', '.')); + bounds[0] = (Type) + AuxiliaryLoader.findClass(((InterimClassType)pTypeParameter.classBound).classTypeName.substring(1).replace('/', '.'), startPoint); } catch (ClassNotFoundException e) { throw new TypeNotPresentException(((InterimClassType)pTypeParameter.classBound).classTypeName.substring(1).replace('/', '.'), e); } catch (ExceptionInInitializerError e) { @@ -145,7 +146,7 @@ bounds[i] = (Type) pType; } else if (pTypeParameter.interfaceBounds[i - 1] instanceof InterimClassType) { try { - bounds[i] = (Type) AuxiliaryLoader.ersatzLoader.findClass(((InterimClassType)pTypeParameter.interfaceBounds[i - 1]).classTypeName.substring(1).replace('/', '.')); + bounds[i] = (Type) AuxiliaryLoader.findClass(((InterimClassType)pTypeParameter.interfaceBounds[i - 1]).classTypeName.substring(1).replace('/', '.'), startPoint); } catch (ClassNotFoundException e) { throw new TypeNotPresentException(((InterimClassType)pTypeParameter.interfaceBounds[i - 1]).classTypeName.substring(1).replace('/', '.'), e); } catch (ExceptionInInitializerError e) { @@ -178,4 +179,4 @@ public String toString() { return name; } -} \ No newline at end of file +} Index: vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/parser/Parser.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/parser/Parser.java (revision 590105) +++ vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/parser/Parser.java (working copy) @@ -107,7 +107,7 @@ genericExceptionTypes[i] = (Type) pType; } else if (throwns[i] instanceof InterimClassType) { try { - genericExceptionTypes[i] = (Type) AuxiliaryLoader.ersatzLoader.findClass(((InterimClassType)throwns[i]).classTypeName.substring(1).replace('/', '.')); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one? + genericExceptionTypes[i] = (Type) AuxiliaryLoader.findClass(((InterimClassType)throwns[i]).classTypeName.substring(1).replace('/', '.'), startPoint); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one? } catch (ClassNotFoundException e) { throw new TypeNotPresentException(((InterimClassType)throwns[i]).classTypeName.substring(1).replace('/', '.'), e); } catch (ExceptionInInitializerError e) { @@ -256,12 +256,12 @@ genericParameterTypes[i] = (Type) pType; } else if (methodParameters[i] instanceof InterimClassType) { try { - genericParameterTypes[i] = (Type) AuxiliaryLoader.ersatzLoader + genericParameterTypes[i] = (Type) AuxiliaryLoader .findClass(((InterimClassType) methodParameters[i]).classTypeName .substring( (((InterimClassType) methodParameters[i]).classTypeName .charAt(0) == 'L' ? 1 - : 0)).replace('/', '.')); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one? + : 0)).replace('/', '.'), startPoint); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one? } catch (ClassNotFoundException e) { throw new TypeNotPresentException( ((InterimClassType) methodParameters[i]).classTypeName @@ -581,12 +581,12 @@ genericExceptionTypes[i] = (Type) pType; } else if (throwns[i] instanceof InterimClassType) { try { - genericExceptionTypes[i] = (Type) AuxiliaryLoader.ersatzLoader + genericExceptionTypes[i] = (Type) AuxiliaryLoader .findClass(((InterimClassType) throwns[i]).classTypeName .substring( (((InterimClassType) throwns[i]).classTypeName .charAt(0) == 'L' ? 1 - : 0)).replace('/', '.')); // XXX: + : 0)).replace('/', '.'), startPoint); // XXX: // should // we // propagate @@ -712,12 +712,12 @@ genericParameterTypes[i] = (Type) pType; } else if (methodParameters[i] instanceof InterimClassType) { try { - genericParameterTypes[i] = (Type) AuxiliaryLoader.ersatzLoader + genericParameterTypes[i] = (Type) AuxiliaryLoader .findClass(((InterimClassType) methodParameters[i]).classTypeName .substring( (((InterimClassType) methodParameters[i]).classTypeName .charAt(0) == 'L' ? 1 : 0)) - .replace('/', '.')); // XXX: should we + .replace('/', '.'), startPoint); // XXX: should we // propagate the // class loader of // initial user's @@ -924,7 +924,7 @@ //FIXME: any potential issue to change findClass->loadClass genericInterfaces[i] = (Type) c.getClass().getClassLoader().loadClass(AuxiliaryFinder.transform(((InterimClassType)superInterfaces[i]).classTypeName.substring(1).replace('/', '.'))); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one? } else { - genericInterfaces[i] = (Type) AuxiliaryLoader.ersatzLoader.findClass(AuxiliaryFinder.transform(((InterimClassType)superInterfaces[i]).classTypeName.substring(1).replace('/', '.'))); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one? + genericInterfaces[i] = (Type) AuxiliaryLoader.findClass(AuxiliaryFinder.transform(((InterimClassType)superInterfaces[i]).classTypeName.substring(1).replace('/', '.')), startPoint); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one? } } catch (ClassNotFoundException e) { throw new TypeNotPresentException(((InterimClassType)superInterfaces[i]).classTypeName.substring(1).replace('/', '.'), e); Index: vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/support/AuxiliaryFinder.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/support/AuxiliaryFinder.java (revision 590105) +++ vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/support/AuxiliaryFinder.java (working copy) @@ -85,7 +85,7 @@ } else if (ownerType != null) { // BUG int i = 0, j = 1; i = j/i; } - klass = AuxiliaryLoader.ersatzLoader.findClass(binaryClassName); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one? + klass = AuxiliaryLoader.findClass(binaryClassName, startPoint); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one? return klass; //it may be null //FRAGMENT FINISH ^ //############################################################################################################################################ @@ -387,7 +387,7 @@ * To use in findGenericClassDeclarationForParameterizedType method. */ private static Class verifyParameterizedType(InterimParameterizedType fldType, Object startPoint) throws ClassNotFoundException { - Class klass = AuxiliaryLoader.ersatzLoader.findClass(fldType.rawType.classTypeName.substring(1).replace('/', '.')/*fldType.rawType.classTypeName*/); + Class klass = AuxiliaryLoader.findClass(fldType.rawType.classTypeName.substring(1).replace('/', '.')/*fldType.rawType.classTypeName*/, startPoint); if (fldType.currentClauseName != null && fldType.currentClauseName.length() > 0) { return klass; // has been verified } @@ -405,7 +405,7 @@ if (fldType.ownerType == null) { try{ - if (AuxiliaryLoader.ersatzLoader.findClass(rtnm.substring(1).replace('/', '.')) != null){ + if (AuxiliaryLoader.findClass(rtnm.substring(1).replace('/', '.'), startPoint) != null){ // telescoping a final unit: InterimClassType newCT = new InterimClassType(); newCT.classTypeName = rtnm; @@ -418,7 +418,7 @@ } else { if (!rtnm.equals((fldType.ownerType instanceof InterimParameterizedType ? ((InterimParameterizedType)fldType.ownerType).rawType.classTypeName : ((InterimClassType)fldType.ownerType).classTypeName))) { try{ - if (AuxiliaryLoader.ersatzLoader.findClass(rtnm.substring(1).replace('/', '.')) != null){ + if (AuxiliaryLoader.findClass(rtnm.substring(1).replace('/', '.'), startPoint) != null){ // telescoping an intermediate unit: newPT = new InterimParameterizedType(); /* ### */ newPT.signature = fldType.signature.substring(0, fldType.signature.lastIndexOf("$"+snm)); //XXX: ??? Index: vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/support/AuxiliaryCreator.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/support/AuxiliaryCreator.java (revision 590105) +++ vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/support/AuxiliaryCreator.java (working copy) @@ -83,7 +83,7 @@ } else if (nextLayer instanceof InterimClassType) { Type cType; try { - cType = (Type) AuxiliaryLoader.ersatzLoader.findClass(((InterimClassType)nextLayer).classTypeName.substring((((InterimClassType)nextLayer).classTypeName.charAt(0)=='L'? 1 : 0)).replace('/', '.')); + cType = (Type) AuxiliaryLoader.findClass(((InterimClassType)nextLayer).classTypeName.substring((((InterimClassType)nextLayer).classTypeName.charAt(0)=='L'? 1 : 0)).replace('/', '.'), startPoint); } catch(ClassNotFoundException e) { throw new TypeNotPresentException(((InterimClassType)nextLayer).classTypeName.substring((((InterimClassType)nextLayer).classTypeName.charAt(0)=='L'? 1 : 0)).replace('/', '.'), e); } @@ -127,7 +127,7 @@ } return (Type) pType; } else { //ClassType - return AuxiliaryLoader.ersatzLoader.findClass(((InterimClassType) nextppType).classTypeName.substring(1).replace('/', '.')); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one? + return AuxiliaryLoader.findClass(((InterimClassType) nextppType).classTypeName.substring(1).replace('/', '.'), startPoint); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one? } } @@ -189,11 +189,13 @@ } else if (pType instanceof InterimGenericArrayType) { res = AuxiliaryCreator.createGenericArrayType((InterimGenericArrayType)pType, startPoint); } else { // ClassType - res = (Type) AuxiliaryLoader.ersatzLoader.findClass(((InterimClassType)pType).classTypeName.substring(1).replace('/', '.')); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one? + String className = ((InterimClassType) + pType).classTypeName.substring(1).replace('/', '.'); + res = (Type) AuxiliaryLoader.findClass(className, startPoint); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one? } return res; } - + /** * This method creates an array of Type objects representing the actual type arguments to this type. * Index: vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/support/AuxiliaryChecker.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/support/AuxiliaryChecker.java (revision 590105) +++ vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/support/AuxiliaryChecker.java (working copy) @@ -49,9 +49,8 @@ InterimClassType currentClass = currentBit.rawType; Class klazz = null; - AuxiliaryLoader loader = AuxiliaryLoader.ersatzLoader; try{ - klazz = loader.findClass(AuxiliaryFinder.transform(currentClass.classTypeName.substring(1).replace('/', '.'))); + klazz = AuxiliaryLoader.findClass(AuxiliaryFinder.transform(currentClass.classTypeName.substring(1).replace('/', '.')), startPoint); } catch (Throwable e) { } @@ -84,7 +83,7 @@ klazz = null; try{ //klazz = ClassLoader.findClass(currentClass.classTypeName); - klazz = loader.findClass(AuxiliaryFinder.transform(currentClass.classTypeName.substring(1).replace('/', '.'))); + klazz = AuxiliaryLoader.findClass(AuxiliaryFinder.transform(currentClass.classTypeName.substring(1).replace('/', '.')), startPoint); } catch (Throwable e) { } @@ -103,4 +102,4 @@ } } } -} \ No newline at end of file +} Index: vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/support/AuxiliaryLoader.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/support/AuxiliaryLoader.java (revision 590105) +++ vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/lang/reflect/support/AuxiliaryLoader.java (working copy) @@ -17,6 +17,10 @@ package org.apache.harmony.lang.reflect.support; import java.security.AccessController; +import java.security.PrivilegedAction; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; /** * @author Serguei S. Zapreyev @@ -29,11 +33,10 @@ * (This should be considered as a temporary decision. A correct approach * in using loader facilities should be implemented later.) */ -public final class AuxiliaryLoader extends ClassLoader { - public static final AuxiliaryLoader ersatzLoader = new AuxiliaryLoader(); +public final class AuxiliaryLoader { - public Class findClass(final String classTypeName) - throws ClassNotFoundException { + public static Class findClass(final String classTypeName, + Object startPoint) throws ClassNotFoundException { if (classTypeName.equals("byte")) { return byte.class; } else if (classTypeName.equals("char")) { @@ -53,57 +56,23 @@ } else if (classTypeName.equals("void")) { return void.class; } - ClassLoader cl = this.getClass().getClassLoader(); - - if (cl == null) { - cl = ClassLoader.getSystemClassLoader(); - } - - try { - return cl.loadClass(classTypeName); - } catch (Throwable _) {} // ignore - + final ClassLoader loader = getClassLoader(startPoint); Class c = (Class) AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new PrivilegedAction() { public Object run() { - - // based on an empiric knowledge - ClassLoader cl = ClassLoader.getSystemClassLoader(); - try { - java.lang.reflect.Method[] ms = - cl.getClass().getDeclaredMethods(); - int i = 0; - - for (; i < ms.length; i++) { - if (!ms[i].getName().equals("loadClass")) { - continue; - } - - if (ms[i].getParameterTypes().length != 2) { - continue; - } - - if (!ms[i].getParameterTypes()[0].getName().equals( - "java.lang.String")) { - continue; - } - - if (!ms[i].getParameterTypes()[1].getName().equals( - "boolean")) { - continue; - } - break; - } - ms[i].setAccessible(true); - return (Object) ms[i].invoke((Object) cl, new Object[] { + Method loadClassMethod = findLoadClassMethod( + loader.getClass()); + loadClassMethod.setAccessible(true); + return (Object) loadClassMethod.invoke((Object) loader, + new Object[] { (Object) AuxiliaryFinder.transform(classTypeName), new Boolean(false) }); - } catch (java.lang.IllegalAccessException e) { + } catch (IllegalAccessException e) { System.err.println("Error: AuxiliaryLoader.findClass(" + classTypeName + "): " + e.toString()); e.printStackTrace(); - } catch (java.lang.reflect.InvocationTargetException e) { + } catch (InvocationTargetException e) { System.err.println("Error: AuxiliaryLoader.findClass(" + classTypeName + "): " + e.getTargetException()); e.getTargetException().printStackTrace(); @@ -122,24 +91,73 @@ return c; } - public void resolve(final Class c) { + /** + * @param startPoint an instance of the Class, Method, Constructor or Field + * type to start the search of a type variable declaration place. + */ + private static ClassLoader getClassLoader(Object startPoint) { + ClassLoader res = null; + + if (startPoint instanceof Class) { + res = ((Class) startPoint).getClassLoader(); + } else if (startPoint instanceof Member) { + res = ((Member) startPoint).getDeclaringClass().getClassLoader(); + } else { + res = startPoint.getClass().getClassLoader(); + } + + if (res == null) { + res = ClassLoader.getSystemClassLoader(); + } + return res; + } + + /** + * Looks for loadClass(String name, boolean resolve) Method in the + * specified 'loader' class (of the type ClassLoader) or its super class. + */ + private static Method findLoadClassMethod(Class loaderClass) { + Method res = null; + Method[] ms = loaderClass.getDeclaredMethods(); + + for (int i = 0; i < ms.length; i++) { + if (!ms[i].getName().equals("loadClass")) { + continue; + } + + if (ms[i].getParameterTypes().length != 2) { + continue; + } + + if (!ms[i].getParameterTypes()[0].getName().equals( + "java.lang.String")) { + continue; + } + + if (!ms[i].getParameterTypes()[1].getName().equals( + "boolean")) { + continue; + } + res = ms[i]; + break; + } + + // no null check is required - at leas this methopd will be found in + // java.lang.ClassLoader + return res != null ? res : + findLoadClassMethod(loaderClass.getSuperclass()); + } + + public static void resolve(final Class c) { AccessController.doPrivileged(new java.security.PrivilegedAction() { public Object run() { - ClassLoader cl = AuxiliaryLoader.this.getClass().getClassLoader(); - if (cl == null) { - cl = ClassLoader.getSystemClassLoader(); - } + ClassLoader loader = getClassLoader(c); + try { - java.lang.reflect.Method[] ms = cl.getClass() - .getDeclaredMethods(); - int i = 0; - for (; i < ms.length; i++) { - if (ms[i].getName().equals("loadClass")) { - break; - } - } - ms[i].setAccessible(true); - ms[i].invoke((Object) cl, new Object[] { + Method loadClassMethod = findLoadClassMethod( + loader.getClass()); + loadClassMethod.setAccessible(true); + loadClassMethod.invoke((Object) loader, new Object[] { (Object) c.getCanonicalName(), (Object) true }); } catch (java.lang.IllegalAccessException _) { } catch (java.lang.reflect.InvocationTargetException _) {