FELIX-4046 Inner class manipulation fails with expanded frames
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1478497 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/InnerClassManipulator.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/InnerClassManipulator.java
index 07727a2..93dbac2 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/InnerClassManipulator.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/InnerClassManipulator.java
@@ -26,6 +26,7 @@
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
/**
* Manipulates inner class allowing outer class access. The manipulated class
@@ -60,13 +61,17 @@
* @return manipulated class
* @throws IOException the class cannot be read correctly
*/
- public byte[] manipulate(byte[] in) throws IOException {
+ public byte[] manipulate(byte[] in, int version) throws IOException {
InputStream is1 = new ByteArrayInputStream(in);
ClassReader cr = new ClassReader(is1);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
InnerClassAdapter adapter = new InnerClassAdapter(cw, m_outer, m_fields);
- cr.accept(adapter, ClassReader.SKIP_FRAMES);
+ if (version >= Opcodes.V1_6) {
+ cr.accept(adapter, ClassReader.EXPAND_FRAMES);
+ } else {
+ cr.accept(adapter, 0);
+ }
is1.close();
return cw.toByteArray();
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
index 24f1552..9a15d55 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
@@ -64,6 +64,11 @@
private List<String> m_inners;
/**
+ * Java byte code version.
+ */
+ private int m_version;
+
+ /**
* Manipulate the given byte array.
* @param origin : original class.
* @return the manipulated class, if the class is already manipulated, the original class.
@@ -89,6 +94,8 @@
m_inners = ck.getInnerClasses();
+ m_version = ck.getClassVersion();
+
ClassWriter finalWriter = null;
if (!ck.isalreadyManipulated()) {
// Manipulation ->
@@ -160,4 +167,7 @@
return m_inners;
}
+ public int getClassVersion() {
+ return m_version;
+ }
}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/ManipulationEngine.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/ManipulationEngine.java
index 0613787..e71c0a7 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/ManipulationEngine.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/ManipulationEngine.java
@@ -133,9 +133,12 @@
}
// Manipulate inner class
+ // Notice that (for performance reason) re-use the class version information
+ // discovered in the main class instead of re-parsing the inner class to find
+ // its own class version
try {
InnerClassManipulator innerManipulator = new InnerClassManipulator(outerClassInternalName, manipulator.getFields().keySet());
- byte[] manipulated = innerManipulator.manipulate(innerClassBytecode);
+ byte[] manipulated = innerManipulator.manipulate(innerClassBytecode, manipulator.getClassVersion());
// Propagate manipulated resource
result.visitManipulatedResource(resourcePath, manipulated);
} catch (IOException e) {