Abe White wrote: > >>> I see. Here's a proposal: in the MetaDataRepository's implementation >>> of the RegisterClassListener interface, the repository only registers >>> the given class if either the user has not specified a persistent >>> types list (which we allow and in which case we attempt to lazily >>> discover persistent types), or if the class name appears in the >>> list. That way if you follow JPA guidelines and specify your >>> persistent class list properly, subclasses left off the list won't >>> even get registered with the metadata repository. >>> >> That sounds about right. I tried something similar using >> MetaDataFactory.getPersistentTypeNames(), but this method requires a >> classloader to be passed to it. Using the thread's classloader >> didn't seem >> right (and didn't work anyway). Is there another way to find this >> list? > > Good point. I guess we can't exclude the classes in the register > class listener method itself, but we can do so when we > processRegisteredClasses(). This method is only ever called from > places where we have the proper classloader (the same one we pass to > getPersistentTypeNames()). > This works for me :) Here's a patch for 0.9.6 source. I've gone for the simplest solution, but it might be improved by looping over pcNames instead of _registered (?).
http://www.nabble.com/file/7398/openjpa-diff openjpa-diff Index: MetaDataRepository.java =================================================================== --- MetaDataRepository.java (.../tags/0.9.6/openjpa-kernel/src/main/java/org/apache/openjpa/meta) (revision 3) +++ MetaDataRepository.java (.../branches/0.9.6-ninthavenue/openjpa-kernel/src/main/java/org/apache/openjpa/meta) (working copy) @@ -302,7 +302,7 @@ return null; // check cache - processRegisteredClasses(); + processRegisteredClasses(envLoader); List classList = (List) _aliases.get(alias); // multiple classes may have been defined with the same alias: we @@ -928,7 +928,7 @@ } // check cache - processRegisteredClasses(); + processRegisteredClasses(envLoader); Class cls = (Class) _oids.get(oid.getClass()); if (cls != null) return getMetaData(cls, envLoader, mustExist); @@ -944,7 +944,7 @@ // if still not match, register any classes that look similar to the // oid class and check again resolveIdentityClass(oid); - if (processRegisteredClasses().length > 0) { + if (processRegisteredClasses(envLoader).length > 0) { cls = (Class) _oids.get(oid.getClass()); if (cls != null) return getMetaData(cls, envLoader, mustExist); @@ -1262,7 +1262,7 @@ * Parses the metadata for all registered classes. */ private void loadRegisteredClassMetaData(ClassLoader envLoader) { - Class[] reg = processRegisteredClasses(); + Class[] reg = processRegisteredClasses(envLoader); for (int i = 0; i < reg.length; i++) { try { getMetaData(reg[i], envLoader, false); @@ -1276,7 +1276,7 @@ /** * Updates our datastructures with the latest registered classes. */ - Class[] processRegisteredClasses() { + Class[] processRegisteredClasses(ClassLoader envLoader) { if (_registered.isEmpty()) return EMPTY_CLASSES; @@ -1289,9 +1289,18 @@ } Collection failed = null; + Collection pcNames = getPersistentTypeNames(false, envLoader); for (int i = 0; i < reg.length; i++) { try { - processRegisteredClass(reg[i]); + + /* + * Only process classes known to this MetaDataRepository, + * since _registered contains all classes loaded by + * PCRegistry. + */ + if (pcNames.contains(reg[i].getName())) { + processRegisteredClass(reg[i]); + } } catch (Throwable t) { if (!_conf.getRetryClassRegistration()) throw new MetaDataException(_loc.get("error-registered", Index: ClassMetaData.java =================================================================== --- ClassMetaData.java (.../tags/0.9.6/openjpa-kernel/src/main/java/org/apache/openjpa/meta) (revision 4) +++ ClassMetaData.java (.../branches/0.9.6-ninthavenue/openjpa-kernel/src/main/java/org/apache/openjpa/meta) (working copy) @@ -309,7 +309,7 @@ if (_owner != null) return _repos.EMPTY_CLASSES; - _repos.processRegisteredClasses(); + _repos.processRegisteredClasses(getEnvClassLoader()); if (_subs == null) { Collection subs = _repos.getPCSubclasses(_type); _subs = (Class[]) subs.toArray(new Class[subs.size()]); -- View this message in context: http://www.nabble.com/Shared-classloader-and-subclasses-tf3431312.html#a9655900 Sent from the open-jpa-dev mailing list archive at Nabble.com.