mirror of https://github.com/apache/openjpa.git
OPENJPA-2283 : Merge changes from 2.3.x to trunk.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1532523 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3b94663fe2
commit
e719ad01e9
|
@ -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>
|
||||
|
||||
|
|
|
@ -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('.', '/');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
11
pom.xml
11
pom.xml
|
@ -43,6 +43,9 @@
|
|||
<version>2.3.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<java.class.version>1.6</java.class.version>
|
||||
<java.testclass.version>1.6</java.testclass.version>
|
||||
|
||||
<openjpa.version>${project.version}</openjpa.version>
|
||||
<openjpa.Log>DefaultLevel=INFO</openjpa.Log>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
@ -81,10 +84,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.class.version}</compile.class.source>
|
||||
<compile.class.target>${java.class.version}</compile.class.target>
|
||||
<compile.testclass.source>${java.testclass.version}</compile.testclass.source>
|
||||
<compile.testclass.target>${java.testclass.version}</compile.testclass.target>
|
||||
</properties>
|
||||
|
||||
<licenses>
|
||||
|
|
Loading…
Reference in New Issue