You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by st...@apache.org on 2013/10/10 00:10:49 UTC

svn commit: r1530808 - in /openjpa/branches/2.3.x: openjpa-kernel/pom.xml openjpa-kernel/src/main/java/org/apache/openjpa/enhance/AsmAdaptor.java openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCClassFileTransformer.java pom.xml

Author: struberg
Date: Wed Oct  9 22:10:48 2013
New Revision: 1530808

URL: http://svn.apache.org/r1530808
Log:
OPENJPA-2283 use xbean-asm4-shaded ASM version as the dynamic handling doesn't work out

This makes sure we always have a guaranteed ASM version 4 regardless what ASM a
user might add to the project. This also rolls back the dynamic ASM handling of
OPENJPA-2171.

Modified:
    openjpa/branches/2.3.x/openjpa-kernel/pom.xml
    openjpa/branches/2.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/AsmAdaptor.java
    openjpa/branches/2.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCClassFileTransformer.java
    openjpa/branches/2.3.x/pom.xml

Modified: openjpa/branches/2.3.x/openjpa-kernel/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/branches/2.3.x/openjpa-kernel/pom.xml?rev=1530808&r1=1530807&r2=1530808&view=diff
==============================================================================
--- openjpa/branches/2.3.x/openjpa-kernel/pom.xml (original)
+++ openjpa/branches/2.3.x/openjpa-kernel/pom.xml Wed Oct  9 22:10:48 2013
@@ -74,9 +74,9 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>asm</groupId>
-            <artifactId>asm</artifactId>
-            <version>3.2</version>
+            <groupId>org.apache.xbean</groupId>
+            <artifactId>xbean-asm4-shaded</artifactId>
+            <version>3.14</version>
         </dependency>
     </dependencies>
 

Modified: openjpa/branches/2.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/AsmAdaptor.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/AsmAdaptor.java?rev=1530808&r1=1530807&r2=1530808&view=diff
==============================================================================
--- openjpa/branches/2.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/AsmAdaptor.java (original)
+++ openjpa/branches/2.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/AsmAdaptor.java Wed Oct  9 22:10:48 2013
@@ -18,84 +18,26 @@
  */
 package org.apache.openjpa.enhance;
 
-import serp.bytecode.BCClass;
-
 import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.OutputStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
 import java.net.URLDecoder;
 
