Start working on FELIX-4253 Add methods from inner classes in the metadata collected during the manipulation
Inner classes are added to the manipulation part of the metadata.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1527700 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
index 3dbebb7..0fcba5f 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
@@ -19,10 +19,8 @@
package org.apache.felix.ipojo.manipulation;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
+import java.util.*;
+
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
@@ -72,7 +70,7 @@
/**
* List of visited inner class owned by the implementation class.
*/
- private List<String> m_inners = new ArrayList<String>();
+ private Map<String, List<MethodDescriptor>> m_inners = new LinkedHashMap<String, List<MethodDescriptor>>();
/**
* <code>true</code> if the class supports annotations.
@@ -150,7 +148,7 @@
if (m_className.equals(outerName) || outerName == null) { // Anonymous classes does not have an outer class.
// Do not include inner static class
if (! ((access & ACC_STATIC) == ACC_STATIC)) {
- m_inners.add(name);
+ m_inners.put(name, new ArrayList<MethodDescriptor>());
}
}
}
@@ -237,17 +235,14 @@
return null;
}
- private boolean isGeneratedConstructor(String name, String desc) {
+ public static boolean isGeneratedConstructor(String name, String desc) {
return ("<init>".equals(name) && isFirstArgumentInstanceManager(desc));
}
- private boolean isFirstArgumentInstanceManager(String desc) {
+ public static boolean isFirstArgumentInstanceManager(String desc) {
Type[] types = Type.getArgumentTypes(desc);
- if (types != null && (types.length >= 1)) {
- return Type.getType("Lorg/apache/felix/ipojo/InstanceManager;")
- .equals(types[0]);
- }
- return false;
+ return types != null && (types.length >= 1)
+ && Type.getType("Lorg/apache/felix/ipojo/InstanceManager;").equals(types[0]);
}
private boolean isGeneratedMethod(String name, String desc) {
@@ -315,10 +310,18 @@
return m_superClass;
}
- public List<String> getInnerClasses() {
+ public Collection<String> getInnerClasses() {
+ return m_inners.keySet();
+ }
+
+ public Map<String, List<MethodDescriptor>> getInnerClassesAndMethods() {
return m_inners;
}
+ public String getClassName() {
+ return m_className;
+ }
+
/**
* This class collects annotations in a method.
* This class creates an {@link AnnotationDescriptor}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/InnerClassAdapter.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/InnerClassAdapter.java
index facb172..c50effa 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/InnerClassAdapter.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/InnerClassAdapter.java
@@ -33,6 +33,8 @@
*/
public class InnerClassAdapter extends ClassAdapter implements Opcodes {
+ private final Manipulator m_manipulator;
+ private final String m_name;
/**
* Implementation class name.
*/
@@ -45,14 +47,19 @@
/**
* Creates the inner class adapter.
*
+ * @param name the inner class name
* @param arg0 parent class visitor
* @param outerClass outer class (implementation class)
* @param fields fields of the implementation class
+ * @param manipulator the manipulator having manipulated the outer class.
*/
- public InnerClassAdapter(ClassVisitor arg0, String outerClass, Set<String> fields) {
+ public InnerClassAdapter(String name, ClassVisitor arg0, String outerClass, Set<String> fields,
+ Manipulator manipulator) {
super(arg0);
+ m_name = name;
m_outer = outerClass;
m_fields = fields;
+ m_manipulator = manipulator;
}
/**
@@ -68,8 +75,9 @@
* @see org.objectweb.asm.ClassAdapter#visitMethod(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
*/
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
- // For non static and non constructor method, generate the wrapping method and move the method content within
- // the manipulated method.
+
+ final MethodDescriptor md = new MethodDescriptor(name, desc, (access & ACC_STATIC) == ACC_STATIC);
+ m_manipulator.addMethodToInnerClass(m_name, md);
// Do nothing on static methods, should not happen in non-static inner classes.
if ((access & ACC_STATIC) == ACC_STATIC) {
@@ -82,7 +90,12 @@
}
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
- return new MethodCodeAdapter(mv, m_outer, access, name, desc, m_fields);
+ if (! m_manipulator.isAlreadyManipulated()) {
+ // Do not re-manipulate.
+ return new MethodCodeAdapter(mv, m_outer, access, name, desc, m_fields);
+ } else {
+ return mv;
+ }
}
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 93dbac2..0e09b6e 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
@@ -36,6 +36,12 @@
public class InnerClassManipulator {
/**
+ * The manipulator having manipulated the component class.
+ */
+ private final Manipulator m_manipulator;
+ private final String m_innerClassName;
+
+ /**
* Outer class class name.
*/
private String m_outer;
@@ -47,12 +53,14 @@
/**
* Creates an inner class manipulator.
- * @param classname : class name
- * @param fields : fields
+ * @param outerclassName : class name
+ * @param manipulator : fields
*/
- public InnerClassManipulator(String classname, Set<String> fields) {
- m_outer = classname;
- m_fields = fields;
+ public InnerClassManipulator(String innerClassName, String outerclassName, Manipulator manipulator) {
+ m_outer = outerclassName;
+ m_innerClassName = innerClassName;
+ m_fields = manipulator.getFields().keySet();
+ m_manipulator = manipulator;
}
/**
@@ -66,7 +74,7 @@
ClassReader cr = new ClassReader(is1);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
- InnerClassAdapter adapter = new InnerClassAdapter(cw, m_outer, m_fields);
+ InnerClassAdapter adapter = new InnerClassAdapter(m_innerClassName, cw, m_outer, m_fields, m_manipulator);
if (version >= Opcodes.V1_6) {
cr.accept(adapter, ClassReader.EXPAND_FRAMES);
} else {
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 a9d439b..7ebb8f4 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
@@ -19,19 +19,17 @@
package org.apache.felix.ipojo.manipulation;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
import org.apache.felix.ipojo.metadata.Attribute;
import org.apache.felix.ipojo.metadata.Element;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.*;
+
/**
* iPOJO Byte code Manipulator.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
@@ -59,9 +57,9 @@
private String m_superClass;
/**
- * List of owned inner classed.
+ * List of owned inner classes and internal methods.
*/
- private List<String> m_inners;
+ private Map<String, List<MethodDescriptor>> m_inners;
/**
* Java byte code version.
@@ -69,6 +67,16 @@
private int m_version;
/**
+ * Was the class already manipulated.
+ */
+ private boolean m_alreadyManipulated;
+
+ /**
+ * The manipulated class name.
+ */
+ private String m_className;
+
+ /**
* Manipulate the given byte array.
* @param origin : original class.
* @return the manipulated class, if the class is already manipulated, the original class.
@@ -84,6 +92,7 @@
is1.close();
m_fields = ck.getFields(); // Get visited fields (contains only POJO fields)
+ m_className = ck.getClassName();
// Get interfaces and super class.
m_interfaces = ck.getInterfaces();
@@ -92,12 +101,15 @@
// Get the methods list
m_methods = ck.getMethods();
- m_inners = ck.getInnerClasses();
+ m_inners = ck.getInnerClassesAndMethods();
m_version = ck.getClassVersion();
ClassWriter finalWriter = null;
- if (!ck.isAlreadyManipulated()) {
+
+ m_alreadyManipulated = ck.isAlreadyManipulated();
+
+ if (!m_alreadyManipulated) {
// Manipulation ->
// Add the _setComponentManager method
// Instrument all fields
@@ -105,17 +117,17 @@
ClassReader cr0 = new ClassReader(is2);
ClassWriter cw0 = new ClassWriter(ClassWriter.COMPUTE_MAXS);
//CheckClassAdapter ch = new CheckClassAdapter(cw0);
- MethodCreator preprocess = new MethodCreator(cw0, m_fields, m_methods);
+ MethodCreator process = new MethodCreator(cw0, m_fields, m_methods);
if (ck.getClassVersion() >= Opcodes.V1_6) {
- cr0.accept(preprocess, ClassReader.EXPAND_FRAMES);
+ cr0.accept(process, ClassReader.EXPAND_FRAMES);
} else {
- cr0.accept(preprocess, 0);
+ cr0.accept(process, 0);
}
is2.close();
finalWriter = cw0;
}
// The file is in the bundle
- if (ck.isAlreadyManipulated()) {
+ if (m_alreadyManipulated) {
return origin;
} else {
return finalWriter.toByteArray();
@@ -123,51 +135,100 @@
}
/**
+ * Checks whether the class was already manipulated.
+ * @return {@code true} if the class was already manipulated, {@code false} otherwise
+ */
+ public boolean isAlreadyManipulated() {
+ return m_alreadyManipulated;
+ }
+
+ public static String toQualifiedName(String clazz) {
+ return clazz.replace("/", ".");
+ }
+
+ /**
* Compute component type manipulation metadata.
* @return the manipulation metadata of the class.
*/
public Element getManipulationMetadata() {
Element elem = new Element("Manipulation", "");
+ elem.addAttribute(new Attribute("className", toQualifiedName(m_className)));
+
if (m_superClass != null) {
elem.addAttribute(new Attribute("super", m_superClass));
}
- for (int j = 0; j < m_interfaces.size(); j++) {
+ for (String m_interface : m_interfaces) {
Element itf = new Element("Interface", "");
- Attribute att = new Attribute("name", m_interfaces.get(j).toString());
+ Attribute att = new Attribute("name", m_interface);
itf.addAttribute(att);
elem.addElement(itf);
}
- for (Iterator<String> it = m_fields.keySet().iterator(); it.hasNext();) {
+ for (Map.Entry<String, String> f : m_fields.entrySet()) {
Element field = new Element("Field", "");
- String name = it.next();
- String type = m_fields.get(name);
- Attribute attName = new Attribute("name", name);
- Attribute attType = new Attribute("type", type);
+ Attribute attName = new Attribute("name", f.getKey());
+ Attribute attType = new Attribute("type", f.getValue());
field.addAttribute(attName);
field.addAttribute(attType);
elem.addElement(field);
}
- for (int j = 0; j < m_methods.size(); j++) {
- MethodDescriptor method = (MethodDescriptor) m_methods.get(j);
+ for (MethodDescriptor method : m_methods) {
elem.addElement(method.getElement());
}
+ for (Map.Entry<String, List<MethodDescriptor>> inner : m_inners.entrySet()) {
+ Element element = new Element("Inner", "");
+ Attribute name = new Attribute("name", extractInnerClassName(toQualifiedName(inner.getKey())));
+ element.addAttribute(name);
+
+ for (MethodDescriptor method : inner.getValue()) {
+ element.addElement(method.getElement());
+ }
+ elem.addElement(element);
+ }
+
return elem;
}
+ /**
+ * Extracts the inner class simple name from the qualified name. It extracts the part after the `$` character.
+ * @param clazz the qualified class name
+ * @return the simple inner class name
+ */
+ public static String extractInnerClassName(String clazz) {
+ if (!clazz.contains("$")) {
+ return clazz;
+ } else {
+ return clazz.substring(clazz.indexOf("$") +1);
+ }
+ }
+
public Map<String, String> getFields() {
return m_fields;
}
- public List<String> getInnerClasses() {
- return m_inners;
+ public Collection<String> getInnerClasses() {
+ return new ArrayList<String>(m_inners.keySet());
}
public int getClassVersion() {
return m_version;
}
+
+ /**
+ * Adds a method to an inner class.
+ * @param name the inner class name
+ * @param md the method descriptor to add
+ */
+ public void addMethodToInnerClass(String name, MethodDescriptor md) {
+ List<MethodDescriptor> list = m_inners.get(name);
+ if (list == null) {
+ list = new ArrayList<MethodDescriptor>();
+ m_inners.put(name, list);
+ }
+ list.add(md);
+ }
}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java
index fe0890c..28e9ccd 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java
@@ -32,26 +32,25 @@
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class MethodDescriptor {
-
/**
* Method name.
*/
- private String m_name;
+ private final String m_name;
/**
* Returned type.
*/
- private String m_returnType;
+ private final String m_returnType;
/**
* Argument types.
*/
- private String[] m_arguments;
+ private final String[] m_arguments;
/**
* The descriptor of the method.
*/
- private String m_desc;
+ private final String m_desc;
/**
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 e71c0a7..5d3eb72 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
@@ -111,7 +111,6 @@
try {
byte[] out = manipulator.manipulate(bytecode);
// Call the visitor
- result.visitClassStructure(manipulator.getManipulationMetadata());
result.visitManipulatedResource(info.getResourcePath(), out);
} catch (IOException e) {
m_reporter.error("Cannot manipulate the class " + info.getClassName() + " : " + e.getMessage());
@@ -137,7 +136,9 @@
// 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());
+ InnerClassManipulator innerManipulator = new InnerClassManipulator(inner,
+ outerClassInternalName,
+ manipulator);
byte[] manipulated = innerManipulator.manipulate(innerClassBytecode, manipulator.getClassVersion());
// Propagate manipulated resource
result.visitManipulatedResource(resourcePath, manipulated);
@@ -147,6 +148,9 @@
}
}
+ // Compute manipulation metadata
+ result.visitClassStructure(manipulator.getManipulationMetadata());
+
// All resources have been manipulated for this component
result.visitEnd();
}
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/ClassCheckerTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/ClassCheckerTestCase.java
index ca0f95b..2d5be01 100644
--- a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/ClassCheckerTestCase.java
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/ClassCheckerTestCase.java
@@ -21,6 +21,7 @@
import java.io.ByteArrayInputStream;
import java.io.File;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -58,7 +59,7 @@
assertNull(checker.getSuperClass());
// Check inner classes
- List<String> inner = checker.getInnerClasses();
+ Collection<String> inner = checker.getInnerClasses();
assertTrue(inner.isEmpty());
// Ensure fields are correctly filtered
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/InnerClassAdapterTest.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/InnerClassAdapterTest.java
index 2e1bd61..3298b57 100644
--- a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/InnerClassAdapterTest.java
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/InnerClassAdapterTest.java
@@ -22,7 +22,7 @@
import junit.framework.Assert;
import org.apache.felix.ipojo.InstanceManager;
import org.apache.felix.ipojo.Pojo;
-import org.junit.Ignore;
+import org.apache.felix.ipojo.metadata.Element;
import org.junit.Test;
import org.mockito.Mockito;
@@ -55,7 +55,8 @@
byte[] innerClassBytecode = ManipulatorTest.getBytesFromFile(new File(baseClassDirectory + s + "" +
".class"));
String innerClassName = s.replace("/", ".");
- InnerClassManipulator innerManipulator = new InnerClassManipulator(outerClassInternalName, manipulator.getFields().keySet());
+ InnerClassManipulator innerManipulator = new InnerClassManipulator(s, outerClassInternalName,
+ manipulator);
byte[] manipulated = innerManipulator.manipulate(innerClassBytecode, manipulator.getClassVersion());
classloader.addInnerClass(innerClassName, manipulated);
}
@@ -146,4 +147,96 @@
assertEquals(result, "foofoofoofoo");
}
+ @Test
+ public void testRemanipulationOfInnerClasses() throws IOException, ClassNotFoundException, NoSuchMethodException,
+ IllegalAccessException, InvocationTargetException, InstantiationException {
+ Manipulator manipulator = new Manipulator();
+ String className = "test.inner.ComponentWithInnerClasses";
+
+ // Two manipulation of the outer class.
+ byte[] bytecode = manipulator.manipulate(ManipulatorTest.getBytesFromFile(new File
+ (baseClassDirectory + className.replace(".", "/") + ".class")));
+ bytecode = manipulator.manipulate(bytecode);
+
+ ManipulatedClassLoader classloader = new ManipulatedClassLoader(className, bytecode);
+
+ // Manipulate all inner classes
+ for (String s : manipulator.getInnerClasses()) {
+ String outerClassInternalName = className.replace(".", "/");
+ byte[] innerClassBytecode = ManipulatorTest.getBytesFromFile(new File(baseClassDirectory + s + "" +
+ ".class"));
+ String innerClassName = s.replace("/", ".");
+ InnerClassManipulator innerManipulator = new InnerClassManipulator(s, outerClassInternalName,
+ manipulator);
+ // Two manipulation of all inner classes.
+ byte[] manipulated = innerManipulator.manipulate(innerClassBytecode, manipulator.getClassVersion());
+ manipulated = innerManipulator.manipulate(manipulated, manipulator.getClassVersion());
+ classloader.addInnerClass(innerClassName, manipulated);
+ }
+
+ Class clazz = classloader.findClass(className);
+ Assert.assertNotNull(clazz);
+ Assert.assertNotNull(manipulator.getManipulationMetadata());
+ Assert.assertFalse(manipulator.getInnerClasses().isEmpty());
+ // We should have found only 2 inner classes.
+ assertThat(manipulator.getInnerClasses().size()).isEqualTo(3);
+
+ // Check that all inner classes are manipulated.
+ InstanceManager im = Mockito.mock(InstanceManager.class);
+ Constructor constructor = clazz.getDeclaredConstructor(InstanceManager.class);
+ constructor.setAccessible(true);
+ Object pojo = constructor.newInstance(new Object[] {im});
+ Assert.assertNotNull(pojo);
+ Assert.assertTrue(pojo instanceof Pojo);
+ Method method = clazz.getMethod("doSomething", new Class[0]);
+ String result = (String) method.invoke(pojo);
+ assertEquals(result, "foofoofoofoo");
+ }
+
+ @Test
+ public void testThatManipulationMetadataContainsTheInnerClasses() throws IOException, ClassNotFoundException,
+ NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
+ Manipulator manipulator = new Manipulator();
+ String className = "test.inner.ComponentWithInnerClasses";
+ manipulate(className, manipulator);
+
+ assertThat(manipulator.getInnerClasses().size()).isEqualTo(3);
+
+ Element manipulation = manipulator.getManipulationMetadata();
+ System.out.println(manipulation);
+ Element[] inners = manipulation.getElements("inner");
+ assertThat(inners.length).isEqualTo(3);
+
+ Element inner = getInnerClassMetadataByName(inners, "MyInnerWithANativeMethod");
+ assertThat(inner).isNotNull();
+ assertThat(getMethodByName(inner.getElements("method"), "foo")).isNotNull();
+
+ inner = getInnerClassMetadataByName(inners, "MyInnerClass");
+ assertThat(inner).isNotNull();
+ assertThat(getMethodByName(inner.getElements("method"), "foo")).isNotNull();
+
+ inner = getInnerClassMetadataByName(inners, "1");
+ assertThat(inner).isNotNull();
+ assertThat(getMethodByName(inner.getElements("method"), "compute")).isNotNull();
+
+ }
+
+ private static Element getInnerClassMetadataByName(Element[] inners, String name) {
+ for (Element element : inners) {
+ if (name.equals(element.getAttribute("name"))) {
+ return element;
+ }
+ }
+ return null;
+ }
+
+ private static Element getMethodByName(Element[] methods, String name) {
+ for (Element element : methods) {
+ if (name.equals(element.getAttribute("name"))) {
+ return element;
+ }
+ }
+ return null;
+ }
+
}
diff --git a/ipojo/manipulator/manipulator/src/test/java/test/inner/ComponentWithInnerClasses.java b/ipojo/manipulator/manipulator/src/test/java/test/inner/ComponentWithInnerClasses.java
index f568c7e..12927b6 100644
--- a/ipojo/manipulator/manipulator/src/test/java/test/inner/ComponentWithInnerClasses.java
+++ b/ipojo/manipulator/manipulator/src/test/java/test/inner/ComponentWithInnerClasses.java
@@ -32,17 +32,19 @@
MyInnerClass inn = new MyInnerClass();
Computation compute = new Computation() {
- public String compute() {
+ public String compute(final String s) {
return "foo";
}
};
- return nat.foo() + MyStaticInnerClass.foo() + inn.foo() + compute.compute();
+ return nat.foo() + MyStaticInnerClass.foo() + inn.foo() + compute.compute("");
}
+ private String foo = "foo";
+
private class MyInnerWithANativeMethod {
public String foo() {
- return "foo";
+ return ComponentWithInnerClasses.this.foo;
}
public native void baz();
@@ -64,7 +66,7 @@
private class MyInnerClass {
public String foo() {
- return "foo";
+ return ComponentWithInnerClasses.this.foo;
}
}
diff --git a/ipojo/manipulator/manipulator/src/test/java/test/inner/Computation.java b/ipojo/manipulator/manipulator/src/test/java/test/inner/Computation.java
index d9252b9..065af03 100644
--- a/ipojo/manipulator/manipulator/src/test/java/test/inner/Computation.java
+++ b/ipojo/manipulator/manipulator/src/test/java/test/inner/Computation.java
@@ -24,5 +24,5 @@
*/
public interface Computation {
- public String compute();
+ public String compute(String s);
}