Details
-
Bug
-
Status: Closed
-
Minor
-
Resolution: Fixed
-
2.4.4
-
None
-
None
Description
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
package packa public interface TheInterface { public void doStuff() }
package packb import packa.TheInterface @groovy.transform.CompileStatic @groovy.transform.PackageScope class TheImplementation implements TheInterface { public void doStuff() { System.out.println("Do some stuff") } }
package packb public class TheFactory { static TheImplementation getAnInstance() { return new TheImplementation() } }
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.
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() } }
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