Steven Walters created GROOVY-7549:
--------------------------------------

             Summary: 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)

Reply via email to