123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- /*******************************************************************************
- * Copyright (c) 2005 Contributors.
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Public License v 2.0
- * which accompanies this distribution and is available at
- * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
- *
- * 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.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);
- }
-
- interface ISome {
- 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 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)
- @interface ASome {}
-
- ISome getJit() {
- ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
- 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", false);
- 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();
- // Needs "--add-opens java.base/java.lang=ALL-UNNAMED" on the JVM command line, injected in Ant build via
- // aj.addOpensKey and aj.addOpensValue variables. See also AntSpec::execute.
- Method def = ClassLoader.class.getDeclaredMethod("defineClass", 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.getDeclaredConstructor().newInstance();
- } catch (Throwable t) {
- fail(t.toString());
- return null;
- }
- }
-
- Serializable getJitNoMatch() {
- ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
- 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", false);
- mv.visitInsn(Opcodes.RETURN);
- mv.visitMaxs(0, 0);
- cw.visitEnd();
-
- try {
- ClassLoader loader = this.getClass().getClassLoader();
- // Needs "--add-opens java.base/java.lang=ALL-UNNAMED" on the JVM command line, injected in Ant build via
- // aj.addOpensKey and aj.addOpensValue variables. See also AntSpec::execute.
- Method def = ClassLoader.class.getDeclaredMethod("defineClass", 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.getDeclaredConstructor().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);
- }
-
- }
|