[ https://issues.apache.org/jira/browse/GROOVY-7549?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14744778#comment-14744778 ]
Shil Sinha commented on GROOVY-7549: ------------------------------------ The underlying issue, I think, is that `if1.doStuff()` results in an invokeVirtual instruction when compiled with @CompileStatic, rather than an invokeInterface instruction (which is what the equivalent java code would yield). This appears to be a result of the way direct method call targets are chosen; the inferred type of a receiver is 'preferred' to the declared type of the accessed variable, causing TheImplementation.doStuff() to be chosen over TheInterface.doStuff(). > java.lang.IllegalAccessError occurs when attempting to run code built with > CompileStatic > ---------------------------------------------------------------------------------------- > > Key: GROOVY-7549 > URL: https://issues.apache.org/jira/browse/GROOVY-7549 > Project: Groovy > Issue Type: Bug > Affects Versions: 2.4.4 > Reporter: Steven Walters > Priority: Minor > > Given a small code setup such as the following, where there exists a > # A publicly declared interface > # A package private implementation of the interface > # A static factory class that returns an instance of the implementation *as > the implementation class* > {code:title=packa.TheInterface.groovy|borderStyle=solid} > package packa > public interface TheInterface { > public void doStuff() > } > {code} > {code:title=packb.TheImplementation.groovy|borderStyle=solid} > package packb > import packa.TheInterface > @groovy.transform.CompileStatic > @groovy.transform.PackageScope > class TheImplementation implements TheInterface { > public void doStuff() { > System.out.println("Do some stuff") > } > } > {code} > {code:title=packb.TheFactory.groovy|borderStyle=solid} > package packb > public class TheFactory { > static TheImplementation getAnInstance() { > return new TheImplementation() > } > } > {code} > With CompileStatic, calling the factory method successfully works, but > calling any method on the returned object fails with > {{java.lang.IllegalAccessError}}. > When CompileStatic is removed, the code runs without issue. > Such as the following. > {code:title=packa.TheMain.groovy|borderStyle=solid} > package packa > import packb.TheFactory > @groovy.transform.CompileStatic > public class TheMain { > public static void main(String[] args) { > TheInterface if1 = TheFactory.anInstance > /* the following only fails when CompileStatic is enabled with the > following error: > * Exception in thread "main" java.lang.IllegalAccessError: tried to > access class packb.TheImplementation from class packa.TheMain */ > if1.doStuff() > } > } > {code} > There seem to be some interesting factors here, as changing the > {{TheFactory}} to return {{TheInterface}} instead of {{TheImplemenation}} > also seems to resolve the issue. > However, changing the return of the {{TheFactory}} is not desirable, as in > the actual production the above sample was formulated from, there are other > classes in the {{packb}} package that utilize {{TheFactory}} and should not > require class casts from {{TheInterface}} to {{TheImplementation}} -- This message was sent by Atlassian JIRA (v6.3.4#6332)