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) {