[jboss-jira] [JBoss JIRA] (JASSIST-250) Javassist gets confused by certain synthetic bridges, produces invalid bytecode

Jari Juslin (JIRA) issues at jboss.org
Mon Aug 24 04:15:29 EDT 2015


Jari Juslin created JASSIST-250:
-----------------------------------

             Summary: Javassist gets confused by certain synthetic bridges, produces invalid bytecode
                 Key: JASSIST-250
                 URL: https://issues.jboss.org/browse/JASSIST-250
             Project: Javassist
          Issue Type: Bug
    Affects Versions: 3.20.0-GA
         Environment: Ubuntu 15.04, JDK 1.8.0_51. 
            Reporter: Jari Juslin
            Assignee: Shigeru Chiba
         Attachments: Bar.java, BaseFoo.java, Foo.java, IBarProvider.java, IExpirationProvider.java, JavassistSyntheticBridgeTest.java

Javassist gets confused by synthetic bridge methods javac has implicitly created and then creates method calls to the bytecode that don't pass the JVM  verify stage.

The situation here is that we have a class Foo, that has superclass BaseFoo implementing an interface IBarProvider. BaseFoo has method Bar getBar(), which is also in the IBarProvider. The IBarProvider defines the method as IExpirationProvider getBar(), where IExpirationProvider is an interface implemented by Bar.

Now, for some reason I am not completely sure about, javac creates a synthetic bridge method to Foo class with erasure of IExpirationProvider getBar which then just passes the call to the Bar BaseFoo.getBar. When Javassist load the class, it misses the fact that the superclass contains method with same name and wider return scope and instead calls the Foo level method also in cases where Bar is needed, not just IExpirationProvider. If it just ignored the synthetic bridge methods altogether, this would work as expected and as Oracle javac handles it.

The resulting error:

Exception in thread "main" java.lang.VerifyError: Bad return type
Exception Details:
  Location:
    InstrumentedClass.getBar()LBar; @4: areturn
  Reason:
    Type 'IExpirationProvider' (current frame, stack[0]) is not assignable to 'Bar' (from method signature)
  Current Frame:
    bci: @4
    flags: { }
    locals: { 'InstrumentedClass' }
    stack: { 'IExpirationProvider' }
  Bytecode:
    0x0000000: 2ab7 000b b0                           

	at java.lang.Class.getDeclaredConstructors0(Native Method)
	at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
	at java.lang.Class.getConstructor0(Class.java:3075)
	at java.lang.Class.getConstructor(Class.java:1825)
	at JavassistSyntheticBridgeTest.main(JavassistSyntheticBridgeTest.java:19)




--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


More information about the jboss-jira mailing list