Bug 162310 - ajc create the bytecode that cause java.lang.VerifyError by instantiation
Summary: ajc create the bytecode that cause java.lang.VerifyError by instantiation
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.5.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-10-25 16:21 EDT by Y. Kornev CLA
Modified: 2006-10-26 05:00 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Y. Kornev CLA 2006-10-25 16:21:42 EDT
receive the error: 

Exception in thread "Thread-0" java.lang.VerifyError: (class: comps/TestUnit, method: doK signature: ()V) Incompatible argument to function
	at java.lang.Class.getDeclaredConstructors0(Native Method)
	at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
	at java.lang.Class.getConstructor0(Unknown Source)
	at java.lang.Class.newInstance0(Unknown Source)
	at java.lang.Class.newInstance(Unknown Source)

the scenario:

1. project with the abstract aspect like this:
public abstract aspect AbstractAspect {
	public pointcut point();
	before() : point() {
		System.out.println(thisJoinPoint);
	}
}

2. project with the concrete aspect like this:
public aspect ConcreteAspect {
	public pointcut point() : execution (* *.doK*());
}
and some class comps.TestUnit having the method doK();

There is the main application in the 1. project. This find ConcreteAspect.class and change it (using BCEL) to make ConcreteAspect extend the AbstractAspect like this:

   JavaClass clazz = new ClassParser(/*needed arguments*/).parse();
   ClassGen clgen = new ClassGen(clazz);		
   clgen.setSuperclassName("AbstractAspect");		
   JavaClass cla = clgen.getJavaClass();
   cla.dump(/*file ConcreteAspect.class*/);

And now making the weaving with ajc. Have tryed do this with Runtime.getRuntime.exec(java org.aspectj.tools.ajc.Main) with needed parameters
or using org.aspectj.weaver.tools.WeavingAdaptor (load-time weaving) - the same result.
I am getting no compilation errors; with the -showWeaveInfo i have
"Join point 'method-execution(void comps.TestUnit.doK())' in Type 'comps.TestUnit' (TestUnit.java:17) advised by before advice from 'ConcreteAspect' (AbstractAspect.aj:6)"

Now i am loading the woven TestUnit to the JVM and try instantiate it with the java reflection (loadedClass.newInstance()) and receiving the above error;
Comment 1 Andrew Clement CLA 2006-10-26 02:55:59 EDT
I'm not sure why you think this would work?  There is more to connecting a pair of aspects together than just setting the superclass of one to be the other????  I don't think we support this way of working.
Comment 2 Y. Kornev CLA 2006-10-26 03:22:46 EDT
(In reply to comment #1)

why shouldnt it? the both aspects have the same pointcut name; the compiler have the access to the both aspects, i.e. pointcut definition and advice.

where is the mistake in this way?
Comment 3 Matthew Webster CLA 2006-10-26 03:26:38 EDT
AspectJ has a number of public, documented (http://www.eclipse.org/aspectj/doc/released/devguide/index.html) interfaces for performing aspect weaving. For example you can use ajc to for compile- or post compile-time (binary) weaving. Alternatively you can use Aj or the -javaagent for load-time weaving.
Comment 4 Andrew Clement CLA 2006-10-26 03:40:15 EDT
If you really want to find the differences - put the 'extends' into the source, do a full build and compare the class file resulting for the sub-aspect and your 'faked' sub-aspect.
Comment 5 Y. Kornev CLA 2006-10-26 05:00:57 EDT
(In reply to comment #4)

okay the bytecode is not the same,
but i compared the compiler's output of TestUnit putting 'extends' to source code with the output provided using "'faked' sub-aspect"
this is the method doK (normal):
 // access flags 1
  public doK() : void
  ATTRIBUTE org.aspectj.weaver.MethodDeclarationLineNumber : unknown
    GETSTATIC TestUnit.ajc$tjp_0 : JoinPoint$StaticPart
    ALOAD 0
    ALOAD 0
    INVOKESTATIC Factory.makeJP(JoinPoint$StaticPart,Object,Object) : JoinPoint
    ASTORE 1
    INVOKESTATIC ConcreteAspect.aspectOf() : ConcreteAspect
    ALOAD 1
    INVOKEVIRTUAL AbstractAspect.ajc$before$asps_AbstractAspect$1$5d3d8e49(JoinPoint) : void
   L0 (8)
    LINENUMBER 18 L0
    GETSTATIC System.out : PrintStream
    LDC "TestUnit doK"
    INVOKEVIRTUAL PrintStream.println(String) : void
   L1 (12)
    LINENUMBER 20 L1
    RETURN
   L2 (14)
    LOCALVARIABLE this TestUnit L0 L2 0
    MAXSTACK = 3
    MAXLOCALS = 2

and "faked":

// access flags 1
  public doK() : void
  ATTRIBUTE org.aspectj.weaver.MethodDeclarationLineNumber : unknown
    GETSTATIC TestUnit.ajc$tjp_0 : JoinPoint$StaticPart
    ALOAD 0
    ALOAD 0
    INVOKESTATIC Factory.makeJP(JoinPoint$StaticPart,Object,Object) : JoinPoint
    ASTORE 1
   L0 (5)
    LINENUMBER 18 L0
    INVOKESTATIC ConcreteAspect.aspectOf() : ConcreteAspect
    ALOAD 1
    INVOKEVIRTUAL AbstractAspect.ajc$before$asps_AbstractAspect$1$5d3d8e49(JoinPoint) : void
   L1 (9)
    GETSTATIC System.out : PrintStream
    LDC "TestUnit doK"
    INVOKEVIRTUAL PrintStream.println(String) : void
   L2 (13)
    LINENUMBER 20 L2
    RETURN
   L3 (15)
    LOCALVARIABLE this TestUnit L1 L3 0
    MAXSTACK = 3
    MAXLOCALS = 2


so i realize they are not the same but can the code in the second case cause the
"Incompatible argument to function"-error?