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

Reply via email to