[
https://issues.apache.org/jira/browse/GROOVY-11365?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17842699#comment-17842699
]
Eric Milles commented on GROOVY-11365:
--------------------------------------
In general, I think the JVM enforces that only a subclass can access a
protected member (outside of the declaring package). Dynamic mode Groovy
indexes protected members down the inheritance chain and provides a mechanism
for inner types to pass along method missing to outer types. When a method
reference is linked to an invoke dynamic call of Java's {{LambdaMetaFactory}},
the Groovy MOP is bypassed.
For your test case, "this" is translated to "getThisObject()". Then an invoke
dynamic call `java.lang.invoke.LambdaMetafactory.metafactory(???, "accept",
"(LC11365;)Ljava/util/function/Consumer;", "(Ljava/lang/Object;)V",
groovy/transform/stc/A11365.op(Ljava/lang/Object;)Ljava/lang/Object; (5),
"(Ljava/lang/Integer;)V")` is written. I think the first argument is the
Lookup from the closure class (the caller/sender).
> IllegalAccessError when using protected method as reference
> -----------------------------------------------------------
>
> Key: GROOVY-11365
> URL: https://issues.apache.org/jira/browse/GROOVY-11365
> Project: Groovy
> Issue Type: Bug
> Components: Compiler
> Affects Versions: 4.0.18, 5.0.0-alpha-8, 4.0.21
> Reporter: Christopher Smith
> Assignee: Eric Milles
> Priority: Critical
>
> I will try to repro this, but posting in case the description is sufficient
> to identify the problem:
> I have an abstract base class {{AbstractServiceImpl<E extends Entity>}} that
> defines {{protected final E upsert(E entity)}}. From a subclass inside a
> closure, I try to use {{this::upsert}} as a {{Consumer<DocumentRequest>}}.
> Starting somewhere between 4.0.14 and 4.0.18 (other bugs prevent me from
> bisecting further), an {{IllegalAccessError}} gets introduced at runtime:
> {code}
> java.lang.IllegalAccessError: class
> com.example.doc.DocumentRequestServiceImpl$_openUpload_closure2 tried to
> access protected method 'com.example.base.Entity
> com.example.base.AbstractServiceImpl.upsert(com.example.base.Entity)'
> (com.example.doc.DocumentRequestServiceImpl$_openUpload_closure2 and
> com.example.base.AbstractServiceImpl are in unnamed module of loader 'app')
> {code}
> I've examined the bytecode for both the call site and the method
> implementation, and I can't see a difference in the code generated between
> 4.0.14 and 4.0.18/21. I'm not certain why it works in 4.0.14, but with javac
> I would expect to see a lambda bridge to allow the lambda to access the
> containing-class-visible-but-only-by-inheritance protected method.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)