diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java index 61d348143..86fd7ddb0 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java @@ -1204,7 +1204,7 @@ public class MappingRepository extends MetaDataRepository { try { Class c = JavaTypes.classForName(name, val, AccessController.doPrivileged( - J2DoPrivHelper.getClassLoaderAction(FieldStrategy.class))); + J2DoPrivHelper.getClassLoaderAction(FieldStrategy.class)),false); Object o = AccessController.doPrivileged( J2DoPrivHelper.newInstanceAction(c)); Configurations.configureInstance(o, getConfiguration(), props); @@ -1231,7 +1231,7 @@ public class MappingRepository extends MetaDataRepository { try { Class c = JavaTypes.classForName(name, val, AccessController.doPrivileged( - J2DoPrivHelper.getClassLoaderAction(ValueHandler.class))); + J2DoPrivHelper.getClassLoaderAction(ValueHandler.class)),false); if (ValueHandler.class.isAssignableFrom(c)) { ValueHandler vh = (ValueHandler) AccessController.doPrivileged( J2DoPrivHelper.newInstanceAction(c)); diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/JavaTypes.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/JavaTypes.java index 83eb8d961..ce0fb49b7 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/JavaTypes.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/JavaTypes.java @@ -205,12 +205,38 @@ public class JavaTypes { context.getFieldMetaData().getDeclaringType(), context, loader); } + /** + * Try to load a class using the provided loader. Optionally tries the + * configuration's ClassResolver if the supplied loader cannot find the class. + * + * @param name Name of the class to load. + * @param context + * @param loader ClassLoader to use. If null, the configuration's ClassResolver will be used. + * @param mustExist Whether the supplied loader must be able to load the class. If true no attempt to use a + * different classloader will be made. If false the ClassResolver from the configuration will be used. + */ + public static Class classForName(String name, ValueMetaData context, + ClassLoader loader, boolean mustExist) { + return classForName(name, + context.getFieldMetaData().getDefiningMetaData(), + context.getFieldMetaData().getDeclaringType(), context, loader, mustExist); + } + + /** + * OJ-758: Delegates to the final classForName. This is needed + * to maintain the existing code path prior to OJ-758. + */ + private static Class classForName(String name, ClassMetaData meta, + Class dec, ValueMetaData vmd, ClassLoader loader) { + return classForName(name, meta, dec, vmd, loader, true); + } + /** * Check the given name against the same set of standard packages used * when parsing metadata. */ private static Class classForName(String name, ClassMetaData meta, Class dec, ValueMetaData vmd, - ClassLoader loader) { + ClassLoader loader, boolean mustExist) { // special case for PersistenceCapable and Object if ("PersistenceCapable".equals(name) || "javax.jdo.PersistenceCapable".equals(name)) // backwards compatibility @@ -232,9 +258,21 @@ public class JavaTypes { pkg = Strings.getPackageName(vmd.getDeclaredType()); cls = CFMetaDataParser.classForName(name, pkg, runtime, loader); } + + //OJ-758 start: If the class is still null, as a last/final attempt to + //load the class, check with the ClassResolver to get a loader + //and use it to attempt to load the class. + if (cls == null && !mustExist){ + loader = rep.getConfiguration().getClassResolverInstance(). + getClassLoader(dec, meta.getEnvClassLoader()); + cls = CFMetaDataParser.classForName(name, pkg, runtime, loader); + } + //OJ-758 end + if (cls == null) throw new MetaDataException(_loc.get("bad-class", name, (vmd == null) ? (Object) meta : (Object) vmd)); + return cls; }