Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-7549

java.lang.IllegalAccessError occurs when attempting to run code built with CompileStatic

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • 2.4.4
    • 4.0.0-alpha-1, 2.4.20, 3.0.5, 2.5.13
    • None
    • None

    Description

      Given a small code setup such as the following, where there exists a

      1. A publicly declared interface
      2. A package private implementation of the interface
      3. A static factory class that returns an instance of the implementation as the implementation class
      packa.TheInterface.groovy
      package packa
      public interface TheInterface {
          public void doStuff()
      }
      
      packb.TheImplementation.groovy
      package packb
      import packa.TheInterface
      @groovy.transform.CompileStatic
      @groovy.transform.PackageScope
      class TheImplementation implements TheInterface {
          public void doStuff() {
              System.out.println("Do some stuff")
          }
      }
      
      packb.TheFactory.groovy
      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.

      packa.TheMain.groovy
      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

      Attachments

        Activity

          People

            emilles Eric Milles
            steven.walters@icidigital.com Steven Walters
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0h
                0h
                Logged:
                Time Spent - 1h
                1h