Repository navigation
GROOVY-12718: use a package-private field of another run-time package through the meta-class in dynamic code - #3252
codeconsole wants to merge 6 commits into
Conversation
… through the meta-class in dynamic code In dynamic and @TypeChecked code, super.f, super.@f and this.@f of a package-private field of a superclass with the same package name compile to a direct field access. For a superclass of another run-time package, such as a class of an earlier parse of the same GroovyShell, the JVM refuses that with IllegalAccessError, although a plain f or this.f reaches the field through the meta-class. These forms now do the same for such a field. Static compilation does not select a member at run time, so it is unchanged.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #3252 +/- ##
==================================================
+ Coverage 74.4524% 74.4595% +0.0071%
- Complexity 44845 44852 +7
==================================================
Files 1702 1702
Lines 151995 151998 +3
Branches 29122 29124 +2
==================================================
+ Hits 113164 113177 +13
+ Misses 28422 28410 -12
- Partials 10409 10411 +2
🚀 New features to boost your workflow:
|
daniellansun
left a comment
There was a problem hiding this comment.
Correct fix for GROOVY-12718.
Package name equality is not run-time package equality (package + ClassLoader). Dynamic / @TypeChecked code that wrote GETFIELD/PUTFIELD for a package-private superclass field from another GCL parse therefore hit IllegalAccessError, while plain f / this.f already went through the meta-class. Routing such access through the meta-class via isDynamicAccessOfAnotherRuntimePackage (and skipping the rewrite under StaticInvocationWriter) matches the JVM rule and leaves SC unchanged — as #3097 reports there.
DynamicFieldOfAnotherRuntimePackageTest covers reads/writes, attribute forms, closures, protected-still-direct, same-compilation-still-direct, and SC still throwing IllegalAccessError — good matrix.
Please before approve:
- CI:
lts (17, ubuntu-latest)failed on:groovy-dateutil:testwithCould not read path '.../resolved-caller-all-caller-working69.xml'— grape/cache infra, unrelated toAsmClassGenerator. Windows/macOS and the other Ubuntu LTS cells are green; please re-run that cell.
Happy to APPROVE once Ubuntu is re-run green (or confirmed flake). Depends conceptually on the runtime-package helpers from #3097.
|
@daniellansun I can't re-run jobs on apache/groovy, so I merged current master (492ae79) to get a fresh run. |
As CONTRIBUTING asks for a standalone regression test class, it is bugs.Groovy12718.
The two tests compiled with a plain CompilationUnit, whose classes are not defined in memory, so every class is in the same run-time package there and the tests could not tell what they are named for. They now compile with a GroovyClassLoader, as a GroovyShell does: the protected field is of a superclass of an earlier compilation, and the package-private field is of the same in-memory compilation.
GroovyShell turns on the compile-time check of the run-time package that GROOVY-12568 adds, which reports this access before it runs. The test compiles with a GroovyClassLoader of its own instead, so it shows the unchanged IllegalAccessError whether or not that check is present.
…time-package # Conflicts: # src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
🚨 All tests passed but jobs failed 🚨Failed Jobs without Test Failures🏷️ Commit: 074d51e Rerun ControlsClick the checkbox to trigger a rerun:
Learn more about TestLens at testlens.app/docs. |
In dynamic and
@TypeCheckedcode, a package-private field of a superclass with the same package name but of another class loader, such as a class of an earlier parse of the sameGroovyShell, is reached through the meta-class byfandthis.f. The forms that go directly to the field fail:4.0.32, 5.0.8 and 6.0.0 fail the same way.
AsmClassGenerator.visitPropertyExpressionandvisitAttributeExpressiondecide by the package name and writeGETFIELDorPUTFIELD. They now leave such a field to the meta-class in dynamic code, usingisInSameRuntimePackage, which only knows the case for an in-memory compilation of aGroovyClassLoader.Static compilation is unchanged: it does not select a member at run time. #3097 (GROOVY-12568) reports such an access there. A protected field, which a subclass can use directly, and a field of the same compilation are still accessed directly.
This and #3097 add an import next to each other in
AsmClassGenerator; whichever lands second keeps both.Compatibility
Code that failed with
IllegalAccessErrornow works.Tests
bugs.Groovy12718:testReadOfPackagePrivateFieldOfSuperclassandtestWriteOfPackagePrivateFieldOfSuperclass, each dynamic and@TypeChecked, fail without the change. The other tests pin what must not change: closures, a protected field and a field of the same compilation stay as they are, and static compilation still fails at run time without #3097. Theorg.codehaus.groovy.classgen.asm.sc,groovy.transform.stcandglstests pass, apart from the twotestSelfReferentialTypeParameter5tests, whose@Grabof netty did not resolve on my network. The Checkstyle and CodeNarc gates pass.