Bug 160146 - JVM VerifyError (invalid stack height) when LTW is used with Hibernate
Summary: JVM VerifyError (invalid stack height) when LTW is used with Hibernate
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: LTWeaving (show other bugs)
Version: 1.5.2   Edit
Hardware: PC Windows XP
: P3 major (vote)
Target Milestone: ---   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-10-08 05:34 EDT by Oleksandr Alesinskyy CLA
Modified: 2010-03-19 19:23 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Oleksandr Alesinskyy CLA 2006-10-08 05:34:52 EDT
This bug is very similar to Bug 117854 that is marked as fixed in 1.5.0, but my bug occurs against 1.5.2a.

Hibernate 3.1.3, JVM 1.5.0.8, AspectJ 1.5.2a. Spring 2.0RC3 (@Transactional aspect is used).

Stack trace

java.lang.VerifyError: (class: de/ntec/lms/impl/topology/CellImpl$$EnhancerByCGLIB$$5c6597e7, method: getPlaces signature: ()Ljava/util/Set;) Inconsistent stack height 1 != 0
	at java.lang.Class.getDeclaredConstructors0(Native Method)
	at java.lang.Class.privateGetDeclaredConstructors(Class.java:2357)
	at java.lang.Class.getConstructor0(Class.java:2671)
	at java.lang.Class.newInstance0(Class.java:321)
	at java.lang.Class.newInstance(Class.java:303)
	at org.hibernate.proxy.CGLIBLazyInitializer.getProxy(CGLIBLazyInitializer.java:99)
	at org.hibernate.proxy.CGLIBProxyFactory.getProxy(CGLIBProxyFactory.java:47)
	at org.hibernate.tuple.AbstractEntityTuplizer.createProxy(AbstractEntityTuplizer.java:372)
	at org.hibernate.persister.entity.AbstractEntityPersister.createProxy(AbstractEntityPersister.java:3121)
	at org.hibernate.event.def.DefaultLoadEventListener.createProxyIfNecessary(DefaultLoadEventListener.java:232)
	at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:173)
	at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:87)
	at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:862)
	at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:830)
	at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:266)
	at org.hibernate.type.EntityType.resolve(EntityType.java:303)
	at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:116)
	at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:842)
	at org.hibernate.loader.Loader.doQuery(Loader.java:717)
	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
	at org.hibernate.loader.Loader.doList(Loader.java:2145)
	at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2029)
	at org.hibernate.loader.Loader.list(Loader.java:2024)
	at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:111)
	at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1655)
	at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:142)
	at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:164)
	at de.ntec.lms.impl.topology.PlaceFinderImpl.reservePlace(PlaceFinderImpl.java:94)
	at de.ntec.lms.impl.topology.PlaceFinderTest.testReservation(PlaceFinderTest.java:165)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:585)
	at junit.framework.TestCase.runTest(TestCase.java:154)
	at de.ntec.common.spring.TxTestCase.access$0(TxTestCase.java:1)
	at de.ntec.common.spring.TxTestCase.doRunTest(TxTestCase.java:60)
	at de.ntec.common.spring.TxTestCase.runTest(TxTestCase.java:53)
	at junit.framework.TestCase.runBare(TestCase.java:127)
	at junit.framework.TestResult$1.protect(TestResult.java:106)
	at junit.framework.TestResult.runProtected(TestResult.java:124)
	at junit.framework.TestResult.run(TestResult.java:109)
	at junit.framework.TestCase.run(TestCase.java:118)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Comment 1 Oleksandr Alesinskyy CLA 2006-10-08 05:38:15 EDT
Forgot to mention -javaagent is used for weaving
Comment 2 Andrew Clement CLA 2006-10-08 15:43:22 EDT
As discussed in the bug you reference, the fix/workaround is probably the same - to avoid weaving the CGLIB generated files by using something like:

<exclude within="*CGLIB*"/>

in your aop.xml file.

Comment 3 Oleksandr Alesinskyy CLA 2006-10-08 17:08:55 EDT
Thank you, workaround I have already (it is specific for application),
but would give a try to your suggestion anyway.

But it would be very nice if bug will be fixed soon.
Comment 4 Oleksandr Alesinskyy CLA 2006-10-08 17:15:41 EDT
Neither 
    <weaver>
        <exclude within="*CGLIB*" /> 
        <include within="de.ntec..*" />
    </weaver>
nor
    <weaver>
        <include within="de.ntec..*" />
        <exclude within="*CGLIB*" /> 
    </weaver>
works. Include I really need as there  are a lot of other classes that I do not wont to weave (all JDK ,  Spring, Hibernate ...).
Comment 5 Oleksandr Alesinskyy CLA 2006-10-08 17:17:51 EDT
But this works
        <include within="de.ntec..*" />
        <exclude within="de.ntec.lms.impl.topology.*CGLIB*" /> 
