diff --git a/openjpa-kernel/pom.xml b/openjpa-kernel/pom.xml
index 5b508438d..c2d7dd9be 100644
--- a/openjpa-kernel/pom.xml
+++ b/openjpa-kernel/pom.xml
@@ -74,9 +74,9 @@
provided
- asm
- asm
- 3.2
+ org.apache.xbean
+ xbean-asm4-shaded
+ 3.14
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/AsmAdaptor.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/AsmAdaptor.java
index ba60affdb..949c4afed 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/AsmAdaptor.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/AsmAdaptor.java
@@ -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);
+ private static byte[] toJava7ByteArray(BCClass bc, byte[] classBytes) throws IOException {
+ ByteArrayInputStream bais = new ByteArrayInputStream(classBytes);
+ 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 cw = new BCClassWriter(ClassWriter.COMPUTE_FRAMES, bc.getClassLoader());
+ ClassReader cr = new ClassReader(bis);
+ cr.accept(cw, 0);
+ return cw.toByteArray();
+ }
- // ClassWriter.getCommonSuperClass uses TCCL
- Thread.currentThread().setContextClassLoader(bc.getClassLoader());
- classReaderAccept.invoke(cr, cw, 0);
+ private static class BCClassWriter extends ClassWriter {
+ private final ClassLoader _loader;
- return (byte[]) classWritertoByteArray.invoke(cw);
- } catch (Exception e) {
- throw new IOException(e);
- } finally {
- Thread.currentThread().setContextClassLoader(cl);
+ 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('.', '/');
}
}
}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCClassFileTransformer.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCClassFileTransformer.java
index c4f0e67ce..f8b2459f4 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCClassFileTransformer.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCClassFileTransformer.java
@@ -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
*/
diff --git a/pom.xml b/pom.xml
index 1e16fe559..93e5f5b27 100644
--- a/pom.xml
+++ b/pom.xml
@@ -43,6 +43,8 @@
2.3.0-SNAPSHOT
+ 1.6
+
${project.version}
DefaultLevel=INFO
UTF-8
@@ -81,10 +83,10 @@
1.6.1
- 1.6
- 1.6
- 1.6
- 1.6
+ ${java.version}
+ ${java.version}
+ ${java.version}
+ ${java.version}