Skip to content

GROOVY-12223: Introduce hidden class support - #2755

Open
daniellansun wants to merge 1 commit into
masterfrom
GROOVY-12223
Open

GROOVY-12223: Introduce hidden class support#2755
daniellansun wants to merge 1 commit into
masterfrom
GROOVY-12223

Conversation

@daniellansun

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.

Benchmark suite Current: 58063be Previous: 544c016 Ratio
org.apache.groovy.bench.AryBench.java ( {"n":"1000"} ) 0.11873074707054951 ms/op 0.059375013802723364 ms/op 2.00

This comment was automatically generated by workflow using github-action-benchmark.

@codecov-commenter

codecov-commenter commented Aug 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.34807% with 41 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.0142%. Comparing base (b67fc73) to head (58063be).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
...codehaus/groovy/runtime/ProxyGeneratorAdapter.java 78.4810% 5 Missing and 12 partials ⚠️
...haus/groovy/runtime/metaclass/ReflectorLoader.java 55.5556% 9 Missing and 3 partials ⚠️
...ava/org/apache/groovy/util/HiddenClassDefiner.java 87.0370% 4 Missing and 3 partials ⚠️
...roovy/reflection/ClassLoaderForClassArtifacts.java 76.1905% 1 Missing and 4 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                 @@
##               master      #2755        +/-   ##
==================================================
+ Coverage     69.9742%   70.0142%   +0.0399%     
- Complexity      35502      35575        +73     
==================================================
  Files            1557       1558         +1     
  Lines          131667     131799       +132     
  Branches        24166      24200        +34     
==================================================
+ Hits            92133      92278       +145     
+ Misses          31193      31164        -29     
- Partials         8341       8357        +16     
Files with missing lines Coverage Δ
...roovy/reflection/ClassLoaderForClassArtifacts.java 79.3103% <76.1905%> (+4.3103%) ⬆️
...ava/org/apache/groovy/util/HiddenClassDefiner.java 87.0370% <87.0370%> (ø)
...haus/groovy/runtime/metaclass/ReflectorLoader.java 60.4167% <55.5556%> (+60.4167%) ⬆️
...codehaus/groovy/runtime/ProxyGeneratorAdapter.java 88.3459% <78.4810%> (-1.5029%) ⬇️

... and 8 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

JMH summary — classic (commit 2a8d895)

Speedup vs trailing 90-day baseline on gh-pages. Higher = faster.
1.00 = in line with history. Per-benchmark ratio, geomean within group.
Time-per-op units inverted so direction is consistent. The calibrated
column divides out this runner's speed vs the baseline hardware, as
measured by Groovy-independent pure-Java ruler benchmarks.

Group Speedup Calibrated n
bench 0.993 × 0.987 × 99
core 0.995 × 0.888 × 83
grails 0.865 × 0.829 × 80

Runner calibration (this run vs baseline hardware): bench 1.00× (26 rulers) · core-ag 1.12× (3 rulers) · core-hz 1.12× (3 rulers) · grails-ad 1.12× (3 rulers) · grails-ez 0.99× (3 rulers)

Baseline: dev/bench/jmh/<part>/classic/data.js on gh-pages, trailing 90 days. Daily dashboard · Per-suite raw data

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

JMH summary — indy (commit 2a8d895)

Speedup vs trailing 90-day baseline on gh-pages. Higher = faster.
1.00 = in line with history. Per-benchmark ratio, geomean within group.
Time-per-op units inverted so direction is consistent. The calibrated
column divides out this runner's speed vs the baseline hardware, as
measured by Groovy-independent pure-Java ruler benchmarks.

Group Speedup Calibrated n
bench 0.971 × 0.990 × 99
core 3.061 × 3.107 × 83
grails 4.350 × 4.220 × 80

Runner calibration (this run vs baseline hardware): bench 0.98× (26 rulers) · core-ag 0.99× (3 rulers) · core-hz 0.98× (3 rulers) · grails-ad 1.13× (3 rulers) · grails-ez 0.96× (3 rulers)

Baseline: dev/bench/jmh/<part>/indy/data.js on gh-pages, trailing 90 days. Daily dashboard · Per-suite raw data

@blackdrag blackdrag left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • HiddenClassDefiner contains method used only in tests
  • ProxyGeneratorAdapter and ReflectorLoader seems to duplicate work already done in HiddenClassDefiner, while still using HiddenClassDefiner

But the big point for me is MethodHandles.lookup(). It has the javadoc:

Returns a lookup object with full capabilities to emulate all supported bytecode behaviors of the caller. These capabilities include full privilege access to the caller. Factory methods on the lookup object can create direct method handles for any member that the caller has access to via bytecodes, including protected and private fields and methods. This lookup object is created by the original lookup class and has the ORIGINAL bit set. This lookup object is a capability which may be delegated to trusted agents. Do not store it in place where untrusted code can access it.

This method is caller sensitive, which means that it may return different values to different callers. In cases where MethodHandles.lookup is called from a context where there is no caller frame on the stack (e.g. when called directly from a JNI attached thread), IllegalCallerException is thrown. To obtain a lookup object in such a context, use an auxiliary class that will implicitly be identified as the caller, or use publicLookup() to obtain a low-privileged lookup instead.

So if I create a Lookup for HiddenClassDefinerTest in HiddenClassDefinerTest I will get full access. But if I create that in the same class for java.lang.String, I will not get full access. In practice this usually means that unless the class creates the lookup (for example during invokedynamic) it is useless for many things. So if you need private module access, then MethodHandles.lookup() is most likely not the way to go.
Which means I don`t think that the intend of HiddenClassDefiner.privateLookupIn and usuability go hand in hand here.

@sonarqubecloud

sonarqubecloud Bot commented Aug 2, 2026

Copy link
Copy Markdown

@testlens-app

testlens-app Bot commented Aug 2, 2026

Copy link
Copy Markdown

✅ All tests passed ✅

🏷️ Commit: 58063be
▶️ Tests: 108769 executed
⚪️ Checks: 31/31 completed


Learn more about TestLens at testlens.app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants