Search in sources :

Example 16 with ClassReader

use of org.objectweb.asm.ClassReader in project android_frameworks_base by ParanoidAndroid.

the class DependencyFinder method parseZip.

// ----------------
/**
     * Parses a JAR file and returns a list of all classes founds using a map
     * class name => ASM ClassReader. Class names are in the form "android.view.View".
     */
Map<String, ClassReader> parseZip(List<String> jarPathList) throws IOException {
    TreeMap<String, ClassReader> classes = new TreeMap<String, ClassReader>();
    for (String jarPath : jarPathList) {
        ZipFile zip = new ZipFile(jarPath);
        Enumeration<? extends ZipEntry> entries = zip.entries();
        ZipEntry entry;
        while (entries.hasMoreElements()) {
            entry = entries.nextElement();
            if (entry.getName().endsWith(".class")) {
                ClassReader cr = new ClassReader(zip.getInputStream(entry));
                String className = classReaderToClassName(cr);
                classes.put(className, cr);
            }
        }
    }
    return classes;
}
Also used : ZipFile(java.util.zip.ZipFile) ZipEntry(java.util.zip.ZipEntry) ClassReader(org.objectweb.asm.ClassReader) TreeMap(java.util.TreeMap)

Example 17 with ClassReader

use of org.objectweb.asm.ClassReader in project android_frameworks_base by ParanoidAndroid.

the class DelegateClassAdapterTest method testConstructorsNotSupported.

/**
     * {@link DelegateMethodAdapter2} does not support overriding constructors yet,
     * so this should fail with an {@link UnsupportedOperationException}.
     *
     * Although not tested here, the message of the exception should contain the
     * constructor signature.
     */
@Test(expected = UnsupportedOperationException.class)
public void testConstructorsNotSupported() throws IOException {
    ClassWriter cw = new ClassWriter(0);
    String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
    HashSet<String> delegateMethods = new HashSet<String>();
    delegateMethods.add("<init>");
    DelegateClassAdapter cv = new DelegateClassAdapter(mLog, cw, internalClassName, delegateMethods);
    ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
    cr.accept(cv, 0);
}
Also used : ClassReader(org.objectweb.asm.ClassReader) ClassWriter(org.objectweb.asm.ClassWriter) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 18 with ClassReader

use of org.objectweb.asm.ClassReader in project android_frameworks_base by ParanoidAndroid.

the class DelegateClassAdapterTest method testDelegateInner.

