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

Eric Milles commented on GROOVY-11929:
--------------------------------------

In order for "super.save(entity)" to call through to "save(T)" from 
AbstractDao, a MOP method {{super$2$save(Object)}} is created in EntityDaoImpl 
-- this is where the INVOKESPECIAL instruction is.

The extra abstract method "Entity save(Entity)" from EntityDao adds an extra 
method to the super method index.  And this method is not replaced by 
{{super$2$save(Object)}} because of the parameter type difference.

If I comment out the abstract method from EntityDao, the index for super only 
has {{super$2$save(Object)}} left in it and this is matched by the call site.

> Generic type information erased for super call
> ----------------------------------------------
>
>                 Key: GROOVY-11929
>                 URL: https://issues.apache.org/jira/browse/GROOVY-11929
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 5.0.5
>         Environment: Groovy 5.0.5, groovy-eclipse-compiler 3.9.1, 
> groovy-eclipse-batch 5.0.5-01, JDK 21, macOS 26
>            Reporter: Tommi Ratamaa
>            Assignee: Eric Milles
>            Priority: Major
>
> MissingMethodException runtime exception from dynamic invocation when calling 
> super method with parameter type bound by interface and base class generic 
> type.
> Simplified code example (in real case classes and interfaces are not inner 
> but that does not matter) that used to work with Groovy 3, Groovy 4 and also 
> works as Java code with JDK21 or with @CompileStatic, but fails to bind to 
> super method on runtime when compiled with Groovy 5 using dynamic invocation:
> {code:java}
> class GroovyBug {
>     static interface Dao<T> {
>         T save(T entity)
>     }
>     static abstract class AbstractDao<T> implements Dao<T> {
>         T save(T entity) {
>             return entity
>         }
>     }
>     static interface EntityDao extends Dao<Entity> {
>         @Override
>         Entity save(Entity entity)
>     }
>     static class EntityDaoImpl extends AbstractDao<Entity> implements 
> EntityDao {
>         @Override
>         //@CompileStatic // would fix it
>         Entity save(Entity entity) {
>             //return super.save((Object) entity) // would fix it
>             return super.save(entity)
>         }
>     }
>     static class Entity {
>         long id
>     }
>     static void main(String[] args) {
>         new EntityDaoImpl().save(new Entity())
>         /* Exception from save ^ call:
>             groovy.lang.MissingMethodException: No signature of method: save 
> for class: GroovyBug$EntityDaoImpl is applicable for argument types: 
> (GroovyBug$Entity) values: [GroovyBug$Entity@1c05a54d]
>              Possible solutions: save(GroovyBug2$Entity), 
> save(java.lang.Object), save(java.lang.Object), wait(), any(), wait(long)
>              at GroovyBug$EntityDaoImpl.methodMissing(GroovyBug.groovy)
>              at GroovyBug$EntityDaoImpl.save(GroovyBug.groovy:24)
>              at GroovyBug.main(GroovyBug.groovy:33)
>          */
>     }
> }{code}
> The generic type information provided for the implemented interface/base 
> class is erased and argument would need to be casted to Object (as 
> save(java.lang.Object) in possible solutions suggests).
> Also removing the overridden declaration from interface would solve it.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to