You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sk...@apache.org on 2008/06/13 10:18:50 UTC
svn commit: r667414 - in /myfaces/orchestra/trunk/sandbox: pom.xml
src/main/java/org/apache/myfaces/orchestra/dynaForm/metadata/impl/ejb/AsmHelper.java
src/main/java/org/apache/myfaces/orchestra/dynaForm/metadata/impl/ejb/ClassHelperFactory.java
Author: skitching
Date: Fri Jun 13 01:18:50 2008
New Revision: 667414
URL: http://svn.apache.org/viewvc?rev=667414&view=rev
Log:
Support ASM 3.x releases as well as ASM 2.x
Modified:
myfaces/orchestra/trunk/sandbox/pom.xml
myfaces/orchestra/trunk/sandbox/src/main/java/org/apache/myfaces/orchestra/dynaForm/metadata/impl/ejb/AsmHelper.java
myfaces/orchestra/trunk/sandbox/src/main/java/org/apache/myfaces/orchestra/dynaForm/metadata/impl/ejb/ClassHelperFactory.java
Modified: myfaces/orchestra/trunk/sandbox/pom.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/sandbox/pom.xml?rev=667414&r1=667413&r2=667414&view=diff
==============================================================================
--- myfaces/orchestra/trunk/sandbox/pom.xml (original)
+++ myfaces/orchestra/trunk/sandbox/pom.xml Fri Jun 13 01:18:50 2008
@@ -64,9 +64,10 @@
<dependency>
<!--
- WARNING: asm versions are horribly non-compatible between major releases.
- - We might need to use maven-shade-plugin to instead import a private version
- - of asm into this project, so that orchestra can be used within projects
- - that use other versions of asm.
+ - The AsmHelper class currently uses reflection to support both ASM 2.x and 3.x.
+ - An alternative would be to use maven-shade-plugin to instead import a private
+ - version of asm into this project, so that this lib does not conflict with the
+ - needs of apps that use it.
-->
<groupId>asm</groupId>
<artifactId>asm</artifactId>
Modified: myfaces/orchestra/trunk/sandbox/src/main/java/org/apache/myfaces/orchestra/dynaForm/metadata/impl/ejb/AsmHelper.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/sandbox/src/main/java/org/apache/myfaces/orchestra/dynaForm/metadata/impl/ejb/AsmHelper.java?rev=667414&r1=667413&r2=667414&view=diff
==============================================================================
--- myfaces/orchestra/trunk/sandbox/src/main/java/org/apache/myfaces/orchestra/dynaForm/metadata/impl/ejb/AsmHelper.java (original)
+++ myfaces/orchestra/trunk/sandbox/src/main/java/org/apache/myfaces/orchestra/dynaForm/metadata/impl/ejb/AsmHelper.java Fri Jun 13 01:18:50 2008
@@ -21,6 +21,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
@@ -48,6 +49,72 @@
private static final Field[] FIELDS_TYPE = new Field[0];
private static final Method[] METHODS_TYPE = new Method[0];
+ // These are initialised during class loading, and are effectively final.
+ // They cannot actually be final because the initialisation is done in
+ // a static method for tidiness, and the compiler isn't smart enough to
+ // figure out that this is equivalent to initialising them in the static
+ // block itself.
+ private static Method ACCEPT_METHOD;
+ private static Object ACCEPT_ARG;
+
+ static
+ {
+ initAsm();
+ }
+
+ /**
+ * Alas, the ASM project broke binary compatibility between the 2.x and 3.x
+ * release for no good reason. In order to be compatible with either version
+ * of ASM, we need to use reflection to invoke ClassReader.accept.
+ * <p>
+ * In 2.x releases, we must call ClassReader.accept(classVisitor, boolean).
+ * In 3.x releases we must call ClassReader.accept(classVisitor, int).
+ * <p>
+ * In both cases, the second arg is a constant value (though of different type)
+ * so we set up ACCEPT_ARG to the appropriate value too.
+ * <p>
+ * The code below does not support ASM 1.x.
+ */
+ private static void initAsm() throws ExceptionInInitializerError
+ {
+ // signature for ASM 3.x
+ Class[] argsForm2 = new Class[] { ClassVisitor.class, Integer.TYPE };
+ try
+ {
+ Method m = ClassReader.class.getMethod("accept", argsForm2);
+ // ok, we are running with asm 3.0.x, 3.1.x or compatible
+ ACCEPT_METHOD = m;
+
+ // flags=SKIP_DEBUG|SKIP_CODE|SKIP_FRAMES
+ ACCEPT_ARG = Integer.valueOf(1 | 2 | 4);
+ return;
+ }
+ catch (NoSuchMethodException e)
+ {
+ // ok
+ }
+
+ // signature for ASM 1.x and 2.x
+ Class[] argsForm1 = new Class[] { ClassVisitor.class, Boolean.TYPE };
+ try
+ {
+ Method m = ClassReader.class.getMethod("accept", argsForm1);
+ // ok, we are running with asm 1.x or 2.x
+ ACCEPT_METHOD = m;
+
+ // skipDebug=true
+ ACCEPT_ARG = Boolean.TRUE;
+ return;
+ }
+ catch (NoSuchMethodException e)
+ {
+ // ok
+ }
+
+ throw new ExceptionInInitializerError(
+ "AsmHelper cannot find compatible ClassReader.access method");
+ }
+
private void applyVisitorToClass(Class clazz, ClassVisitor visitor)
{
// Note: Simply using the constructor ClassReader(clazz.getName())
@@ -55,17 +122,33 @@
// from.
String className = clazz.getName().replace('.', '/') + ".class";
ClassReader cr = null;
- InputStream is = null;
+ InputStream is = null;
try
{
is = this.getClass().getClassLoader().getResourceAsStream(className);
cr = new ClassReader(is);
- cr.accept(visitor, true);
+
+ // Invoke ClassReader.accept(ClassVisitor, ?).
+ // See method initAsm for further details...
+ Object[] args = new Object[2];
+ args[0] = visitor;
+ args[1] = ACCEPT_ARG;
+ ACCEPT_METHOD.invoke(cr, args);
}
catch (IOException e)
{
throw new OrchestraException("Unable to read class " + className, e);
}
+ catch(InvocationTargetException e)
+ {
+ // should never happen
+ throw new OrchestraException("Unable to read class " + className, e);
+ }
+ catch(IllegalAccessException e)
+ {
+ // should never happen
+ throw new OrchestraException("Unable to read class " + className, e);
+ }
finally
{
if (is != null)
@@ -74,7 +157,7 @@
{
is.close();
}
- catch(IOException e2)
+ catch (IOException e2)
{
// Not likely to occur, and nothing can be done about it.
log.error("Unable to close input stream", e2);
@@ -138,7 +221,7 @@
// of any of the classes that those Method objects are on, unless weak
// references are used. For now, keep things simple..
Method[] methods = clazz.getDeclaredMethods();
- for(Method m: methods)
+ for (Method m : methods)
{
String thisMethodDesc = org.objectweb.asm.Type.getMethodDescriptor(m);
if (thisMethodDesc.equals(descriptor))
Modified: myfaces/orchestra/trunk/sandbox/src/main/java/org/apache/myfaces/orchestra/dynaForm/metadata/impl/ejb/ClassHelperFactory.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/sandbox/src/main/java/org/apache/myfaces/orchestra/dynaForm/metadata/impl/ejb/ClassHelperFactory.java?rev=667414&r1=667413&r2=667414&view=diff
==============================================================================
--- myfaces/orchestra/trunk/sandbox/src/main/java/org/apache/myfaces/orchestra/dynaForm/metadata/impl/ejb/ClassHelperFactory.java (original)
+++ myfaces/orchestra/trunk/sandbox/src/main/java/org/apache/myfaces/orchestra/dynaForm/metadata/impl/ejb/ClassHelperFactory.java Fri Jun 13 01:18:50 2008
@@ -58,6 +58,10 @@
{
// not available
}
+ catch(ExceptionInInitializerError e)
+ {
+ // not available
+ }
}
// last exit