openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "roger.keays" <roger.ke...@ninthavenue.com.au>
Subject Re: Shared classloader and subclasses
Date Sun, 25 Mar 2007 00:19:51 GMT


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.


Mime
View raw message