-import org.apache.openjpa.lib.util.Localizer;
+import org.apache.xbean.asm4.ClassReader;
+import org.apache.xbean.asm4.ClassWriter;
+import serp.bytecode.BCClass;
+
 
 /**
  * Use ASM to add required StackMapTable attribute to the byte code generated by
  * Serp.
- *
- * This class contains a small hack to pickup different known shades of ASM
- * to prevent classpath clashes.
- * We first try to use standard ASM. If this is not available we try to pickup
- * the shaded xbean-asm version used in OpenEJB, Geronimo or WAS.
- * At last we try to use the shaded version from Spring.
  */
 public final class AsmAdaptor {
-    private static final Localizer _loc = Localizer.forPackage(AsmAdaptor.class);
-    
     private static final int Java7_MajorVersion = 51;
 
-    private static Class<?> cwClass;
-    private static Class<?> crClass;
-    private static int COMPUTE_FRAMES;
-    private static Method classReaderAccept;
-    private static Method classWritertoByteArray;
-    private static Constructor<?> classWriterConstructor;
-    private static Constructor<?> classReaderConstructor;
-
-    static {
-        // try the "real" asm first, then the others
-        tryClass("org.objectweb.asm.");
-        tryClass("org.apache.xbean.asm4.");
-        tryClass("org.apache.xbean.asm.");
-        tryClass("org.springframework.asm.");
-
-        // get needed stuff
-        try {
-            COMPUTE_FRAMES = cwClass.getField("COMPUTE_FRAMES").getInt(null);
-            if (cwClass.getInterfaces().length > 0) { // ASM 3
-                classReaderAccept = crClass.getMethod("accept", cwClass.getInterfaces()[0], int.class);
-            } else { // ASM 4
-                classReaderAccept = crClass.getMethod("accept", cwClass.getSuperclass(), int.class);
-            }
-            classReaderConstructor = crClass.getConstructor(InputStream.class);
-            classWriterConstructor = cwClass.getConstructor(int.class);
-            classWritertoByteArray = cwClass.getMethod("toByteArray");
-        } catch (Exception e) {
-            throw new IllegalStateException(_loc.get("static-asm-exception").getMessage(), e);
-        }
-    }
-
-    private static void tryClass(final String s) {
-        if (cwClass == null) {
-            try {
-                cwClass = AsmAdaptor.class.getClassLoader().loadClass(s + "ClassWriter");
-            } catch (Throwable t) {
-                //ignore
-            }
-        }
-        if (crClass == null) {
-            try {
-                crClass = AsmAdaptor.class.getClassLoader().loadClass(s + "ClassReader");
-            } catch (Throwable t) {
-                //ignore
-            }
-        }
-    }
-
     @SuppressWarnings("deprecation")
     public static void write(BCClass bc) throws IOException {
         if (bc.getMajorVersion() < Java7_MajorVersion) {
@@ -143,24 +85,47 @@ public final class AsmAdaptor {
         out.write(java7Bytes);
     }
 
-    private static byte[] toJava7ByteArray(final BCClass bc, final byte[] classBytes) throws IOException {
-        final ByteArrayInputStream bais = new ByteArrayInputStream(classBytes);
-        final BufferedInputStream bis = new BufferedInputStream(bais);
-
-        final ClassLoader cl = Thread.currentThread().getContextClassLoader();
-        try {
-            final Object cw = classWriterConstructor.newInstance(COMPUTE_FRAMES);
-            final Object cr = classReaderConstructor.newInstance(bis);
-
-            // ClassWriter.getCommonSuperClass uses TCCL
-            Thread.currentThread().setContextClassLoader(bc.getClassLoader());
-            classReaderAccept.invoke(cr, cw, 0);
-
-            return (byte[]) classWritertoByteArray.invoke(cw);
-        } catch (Exception e) {
-            throw new IOException(e);
-        } finally {
-            Thread.currentThread().setContextClassLoader(cl);
+    private static byte[] toJava7ByteArray(BCClass bc, byte[] classBytes) throws IOException {
+        ByteArrayInputStream bais = new ByteArrayInputStream(classBytes);
+        BufferedInputStream bis = new BufferedInputStream(bais);
+
+        ClassWriter cw = new BCClassWriter(ClassWriter.COMPUTE_FRAMES, bc.getClassLoader());
+        ClassReader cr = new ClassReader(bis);
+        cr.accept(cw, 0);
+        return cw.toByteArray();
+    }
+
+    private static class BCClassWriter extends ClassWriter {
+        private final ClassLoader _loader;
+
+        BCClassWriter(int flags, ClassLoader loader) {
+            super(flags);
+            _loader = loader;
+        }
+
+        @Override
+        protected String getCommonSuperClass(String type1, String type2) {
+            Class<?> class1;
+            Class<?> class2;
+            try {
+                class1 = _loader.loadClass(type1.replace('/', '.'));
+                class2 = _loader.loadClass(type2.replace('/', '.'));
+            } catch (ClassNotFoundException ex) {
+                throw new RuntimeException(ex);
+            }
+            if (class1.isAssignableFrom(class2)) {
+                return type1;
+            }
+            if (class2.isAssignableFrom(class1)) {
+                return type2;
+            }
+            if (class1.isInterface() || class2.isInterface()) {
+                return "java/lang/Object";
+            }
+            do {
+                class1 = class1.getSuperclass();
+            } while (!class1.isAssignableFrom(class2));
+            return class1.getName().replace('.', '/');
         }
     }
 }

Modified: openjpa/branches/2.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCClassFileTransformer.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCClassFileTransformer.java?rev=1530808&r1=1530807&r2=1530808&view=diff
==============================================================================
--- openjpa/branches/2.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCClassFileTransformer.java (original)
+++ openjpa/branches/2.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCClassFileTransformer.java Wed Oct  9 22:10:48 2013
@@ -87,7 +87,7 @@ public class PCClassFileTransformer
      *
      * @param repos metadata repository to use internally
      * @param flags enhancer configuration
-     * @param loader temporary class loader for loading intermediate classes
+     * @param tmpLoader temporary class loader for loading intermediate classes
      * @param devscan whether to scan the dev classpath for persistent types
      * if none are configured
      */

Modified: openjpa/branches/2.3.x/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/branches/2.3.x/pom.xml?rev=1530808&r1=1530807&r2=1530808&view=diff
==============================================================================
--- openjpa/branches/2.3.x/pom.xml (original)
+++ openjpa/branches/2.3.x/pom.xml Wed Oct  9 22:10:48 2013
@@ -43,6 +43,8 @@
     <version>2.3.0-SNAPSHOT</version>
 
     <properties>
+        <java.version>1.6</java.version>
+
         <openjpa.version>${project.version}</openjpa.version>
         <openjpa.Log>DefaultLevel=INFO</openjpa.Log>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -81,10 +83,10 @@
         <!-- other common versions -->
         <slf4jVersion>1.6.1</slf4jVersion>
         <!-- Compile Java source/target class level -->
-        <compile.class.source>1.6</compile.class.source>
-        <compile.class.target>1.6</compile.class.target>
-        <compile.testclass.source>1.6</compile.testclass.source>
-        <compile.testclass.target>1.6</compile.testclass.target>
+        <compile.class.source>${java.version}</compile.class.source>
+        <compile.class.target>${java.version}</compile.class.target>
+        <compile.testclass.source>${java.version}</compile.testclass.source>
+        <compile.testclass.target>${java.version}</compile.testclass.target>
     </properties>
 
     <licenses>