@Test
public void testDelegateInner() throws Throwable {
    // We'll delegate the "get" method of both the inner and outer class.
    HashSet<String> delegateMethods = new HashSet<String>();
    delegateMethods.add("get");
    delegateMethods.add("privateMethod");
    // Generate the delegate for the outer class.
    ClassWriter cwOuter = new ClassWriter(0);
    String outerClassName = OUTER_CLASS_NAME.replace('.', '/');
    DelegateClassAdapter cvOuter = new DelegateClassAdapter(mLog, cwOuter, outerClassName, delegateMethods);
    ClassReader cr = new ClassReader(OUTER_CLASS_NAME);
    cr.accept(cvOuter, 0);
    // Generate the delegate for the inner class.
    ClassWriter cwInner = new ClassWriter(0);
    String innerClassName = INNER_CLASS_NAME.replace('.', '/');
    DelegateClassAdapter cvInner = new DelegateClassAdapter(mLog, cwInner, innerClassName, delegateMethods);
    cr = new ClassReader(INNER_CLASS_NAME);
    cr.accept(cvInner, 0);
    // Load the generated classes in a different class loader and try them
    ClassLoader2 cl2 = null;
    try {
        cl2 = new ClassLoader2() {

            @Override
            public void testModifiedInstance() throws Exception {
                // Check the outer class
                Class<?> outerClazz2 = loadClass(OUTER_CLASS_NAME);
                Object o2 = outerClazz2.newInstance();
                assertNotNull(o2);
                // The original Outer.get returns 1+10+20,
                // but the delegate makes it return 4+10+20
                assertEquals(4 + 10 + 20, callGet(o2, 10, 20));
                assertEquals(1 + 10 + 20, callGet_Original(o2, 10, 20));
                // The original Outer has a private method that is
                // delegated. We should be able to call both the delegate
                // and the original (which is now public).
                assertEquals("outerPrivateMethod", callMethod(o2, "privateMethod_Original", false));
                // The original method is private, so by default we can't access it
                boolean gotIllegalAccessException = false;
                try {
                    callMethod(o2, "privateMethod", false);
                } catch (IllegalAccessException e) {
                    gotIllegalAccessException = true;
                }
                assertTrue(gotIllegalAccessException);
                // Try again, but now making it accessible
                assertEquals("outerPrivate_Delegate", callMethod(o2, "privateMethod", true));
                // Check the inner class. Since it's not a static inner class, we need
                // to use the hidden constructor that takes the outer class as first parameter.
                Class<?> innerClazz2 = loadClass(INNER_CLASS_NAME);
                Constructor<?> innerCons = innerClazz2.getConstructor(new Class<?>[] { outerClazz2 });
                Object i2 = innerCons.newInstance(new Object[] { o2 });
                assertNotNull(i2);
                // The original Inner.get returns 3+10+20,
                // but the delegate makes it return 6+10+20
                assertEquals(6 + 10 + 20, callGet(i2, 10, 20));
                assertEquals(3 + 10 + 20, callGet_Original(i2, 10, 20));
            }
        };
        cl2.add(OUTER_CLASS_NAME, cwOuter.toByteArray());
        cl2.add(INNER_CLASS_NAME, cwInner.toByteArray());
        cl2.testModifiedInstance();
    } catch (Throwable t) {
        throw dumpGeneratedClass(t, cl2);
    }
}
Also used : Constructor(java.lang.reflect.Constructor) ClassWriter(org.objectweb.asm.ClassWriter) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException) ClassReader(org.objectweb.asm.ClassReader) OuterClass(com.android.tools.layoutlib.create.dataclass.OuterClass) InnerClass(com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 19 with ClassReader

use of org.objectweb.asm.ClassReader in project android_frameworks_base by ParanoidAndroid.

the class DelegateClassAdapterTest method dumpGeneratedClass.

/**
     * For debugging, it's useful to dump the content of the generated classes
     * along with the exception that was generated.
     *
     * However to make it work you need to pull in the org.objectweb.asm.util.TraceClassVisitor
     * class and associated utilities which are found in the ASM source jar. Since we don't
     * want that dependency in the source code, we only put it manually for development and
     * access the TraceClassVisitor via reflection if present.
     *
     * @param t The exception thrown by {@link ClassLoader2#testModifiedInstance()}
     * @param cl2 The {@link ClassLoader2} instance with the generated bytecode.
     * @return Either original {@code t} or a new wrapper {@link Throwable}
     */
private Throwable dumpGeneratedClass(Throwable t, ClassLoader2 cl2) {
    try {
        // For debugging, dump the bytecode of the class in case of unexpected error
        // if we can find the TraceClassVisitor class.
        Class<?> tcvClass = Class.forName("org.objectweb.asm.util.TraceClassVisitor");
        StringBuilder sb = new StringBuilder();
        sb.append('\n').append(t.getClass().getCanonicalName());
        if (t.getMessage() != null) {
            sb.append(": ").append(t.getMessage());
        }
        for (Entry<String, byte[]> entry : cl2.getByteCode()) {
            String className = entry.getKey();
            byte[] bytes = entry.getValue();
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            // next 2 lines do: TraceClassVisitor tcv = new TraceClassVisitor(pw);
            Constructor<?> cons = tcvClass.getConstructor(new Class<?>[] { pw.getClass() });
            Object tcv = cons.newInstance(new Object[] { pw });
            ClassReader cr2 = new ClassReader(bytes);
            cr2.accept((ClassVisitor) tcv, 0);
            sb.append("\nBytecode dump: <").append(className).append(">:\n").append(sw.toString());
        }
        // Re-throw exception with new message
        RuntimeException ex = new RuntimeException(sb.toString(), t);
        return ex;
    } catch (Throwable ignore) {
        // In case of problem, just throw the original exception as-is.
        return t;
    }
}
Also used : StringWriter(java.io.StringWriter) ClassReader(org.objectweb.asm.ClassReader) PrintWriter(java.io.PrintWriter)

Example 20 with ClassReader

use of org.objectweb.asm.ClassReader in project android_frameworks_base by ParanoidAndroid.

the class DelegateClassAdapterTest method testNoOp.

/**
     * Tests that a class not being modified still works.
     */
@SuppressWarnings("unchecked")
@Test
public void testNoOp() throws Throwable {
    // create an instance of the class that will be modified
    // (load the class in a distinct class loader so that we can trash its definition later)
    ClassLoader cl1 = new ClassLoader(this.getClass().getClassLoader()) {
    };
    Class<ClassWithNative> clazz1 = (Class<ClassWithNative>) cl1.loadClass(NATIVE_CLASS_NAME);
    ClassWithNative instance1 = clazz1.newInstance();
    assertEquals(42, instance1.add(20, 22));
    try {
        instance1.callNativeInstance(10, 3.1415, new Object[0]);
        fail("Test should have failed to invoke callTheNativeMethod [1]");
    } catch (UnsatisfiedLinkError e) {
    // This is expected to fail since the native method is not implemented.
    }
    // Now process it but tell the delegate to not modify any method
    ClassWriter cw = new ClassWriter(0);
    HashSet<String> delegateMethods = new HashSet<String>();
    String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
    DelegateClassAdapter cv = new DelegateClassAdapter(mLog, cw, internalClassName, delegateMethods);
    ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
    cr.accept(cv, 0);
    // Load the generated class in a different class loader and try it again
    ClassLoader2 cl2 = null;
    try {
        cl2 = new ClassLoader2() {

            @Override
            public void testModifiedInstance() throws Exception {
                Class<?> clazz2 = loadClass(NATIVE_CLASS_NAME);
                Object i2 = clazz2.newInstance();
                assertNotNull(i2);
                assertEquals(42, callAdd(i2, 20, 22));
                try {
                    callCallNativeInstance(i2, 10, 3.1415, new Object[0]);
                    fail("Test should have failed to invoke callTheNativeMethod [2]");
                } catch (InvocationTargetException e) {
                    // This is expected to fail since the native method has NOT been
                    // overridden here.
                    assertEquals(UnsatisfiedLinkError.class, e.getCause().getClass());
                }
                // Check that the native method does NOT have the new annotation
                Method[] m = clazz2.getDeclaredMethods();
                assertEquals("native_instance", m[2].getName());
                assertTrue(Modifier.isNative(m[2].getModifiers()));
                Annotation[] a = m[2].getAnnotations();
                assertEquals(0, a.length);
            }
        };
        cl2.add(NATIVE_CLASS_NAME, cw);
        cl2.testModifiedInstance();
    } catch (Throwable t) {
        throw dumpGeneratedClass(t, cl2);
    }
}
Also used : ClassWriter(org.objectweb.asm.ClassWriter) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException) InvocationTargetException(java.lang.reflect.InvocationTargetException) ClassReader(org.objectweb.asm.ClassReader) OuterClass(com.android.tools.layoutlib.create.dataclass.OuterClass) InnerClass(com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass) ClassWithNative(com.android.tools.layoutlib.create.dataclass.ClassWithNative) HashSet(java.util.HashSet) Test(org.junit.Test)

Aggregations

ClassReader (org.objectweb.asm.ClassReader)437 ClassWriter (org.objectweb.asm.ClassWriter)182 Test (org.junit.Test)134 IOException (java.io.IOException)77 InputStream (java.io.InputStream)75 TreeMap (java.util.TreeMap)59 ClassNode (org.objectweb.asm.tree.ClassNode)58 SemanticVersioningClassVisitor (org.apache.aries.versioning.utils.SemanticVersioningClassVisitor)53 ClassVisitor (org.objectweb.asm.ClassVisitor)48 HashSet (java.util.HashSet)39 ZipEntry (java.util.zip.ZipEntry)34 BinaryCompatibilityStatus (org.apache.aries.versioning.utils.BinaryCompatibilityStatus)32 ZipFile (java.util.zip.ZipFile)29 InvocationTargetException (java.lang.reflect.InvocationTargetException)26 Method (java.lang.reflect.Method)25 OuterClass (com.android.tools.layoutlib.create.dataclass.OuterClass)23 InnerClass (com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass)23 PrintWriter (java.io.PrintWriter)23 MethodVisitor (org.objectweb.asm.MethodVisitor)23 MethodNode (org.objectweb.asm.tree.MethodNode)21