[ 
https://issues.apache.org/jira/browse/OPENJPA-2298?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Albert Lee updated OPENJPA-2298:
--------------------------------

    Fix Version/s: 2.2.1.1
                   2.2.2
                   2.3.0
    
> VerifyError/Stack underflow due to extra 'return' statements generated by 
> PCEnhancer.
> -------------------------------------------------------------------------------------
>
>                 Key: OPENJPA-2298
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-2298
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: Enhance, instrumentation
>    Affects Versions: 2.2.0, 2.3.0
>            Reporter: Heath Thomann
>            Assignee: Heath Thomann
>            Priority: Critical
>             Fix For: 2.3.0, 2.2.2, 2.2.1.1
>
>         Attachments: PersistentTimerStatsJPA.java, 
> PersistentTimerStatsPK.java, VerifyError.patch
>
>
> I've been assisting Kevin Sutter with a 'VerifyError' and am opening this 
> JIRA on his behalf.  He has discovered a situation where the following 
> VerifyError occurs:
> Exception data: java.lang.VerifyError: JVMVRFY036 stack underflow; 
> class=irwwbase/PersistentTimerStatsJPA, 
> method=pcNewObjectIdInstance(Ljava/lang/Object;)Ljava/lang/Object;, pc=26
>     at java.lang.J9VMInternals.verifyImpl(Native Method)
>     at java.lang.J9VMInternals.verify(J9VMInternals.java:85)
>     at java.lang.J9VMInternals.initialize(J9VMInternals.java:162)
>     at java.lang.Class.forNameImpl(Native Method)
>     at java.lang.Class.forName(Class.java:176)
>     at 
> org.apache.openjpa.meta.MetaDataRepository.classForName(MetaDataRepository.java:1552)
>     at 
> org.apache.openjpa.meta.MetaDataRepository.loadPersistentTypesInternal(MetaDataRepository.java:1528)
>     at 
> org.apache.openjpa.meta.MetaDataRepository.loadPersistentTypes(MetaDataRepository.java:1506)
>     at 
> org.apache.openjpa.kernel.AbstractBrokerFactory.loadPersistentTypes(AbstractBrokerFactory.java:282)
>     at 
> org.apache.openjpa.kernel.AbstractBrokerFactory.initializeBroker(AbstractBrokerFactory.java:238)
>     at 
> org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:212)
>     at 
> org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:156)
>     at 
> org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:227)
>     ...........
> This issue occurs on, and is unique to, Java 7 and our enhancement code (as 
> well as the entity definition).  That is, in PCEnhancer we are generating 
> extra 'returns' in methods which throw an exception.  This has an effect on 
> ASM post-processing needed on Java 7 which ultimately causes the VerifyError. 
>  This description probably makes no sense without more details and code to go 
> along with it.  So let me now show how this looks in code.  First, I'm 
> attaching an entity, named PersistentTimerStatsJPA.java, and a PK class named 
> 'PersistentTimerStatsPK.java'.  While I won't go into exact details on how to 
> use these classes to recreate the issue, I am providing them for the reader's 
> reference.
> Next, lets look at enhanced code before ASM post-processing occurs.  Take 
> this code:
>   public java.lang.Object pcNewObjectIdInstance(java.lang.Object);
>     flags: ACC_PUBLIC
>     Code:
>       stack=3, locals=2, args_size=2
>          0: new           #207                // class 
> java/lang/IllegalArgumentException
>          3: dup           
>          4: ldc_w         #367                // String The id type \"class 
> irwwbase.PersistentTimerStatsPK\" specified by persistent type \"class 
> irwwbase.PersistentTimerStatsJPA\" does not have a public class 
> irwwbase.PersistentTimerStatsPK(String) or class 
> irwwbase.PersistentTimerStatsPK(Class, String) constructor.
>          7: invokespecial #368                // Method 
> java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
>         10: athrow        
>         11: return        
> As you can see, we have a "10: athrow" and "11: return".  This extraneous 
> "11: return" hasn't caused problems in the past, but as will be explained in 
> more details below, with ASM post-processing necessary in Java 7, this "11: 
> return" causes problems.  To see this, lets look at the code above after 
> going through ASM post-processing:
>   public java.lang.Object pcNewObjectIdInstance(java.lang.Object);
>     flags: ACC_PUBLIC
>     Code:
>       stack=3, locals=2, args_size=2
>          0: new           #205                // class 
> java/lang/IllegalArgumentException
>          3: dup           
>          4: ldc_w         #363                // String The id type \"class 
> irwwbase.PersistentTimerStatsPK\" specified by persistent type \"class 
> irwwbase.PersistentTimerStatsJPA\" does not have a public class 
> irwwbase.PersistentTimerStatsPK(String) or class 
> irwwbase.PersistentTimerStatsPK(Class, String) constructor.
>          7: invokespecial #364                // Method 
> java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
>         10: athrow        
>         11: athrow        
>       StackMapTable: number_of_entries = 1
>            frame_type = 255 /* full_frame */
>           offset_delta = 11
>           locals = []
>           stack = [ class java/lang/Throwable ]
> Notice that the "11: return" was changed to a second "11: athrow".  To tie 
> this all together, let me blatantly copy/paste a detailed description sent to 
> me by Kevin: 
> "When JPA was attempting to generate the bytecodes for throwing an exception, 
> we were accidentally including a return bytecode as well.  Of course, in a 
> normal Java environment, this would have been flagged since the return would 
> have been unreachable code.  But, since we were generating the bytecodes 
> during enhancement, nothing is going to flag this situation.  But, due to the 
> Java 7 class validation that is now being performed, we had to introduce the 
> ASM post-processing.  Normally, these simple enhanced methods would not have 
> been touched by ASM.  But, since these methods now had multiple exit points 
> (due to the throw and return bytecodes), these methods were being flagged as 
> "complicated" and needed Stack Map table adjustments performed by ASM.  
> Unfortunately, this additional ASM code now introduced the situation where 
> too many items would have been popped off the stack (if the code could have 
> actually executed as coded).  This is the Stack Underflow exception that was 
> happening during Class load time."
> Basically, Kevin's fix was to find all of the areas where we generate a 
> "throw" followed by a "return", and remove the "return".  Since this method 
> is only attempting to throw an exception, we really don't need the second 
> "return" instruction.  I'm providing Kevin's patch, which is named 
> 'VerifyError.patch'.
> Thanks,
> Heath

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to