Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
4.0.1
-
None
Description
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
interface E extends B { default <R extends Record> Table<R> tableForRecord(R record) { this.stuff(r) } }
Because of Groovy internals, this is implemented as a trait. I now have
class EImpl extends BImpl implements E { EImpl(DynamoDbClient c) { super(c) } }
Instantiating EImpl now fails with a MissingMethodException inside ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:72):
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)]
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.
Attachments
Issue Links
- is related to
-
GROOVY-2433 Closure in base class unable to call private methods when invoked from derived class
- Closed
-
GROOVY-5051 'this' uses in a superclass is treated as subclass, preventing acces to private members
- Closed