ataspectj.UnweavableTest.java Source code

Java tutorial

Introduction

Here is the source code for ataspectj.UnweavableTest.java

Source

/*******************************************************************************
 * Copyright (c) 2005 Contributors.
 * All rights reserved. 
 * This program and the accompanying materials are made available 
 * under the terms of the Eclipse Public License v1.0 
 * which accompanies this distribution and is available at 
 * http://eclipse.org/legal/epl-v10.html 
 * 
 * Contributors:
 *   Alexandre Vasseur         initial implementation
 *******************************************************************************/
package ataspectj;

import junit.framework.TestCase;

import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.security.ProtectionDomain;
import java.io.Serializable;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.AnnotationVisitor;

/**
 * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
 */
public class UnweavableTest extends TestCase {

    public void testUnweavableProxy() {
        TestAspect.I = 0;
        ISome some = getProxy();
        some.giveOne();
        assertEquals(1, TestAspect.I);
    }

    static interface ISome {
        public int giveOne();
    }

    ISome getProxy() {
        return (ISome) Proxy.newProxyInstance(ISome.class.getClassLoader(), new Class[] { ISome.class },
                new InvocationHandler() {
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        return new Integer(1);
                    }
                });
    }

    @Aspect
    public static class TestAspect {

        static int I = 0;

        @Before("execution(* ataspectj.UnweavableTest.ISome+.giveOne())")
        public void before() {
            I++;
        }
    }

    public void testJit() {
        TestAspect.I = 0;
        TestAspect2.I = 0;
        ISome some = getJit();
        assertNotNull(some.getClass().getAnnotation(ASome.class));
        assertEquals(2, some.giveOne());
        assertEquals(1, TestAspect.I);
        assertEquals(1, TestAspect2.I);
    }

    public void testJitNotMatched() {
        // just load a jit to make sure the weaver does not complains for classes coming from nowhere
        Serializable serial = getJitNoMatch();
        assertEquals(0, serial.getClass().getDeclaredMethods().length);
    }

    @Retention(RetentionPolicy.RUNTIME)
    static @interface ASome {
    }

    ISome getJit() {
        ClassWriter cw = new ClassWriter(true, true);
        cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "ataspectj/ISomeGen", null, "java/lang/Object",
                new String[] { "ataspectj/UnweavableTest$ISome" });
        AnnotationVisitor av = cw.visitAnnotation("Lataspectj/UnweavableTest$ASome;", true);
        av.visitEnd();

        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, new String[0]);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(0, 0);
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "giveOne", "()I", null, new String[0]);
        mv.visitInsn(Opcodes.ICONST_2);
        mv.visitInsn(Opcodes.IRETURN);
        mv.visitMaxs(0, 0);
        cw.visitEnd();

        try {
            ClassLoader loader = this.getClass().getClassLoader();
            Method def = ClassLoader.class.getDeclaredMethod("defineClass",
                    new Class[] { String.class, byte[].class, int.class, int.class });
            def.setAccessible(true);
            Class gen = (Class) def.invoke(loader, "ataspectj.ISomeGen", cw.toByteArray(), 0,
                    cw.toByteArray().length);
            return (ISome) gen.newInstance();
        } catch (Throwable t) {
            fail(t.toString());
            return null;
        }
    }

    Serializable getJitNoMatch() {
        ClassWriter cw = new ClassWriter(true, true);
        cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "ataspectj/unmatched/Gen", null, "java/lang/Object",
                new String[] { "java/io/Serializable" });

        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, new String[0]);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(0, 0);
        cw.visitEnd();

        try {
            ClassLoader loader = this.getClass().getClassLoader();
            Method def = ClassLoader.class.getDeclaredMethod("defineClass",
                    new Class[] { String.class, byte[].class, int.class, int.class });
            def.setAccessible(true);
            Class gen = (Class) def.invoke(loader, "ataspectj.unmatched.Gen", cw.toByteArray(), 0,
                    cw.toByteArray().length);
            return (Serializable) gen.newInstance();
        } catch (Throwable t) {
            fail(t.toString());
            return null;
        }
    }

    @Aspect
    public static class TestAspect2 {
        static int I = 0;

        @Before("execution(* @ataspectj.UnweavableTest$ASome ataspectj..*.giveOne())")
        public void before() {
            I++;
        }
    }

    public static void main(String args[]) throws Throwable {
        TestHelper.runAndThrowOnFailure(suite());
    }

    public static junit.framework.Test suite() {
        return new junit.framework.TestSuite(UnweavableTest.class);
    }

}