Author: mprudhom
Date: Fri Sep 29 19:00:40 2006
New Revision: 451517

URL: http://svn.apache.org/viewvc?view=rev&rev=451517
Log:
Prevent reentrant calls to transform() in order to prevent attempts to enhance 
OpenJPA libraries (for cases where OpenJPA falls under the control of the 
enhancing class loader).

Modified:
    
incubator/openjpa/trunk/openjpa-kernel-5/src/main/java/org/apache/openjpa/enhance/PCClassFileTransformer.java

Modified: 
incubator/openjpa/trunk/openjpa-kernel-5/src/main/java/org/apache/openjpa/enhance/PCClassFileTransformer.java
URL: 
http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel-5/src/main/java/org/apache/openjpa/enhance/PCClassFileTransformer.java?view=diff&rev=451517&r1=451516&r2=451517
==============================================================================
--- 
incubator/openjpa/trunk/openjpa-kernel-5/src/main/java/org/apache/openjpa/enhance/PCClassFileTransformer.java
 (original)
+++ 
incubator/openjpa/trunk/openjpa-kernel-5/src/main/java/org/apache/openjpa/enhance/PCClassFileTransformer.java
 Fri Sep 29 19:00:40 2006
@@ -26,6 +26,7 @@
 import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.lib.util.Options;
 import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.util.ClassResolver;
 import org.apache.openjpa.util.GeneralException;
 import serp.bytecode.Project;
 import serp.bytecode.lowlevel.ConstantPoolTable;
@@ -43,9 +44,10 @@
     private static final Localizer _loc = Localizer.forPackage
         (PCClassFileTransformer.class);
 
+    private boolean _transforming = false;
     private final MetaDataRepository _repos;
     private final PCEnhancer.Flags _flags;
-    private final ClassLoader _loader;
+    private final ClassLoader _tmpLoader;
     private final Log _log;
     private final Set _names;
 
@@ -86,14 +88,23 @@
      * if none are configured
      */
     public PCClassFileTransformer(MetaDataRepository repos,
-        PCEnhancer.Flags flags, ClassLoader loader, boolean devscan) {
+        PCEnhancer.Flags flags, ClassLoader tmpLoader, boolean devscan) {
         _repos = repos;
-        _log =
-            repos.getConfiguration().getLog(OpenJPAConfiguration.LOG_ENHANCE);
+        _tmpLoader = tmpLoader;
+
+        // ensure that we are using the temporary class loader for
+        // all class resolution
+        repos.getConfiguration().setClassResolver(new ClassResolver() {
+            public ClassLoader getClassLoader(Class context, ClassLoader env) {
+                return _tmpLoader;
+            }
+        });
+
+        _log = repos.getConfiguration().
+            getLog(OpenJPAConfiguration.LOG_ENHANCE);
         _flags = flags;
-        _loader = loader;
 
-        _names = repos.getPersistentTypeNames(devscan, loader);
+        _names = repos.getPersistentTypeNames(devscan, tmpLoader);
         if (_names == null && _log.isInfoEnabled())
             _log.info(_loc.get("runtime-enhance-pcclasses"));
     }
@@ -101,9 +112,18 @@
     public byte[] transform(ClassLoader loader, String className,
         Class redef, ProtectionDomain domain, byte[] bytes)
         throws IllegalClassFormatException {
-        if (loader == _loader)
+
+        if (loader == _tmpLoader)
             return null;
 
+        // prevent re-entrant calls, which can occur if the enhanceing
+        // loader is used to also load OpenJPA libraries; this is to prevent 
+        // recursive enhancement attempts for internal openjpa libraries
+        if (_transforming)
+            return null;
+
+        _transforming = true;
+
         try {
             Boolean enhance = needsEnhance(className, redef, bytes);
             if (enhance != null && _log.isTraceEnabled())
@@ -114,7 +134,7 @@
 
             PCEnhancer enhancer = new PCEnhancer(_repos.getConfiguration(),
                 new Project().loadClass(new ByteArrayInputStream(bytes),
-                    _loader), _repos);
+                    _tmpLoader), _repos);
             enhancer.setAddDefaultConstructor(_flags.addDefaultConstructor);
             enhancer.setEnforcePropertyRestrictions
                 (_flags.enforcePropertyRestrictions);
@@ -129,6 +149,8 @@
             if (t instanceof IllegalClassFormatException)
                 throw (IllegalClassFormatException) t;
             throw new GeneralException(t);
+        } finally {
+            _transforming = false;
         }
     }
 
@@ -157,7 +179,8 @@
             return Boolean.FALSE;
 
         try {
-            Class c = Class.forName(clsName.replace('/', '.'), false, _loader);
+            Class c = Class.forName(clsName.replace('/', '.'), false,
+                _tmpLoader);
             if (_repos.getMetaData(c, null, false) != null)
                 return Boolean.TRUE;
             return null;


Reply via email to