[ 
https://issues.apache.org/jira/browse/GROOVY-11982?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18077859#comment-18077859
 ] 

ASF GitHub Bot commented on GROOVY-11982:
-----------------------------------------

paulk-asert opened a new pull request, #2507:
URL: https://github.com/apache/groovy/pull/2507

   …ngeError under indy=false




> 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
>
> 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)

Reply via email to