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

Inner classes in Groovy should have the same access modifiers as in Java

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 2.1.7
    • Fix Version/s: 2.1.8
    • Component/s: bytecode, class generator
    • Labels:
      None

      Description

      There are differences in the flags/access modifiers for inner classes between Java and Groovy.

      Java code:

      public class Java {
                    class InnerPackage { }
          public    class InnerPublic { }
          protected class InnerProtected { }
          private   class InnerPrivate { }
      }
      

      Groovy code:

      import groovy.transform.PackageScope
      
      class Groovy {
          @PackageScope class InnerPackage { }
          public        class InnerPublic { }
          protected     class InnerProtected { }
          private       class InnerPrivate { }
      }
      

      Flags for inner classes (extracted via javap):

        package scope public scope protected scope private scope
      Java ACC_SUPER ACC_SUPER, ACC_PUBLIC ACC_SUPER, ACC_PUBLIC ACC_SUPER
      Groovy ACC_SUPER ACC_SUPER, ACC_PUBLIC ACC_SUPER, 0x4 (means ACC_PROTECTED) ACC_SUPER, 0x2 (means ACC_PRIVATE)

      Comment from blackdrag:

      I think as Groovy does is correct. But we did learn only recently, that
      the VMs have trouble doing it like this. AS a result we forbid the
      private modifer on classes... but looks like we forgot inner classes.

      These different flags for example result in Cobertura failing to instrument the inner classes because ASM throws this exception:

      Unable to instrument file build/instrumented_classes/Groovy$InnerPrivate.class
      java.lang.IllegalArgumentException: Invalid access flags: 34
              at org.objectweb.asm.util.CheckClassAdapter.checkAccess(Unknown Source)
              at org.objectweb.asm.util.CheckClassAdapter.visit(Unknown Source)
              at org.objectweb.asm.ClassVisitor.visit(Unknown Source)
              at net.sourceforge.cobertura.instrument.pass1.DetectDuplicatedCodeClassVisitor.visit(DetectDuplicatedCodeClassVisitor.java:205)
              at org.objectweb.asm.ClassReader.accept(Unknown Source)
              at org.objectweb.asm.ClassReader.accept(Unknown Source)
              at net.sourceforge.cobertura.instrument.CoberturaInstrumenter.instrumentClass(CoberturaInstrumenter.java:153)
              at net.sourceforge.cobertura.instrument.CoberturaInstrumenter.instrumentClass(CoberturaInstrumenter.java:121)
              at net.sourceforge.cobertura.instrument.CoberturaInstrumenter.addInstrumentationToSingleClass(CoberturaInstrumenter.java:234)
              at net.sourceforge.cobertura.instrument.Main.addInstrumentationToSingleClass(Main.java:298)
              at net.sourceforge.cobertura.instrument.Main.addInstrumentation(Main.java:307)
              at net.sourceforge.cobertura.instrument.Main.addInstrumentation(Main.java:316)
              at net.sourceforge.cobertura.instrument.Main.parseArguments(Main.java:399)
              at net.sourceforge.cobertura.instrument.Main.main(Main.java:421)
              at net.saliman.gradle.plugin.cobertura.CoberturaRunner.instrument(CoberturaRunner.java:79)
      

        Attachments

          Activity

            People

            • Assignee:
              melix C├ędric Champeau
              Reporter:
              rene.scheibe Rene Scheibe
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: