Bug 266564 - java.lang.VerifyError: Register 2 contains wrong type
Summary: java.lang.VerifyError: Register 2 contains wrong type
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Runtime (show other bugs)
Version: 1.6.3   Edit
Hardware: PC Windows XP
: P2 critical (vote)
Target Milestone: 1.6.4   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-02-27 16:43 EST by Rao Vootla CLA
Modified: 2009-02-27 21:29 EST (History)
2 users (show)

See Also:


Attachments
Error stack trace for Bug id: 266564 (4.12 KB, text/plain)
2009-02-27 17:13 EST, Rao Vootla CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Rao Vootla CLA 2009-02-27 16:43:31 EST
ENV:
Eclipse 3.4
AJDT 1.6.3
Spring 2.5
JDK 1.6
Windows XP SP2

I have Annotation based AOP on Spring managed beans and on objects that are not managed by Spring. 

Only certain methods run into the above error. If I tweak my pointcut expression to limit the markers, evrything in Eclipse and Jetty works fine.

Example method body that shows the error:
*****
	public boolean isUserAuthrized(long docId, String userId) {

		return priceUtilDao.isUserAuthrized(docId, userId);
	}
********

Pointcut:
	@Pointcut("execution(* *..business..*(..))")
	public void businessServiceLayer() {
	}

If I use 
	@Pointcut("execution(* *..business..get*(..))")
	public void businessServiceLayer() {
	}

Jetty and Junit work just fine.


A regualr compile works fine and runs fine in weblogic 103.

Junit tests and jetty launch throw the above error.
Comment 1 Rao Vootla CLA 2009-02-27 16:46:07 EST
adding myself to the mail-
Comment 2 Andrew Clement CLA 2009-02-27 16:47:39 EST
can you include the exception stack trace please?
Comment 3 Rao Vootla CLA 2009-02-27 17:13:49 EST
Created attachment 127055 [details]
Error stack trace for Bug id: 266564

Error stack trace attached.
Comment 4 Andrew Clement CLA 2009-02-27 17:38:50 EST
From the stack trace we see that the verifyerror is in some generated around advice in PWSPriceUtilImpl.isPriceDocAuthrized_aroundBody23$advice.

java.lang.VerifyError: (class: com/uprr/app/pws/client/price/business/PWSPriceUtilImpl, method: isPriceDocAuthrized_aroundBody23$advice signature: (Lcom/uprr/app/pws/client/price/business/PWSPriceUtilImpl;JLjava/lang/String;Lorg/aspectj/lang/JoinPoint;Lcom/uprr/app/pws/client/price/aop/TraceInterceptor;Lorg/aspectj/lang/ProceedingJoinPoint;)Ljava/lang/Object;) Register 2 contains wrong type

Presumably this is because of one of the join points that the unrestricted pointcut (that didn't specify a name) matched upon in the PWSPriceUtilImpl class.

My current thought based on the signature of the method:

public boolean isUserAuthrized(long docId, String userId)

is that the weaver is not allowing for a long which consumes two slots rather than just one.

Comment 5 Andrew Clement CLA 2009-02-27 17:42:06 EST
Yup, that is it - very serious bug. This program will crash in the same way:

---
package business;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

public class AA {

        public void foo(long docId, String userid) {
        }

        public static void main(String[] args) {
                new AA().foo(12, "hello");
        }
}

@Aspect
class Asp {

        @Around("execution(* foo(..))")
        public Object around(ProceedingJoinPoint pjp) {
                return pjp.proceed();
        }
}
---


Comment 6 Andrew Clement CLA 2009-02-27 17:46:25 EST
In the bytecode for the method:

private static final java.lang.Object foo_aroundBody1$advice(business.AA, long, java.lang.String, org.aspectj.lang.JoinPoint, business.Asp, org.aspectj.lang.ProceedingJoinPoint);
  Synthetic: true
  Code:
   Stack=5, Locals=8, Args_size=6
   0:	aload	6
   2:	astore	7
   4:	aload_0
   5:	lload_1
   6:	aload_2
   7:	aload	7
   9:	invokestatic	#70; //Method foo_aroundBody0:(Lbusiness/AA;JLjava/lang/String;Lorg/aspectj/lang/JoinPoint;)V
   12:	aconst_null
   13:	areturn

At instruction 6 we attempt aload_2 - that should have allowed for the long taking up 2 slots and been an aload_3
Comment 7 Rao Vootla CLA 2009-02-27 17:49:47 EST
Awesome! You are right on the mark.

However I am surprised as to why the weaver behavior is different in Eclipse vs. the regularly deployed ear package?

For now I am changing the method signatures to use int.

Also, is using an Object instead of a primitive help?

Thank you for such a quick discovery.
Comment 8 Rao Vootla CLA 2009-02-27 17:57:26 EST
With reference my question/comment regarding using an Object vs a primitive

Using a "Long" works well. It may be a little work, but it is a better work around.

Thanks.
Comment 9 Andrew Clement CLA 2009-02-27 17:58:48 EST
> However I am surprised as to why the weaver behavior is different in 
> Eclipse vs. the regularly deployed ear package?

Not quite sure - the probable reason is that in eclipse something happened that
meant it decided to not weave via inlining, but instead decided to use a
closure class.  This can be forced with the -XnoInline option, and indeed if I
force that test program to compile with no inlining:

ajc -XnoInline -1.5 AA.java

then it runs fine.

Sometimes the decision on whether inlining can occur can be for very simple
reasons like the order in which the weaver encountered the types.  So if your
eclipse and the later load-time weaver touched the types in a different order
that might explain it.
Comment 10 Andrew Clement CLA 2009-02-27 18:29:04 EST
Ok - fixed it.  It was the code to convert the proceed() call into a method call - it did not prepare the arguments correctly.

A messy workaround is to expose the parameter as context and pass them on proceed, that avoids the weaver trying and getting it wrong:


        @Around("execution(* foo(..)) && args(l,s)")
        public Object around(ProceedingJoinPoint pjp,Long l, String s) {
                return pjp.proceed(new Object[]{l,s});
        }

Anyway, the fix will be in the next dev build.

The fastest workaround for you would probably be putting -XnoInline in the weaver options section of your aop.xml:

<weaver options="-XnoInline"/>
Comment 11 Rao Vootla CLA 2009-02-27 21:29:32 EST
Thank you. This has been one of the fastest resolutions I have come across.

I will use the weaver options until the next stable release.