[jboss-jira] [JBoss JIRA] (JASSIST-250) Javassist gets confused by certain synthetic bridges, produces invalid bytecode
Shigeru Chiba (JIRA)
issues at jboss.org
Tue Feb 23 11:59:00 EST 2016
[ https://issues.jboss.org/browse/JASSIST-250?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Shigeru Chiba resolved JASSIST-250.
-----------------------------------
Fix Version/s: 3.21.0-GA
Resolution: Done
> 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
> Fix For: 3.21.0-GA
>
> 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.4.11#64026)
More information about the jboss-jira
mailing list