[
https://issues.apache.org/jira/browse/GROOVY-11982?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Paul King updated GROOVY-11982:
-------------------------------
Fix Version/s: 5.0.6
> Default methods in interface throw IncompatibleClassChangeError under
> indy=false
> --------------------------------------------------------------------------------
>
> Key: GROOVY-11982
> URL: https://issues.apache.org/jira/browse/GROOVY-11982
> Project: Groovy
> Issue Type: Bug
> Reporter: Paul King
> Assignee: Paul King
> Priority: Major
> Fix For: 6.0.0-alpha-1, 5.0.6
>
>
> A Groovy interface with default methods whose bodies use dynamic Groovy
> features (e.g. GString interpolation) fails at runtime with
> {{IncompatibleClassChangeError}} when compiled with {{indy=false}}.
> h3. Symptom
> {noformat}
> java.lang.IncompatibleClassChangeError: Method
> 'org.codehaus.groovy.runtime.callsite.CallSite[]
> IConfig.$getCallSiteArray()'
> must be InterfaceMethodref constant
> at IConfig.getDescription(IConfig.groovy)
> {noformat}
> h3. Reproducer
> {code:groovy}
> interface IConfig {
> String getName()
> default String getDescription() { "config[name=${getName()}]" }
> }
> class ConfigImpl implements IConfig { String getName() { 'impl' } }
> new ConfigImpl().description // throws under indy=false
> {code}
> Compile with {{-Dgroovy.target.indy=false}} and invoke any default method.
> h3. Root cause
> {{CallSiteWriter.makeSiteEntry()}} emits {{INVOKESTATIC
> <interface>.$getCallSiteArray}} as a {{CONSTANT_Methodref_info}} entry. JVMS
> §5.4.3.3 requires {{CONSTANT_InterfaceMethodref_info}} when the owner is an
> interface, so resolution throws {{IncompatibleClassChangeError}}.
> * {{CallSiteWriter.java:118}} uses {{controller.getInternalClassName()}} with
> {{isInterface=false}} instead of redirecting to the
> {{InterfaceHelperClassNode}} (cf. {{prepareCallSite()}} at line 233 which
> uses {{controller.getClassName()}}).
> * {{AsmClassGenerator.createInterfaceSyntheticStaticFields()}} only
> materialises the helper inner class when {{referencedClasses}} is non-empty,
> so an interface with call sites but no class literals has no helper to
> redirect to.
> h3. Workaround
> Convert the interface to a {{trait}} — trait helper bodies live in a regular
> {{$Trait$Helper}} class where {{Methodref}} encoding is valid. Or compile
> with {{indy=true}} ({{IndyCallSiteWriter.makeSiteEntry()}} is a no-op).
--
This message was sent by Atlassian Jira
(v8.20.10#820010)