You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Eric Milles (Jira)" <ji...@apache.org> on 2023/07/14 16:53:00 UTC
[jira] [Commented] (GROOVY-10568) MissingMethodException using method-pointer operator in superclass
[ https://issues.apache.org/jira/browse/GROOVY-10568?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17743234#comment-17743234 ]
Eric Milles commented on GROOVY-10568:
--------------------------------------
You can use a combination of the declaring class and curry for a workaround since Groovy 3:
{code:groovy}
Caffeine.newBuilder().build(BImpl.&getOrCreateTable.curry(this))
{code}
> MissingMethodException using method-pointer operator in superclass
> ------------------------------------------------------------------
>
> Key: GROOVY-10568
> URL: https://issues.apache.org/jira/browse/GROOVY-10568
> Project: Groovy
> Issue Type: Bug
> Components: Compiler, Static compilation
> Affects Versions: 4.0.1
> Reporter: Christopher Smith
> Priority: Major
>
> I'm working on teasing out the minimal effect here, but this is my setup:
> - Base service interface {{B}}.
> - Core concrete implementation {{BImpl implements B}}. This implementation includes a private method {{Table<T> getOrCreateTable(TableKey<T>)}} and a Caffeine cache defined as {{Caffeine.newBuilder().build(this.&getOrCreateTable)}}.
> This worked fine. However, in a particular project, I want to extend {{B}}. For Reasons™, the extensions are implementable just fine as default methods, so I have
> {code}
> interface E extends B {
> default <R extends Record> Table<R> tableForRecord(R record) {
> this.stuff(r)
> }
> }
> {code}
> Because of Groovy internals, this is implemented as a _trait_. I now have
> {code}
> class EImpl extends BImpl implements E {
> EImpl(DynamoDbClient c) {
> super(c)
> }
> }
> {code}
> Instantiating {{EImpl}} now fails with a {{MissingMethodException}} inside {{ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:72)}}:
> {code}
> groovy.lang.MissingMethodException: No signature of method: com.example.EImpl.getOrCreateTable() is applicable for argument types: (com.example.BImpl$TableKey) values: [com.example.BImpl$TableKey(flow_preference, software.amazon.awssdk.enhanced.dynamodb.mapper.BeanTableSchema@427946b9)]
> {code}
> I _think_ what's happening is that since the Groovy compiler doesn't support real method closures, it's delegating the implementation duties of {{.&}} to a reflection routine that is tripping on either the private super method or the private type; I'm inclined to guess the method since the functionality works correctly with a single type. Changing the access modifier on {{B.getOrCreateTable(TableKey)}} to protected seems to fix it, but the base class should be able to access its own private members.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)