Sorry for flooding.
Comment 6 Ron Bodkin CLA 2006-10-08 20:29:40 EDT
Have you tried using a recent development build of AspectJ? There have been a lot of bugs fixed since the 1.5.2 code came out (on which 1.5.2a is based). It would be helpful to know if this bug has been fixed already or not.
Comment 7 Andrew Clement CLA 2006-10-09 03:04:36 EDT
The CGLIB generated code is not suitable for our weaving strategy - as discussed in the other bug, it contains some incorrect stack manipulation which AspectJ makes 'visible' when the code is woven.  I don't plan on changing our weaving strategy any time soon.  The CGLIB guys said they would take a patch for the problem if anyone cared to write it - then code they created would work fine with AspectJ.
Comment 8 Oleksandr Alesinskyy CLA 2006-10-09 06:12:31 EDT
No, I have not, never use development builds for development. 
May try just to clarify if bug is fixed. Would inform about results.
Comment 9 Oleksandr Alesinskyy CLA 2006-10-09 07:28:23 EDT
Hello,

recent development build (aspectj-DEVELOPMENT-20061005121113.jar)
exibits exactly the same behavior. 

Concerning CGLIB - in other bug discussin was stated not that CGLIB makes incorrect stack manipulation that AspectJ, in turn, makes visible,
but that CGLIB make some unusual but perfectly legal stack manipulation that AspectJ is not prepared for. 

Anyway, I have to agree that weaving of proxies is usually not so great idea, so excluding of CGLIB generated classes from weaving is a correct solution for most cases - the only thing that, IMHO, it shall be documented outside of bug-tracking system, e.g. in AspectJ FAQ (faq.html delivered with AspectJ).

Regards,

Oleksandr
Comment 10 Andrew Clement CLA 2006-10-09 08:30:15 EDT
Yes - could put something in the FAQ on this, or compiler limitations section of the doc.

I shouldn't have used the word 'incorrect' earlier - I should have said "unusual".  AspectJ doesn't expect two exit points from a method to have different stack heights - so when they are merged to travel through a single after advice, the stack heights are discovered to be inconsistent on arrival at the advice call.  The fix to include multiple after advice sections would take a lot of work - and given that you usually don't want to weave these things - I have not done this work.
Comment 11 Oleksandr Alesinskyy CLA 2006-10-09 11:13:54 EDT
As soon as it find its way into documentation it would be absolutely Ok.
Comment 12 Andrew Clement CLA 2007-10-25 05:27:29 EDT
check in this timeframe if cglib have resolved the problem that causes this
Comment 13 Andrew Clement CLA 2008-03-24 16:15:27 EDT
doesnt look like it as reported again on the spring list last week.
Comment 14 Oleksandr Alesinskyy CLA 2009-02-13 07:18:02 EST
The problem still overfloods Spring forum, only for yesterday and today I have seen several separate reports in Spring forums, here is one of them.

http://forum.springframework.org/showthread.php?p=226681&posted=1#post226681
Comment 15 Andrew Clement CLA 2009-02-13 23:08:17 EST
perhaps review the urgency of this as people are still hitting it - likely to be a huge amount of AspectJ work to cope with what CGLIB is doing.  I wonder if a shorter term solution would be a huge aspectj warning that comes out if it recognizes it is attempting to weave CGLIB code.
Comment 16 Ramnivas Laddad CLA 2009-02-14 08:38:31 EST
Yes, a warning when an attempt is made to weave in CGLIB classes (or, if possible, any class with unusual stack modification) will go a long way.
Comment 17 Oleksandr Alesinskyy CLA 2009-02-14 12:11:53 EST
Warning would be good, but it would be even better if the same warning would be clearly expressed in the documentation.

Another possible solutions is skip such classes (CGLIB-ed and other with unusual stack modification) by default and try to process them only if special switch is provided (e. g. in the aop.xml)
Comment 18 Andrew Clement CLA 2009-02-17 17:22:51 EST
i'm nervous about the implementation here, am I really going to check the name of every single class that goes through the weaver on the off chance it has CGLIB in the name.  I don't really want to make everyone suffer the cost for just a few types. hmmm.
Comment 19 Andrew Clement CLA 2009-02-17 17:50:24 EST
The faq entry has existed for this for a while - but is only visible in the downloaded faq included with a distribution.  The online copy of the faq has not been updated to reflect this change. I've just changed it so the online copy also describes it:

http://www.eclipse.org/aspectj/doc/released/faq.php#q:verifyError
Comment 20 Oleksandr Alesinskyy CLA 2009-02-18 03:06:04 EST
While  it is not directly related to this problem, but online FAQ still miss some at least one entry that is present in FAQ inside distribution, namely 
"10.17 How do I write synchronized advice?".

And one more remark - in both FAQs entries in chapter 12 are numbered somewhat comically (1,2,3,1,2,3) - numbers duplicate.
Comment 21 Andrew Clement CLA 2009-03-05 18:58:53 EST
> While  it is not directly related to this problem, but online FAQ still miss
> some at least one entry that is present in FAQ inside distribution, namely 
>"10.17 How do I write synchronized advice?".

faq.php (which is referenced online) is updated manually from faq.html (generated by the build process).  I have just done this update and now question 10.17 is there.

> And one more remark - in both FAQs entries in chapter 12 are numbered somewhat
> comically (1,2,3,1,2,3) - numbers duplicate.

That is because of the test missing for a header, so those numbers are correct but they need a header after the first 1,2,3 - this is now done.
Comment 22 Andrew Clement CLA 2010-03-19 19:23:20 EDT
unlikely to rework the weaving process in the required way anytime soon.  Most users seem happy with avoiding weaving CGLIB code.