Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
2.1.7
-
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)