You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2014/05/06 16:59:52 UTC
svn commit: r1592767 - in
/felix/trunk/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation:
ClassLoaderAwareClassWriter.java Manipulator.java
NoClassLoaderClassWriter.java
Author: clement
Date: Tue May 6 14:59:52 2014
New Revision: 1592767
URL: http://svn.apache.org/r1592767
Log:
To correctly compute the frames, we need a way to load classes - so a classloader. The manipulator now takes a classloader as parameter used for this purpose. (FELIX-4509).
Added:
felix/trunk/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassLoaderAwareClassWriter.java
- copied, changed from r1592381, felix/trunk/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/NoClassLoaderClassWriter.java
Removed:
felix/trunk/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/NoClassLoaderClassWriter.java
Modified:
felix/trunk/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
Copied: felix/trunk/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassLoaderAwareClassWriter.java (from r1592381, felix/trunk/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/NoClassLoaderClassWriter.java)
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassLoaderAwareClassWriter.java?p2=felix/trunk/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassLoaderAwareClassWriter.java&p1=felix/trunk/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/NoClassLoaderClassWriter.java&r1=1592381&r2=1592767&rev=1592767&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/NoClassLoaderClassWriter.java (original)
+++ felix/trunk/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassLoaderAwareClassWriter.java Tue May 6 14:59:52 2014
@@ -19,29 +19,30 @@
package org.apache.felix.ipojo.manipulation;
-import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
/**
- * An extension of {@link org.objectweb.asm.ClassWriter} that doe snot trigger class loading to compute the common super
- * class. It generally returns Object.
+ * An extension of {@link org.objectweb.asm.ClassWriter} that uses a specific classloader to load classes.
*/
-public class NoClassLoaderClassWriter extends ClassWriter {
+public class ClassLoaderAwareClassWriter extends ClassWriter {
private static final String OBJECT_INTERNAL_NAME = "java/lang/Object";
+ private final String className;
+ private final String superClass;
+ private final ClassLoader classLoader;
- public NoClassLoaderClassWriter(ClassReader reader, int flags) {
- super(reader, flags);
- }
-
- public NoClassLoaderClassWriter(int flags) {
+ public ClassLoaderAwareClassWriter(int flags, String className, String superClass, ClassLoader loader) {
super(flags);
+ this.className = className;
+ this.superClass = superClass;
+ this.classLoader = loader;
}
/**
* Implements the common super class lookup to be a bit more permissive. First we check is type1 == type2,
* because in this case, the lookup is done. Then, if one of the class is Object,
* returns object. If both checks failed, it returns Object.
+ *
* @param type1 the first class
* @param type2 the second class
* @return the common super class
@@ -58,8 +59,34 @@ public class NoClassLoaderClassWriter ex
return OBJECT_INTERNAL_NAME;
}
- // We shunt the rest of the process.
- return OBJECT_INTERNAL_NAME;
+ // If either of these class names are the current class then we can short
+ // circuit to the superclass (which we already know)
+ if (type1.equals(className.replace(".", "/")) && superClass != null) {
+ return getCommonSuperClass(superClass.replace(".", "/"), type2);
+ } else if (type2.equals(className.replace(".", "/")) && superClass != null)
+ return getCommonSuperClass(type1, superClass.replace(".", "/"));
+
+ Class<?> c, d;
+ try {
+ c = classLoader.loadClass(type1.replace('/', '.'));
+ d = classLoader.loadClass(type2.replace('/', '.'));
+ } catch (Exception e) {
+ throw new RuntimeException(e.toString());
+ }
+ if (c.isAssignableFrom(d)) {
+ return type1;
+ }
+ if (d.isAssignableFrom(c)) {
+ return type2;
+ }
+ if (c.isInterface() || d.isInterface()) {
+ return "java/lang/Object";
+ } else {
+ do {
+ c = c.getSuperclass();
+ } while (!c.isAssignableFrom(d));
+ return c.getName().replace('.', '/');
+ }
}
}
Modified: felix/trunk/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java?rev=1592767&r1=1592766&r2=1592767&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java (original)
+++ felix/trunk/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java Tue May 6 14:59:52 2014
@@ -38,6 +38,10 @@ import java.util.*;
*/
public class Manipulator {
/**
+ * A classloader used to compute frames.
+ */
+ private final ClassLoader m_classLoader;
+ /**
* Store the visited fields : [name of the field, type of the field].
*/
private Map<String, String> m_fields;
@@ -77,6 +81,11 @@ public class Manipulator {
*/
private String m_className;
+ public Manipulator(ClassLoader loader) {
+ // No classloader set, use current one.
+ m_classLoader = loader;
+ }
+
/**
* Checks the given bytecode, determines if the class was already manipulated, and collect the metadata about the
* class.
@@ -119,7 +128,8 @@ public class Manipulator {
if (!m_alreadyManipulated) {
InputStream is2 = new ByteArrayInputStream(origin);
ClassReader reader = new ClassReader(is2);
- ClassWriter writer = new NoClassLoaderClassWriter(ClassWriter.COMPUTE_FRAMES);
+ ClassWriter writer = new ClassLoaderAwareClassWriter(ClassWriter.COMPUTE_FRAMES, m_className, m_superClass,
+ m_classLoader);
ClassManipulator process = new ClassManipulator(new CheckClassAdapter(writer, false), this);
if (m_version >= Opcodes.V1_6) {
reader.accept(process, ClassReader.EXPAND_FRAMES);
@@ -262,7 +272,7 @@ public class Manipulator {
InputStream is1 = new ByteArrayInputStream(bytecode);
ClassReader cr = new ClassReader(is1);
- ClassWriter cw = new NoClassLoaderClassWriter(ClassWriter.COMPUTE_FRAMES);
+ ClassWriter cw = new ClassLoaderAwareClassWriter(ClassWriter.COMPUTE_FRAMES, inner, null, m_classLoader);
InnerClassAdapter adapter = new InnerClassAdapter(inner, cw, m_className, this);
if (m_version >= Opcodes.V1_6) {
cr.accept(adapter, ClassReader.EXPAND_FRAMES);