[ 
https://issues.apache.org/jira/browse/GROOVY-12223?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18101426#comment-18101426
 ] 

ASF GitHub Bot commented on GROOVY-12223:
-----------------------------------------

testlens-app[bot] commented on PR #2755:
URL: https://github.com/apache/groovy/pull/2755#issuecomment-5168723887

   ## 🚨 TestLens detected 3 failed tests 🚨
   
   Here is what you can do:
   
   1) Inspect the test failures carefully.
   2) If you are convinced that some of the tests are flaky, you can mute them 
below.
   3) Finally, trigger a rerun by checking the rerun checkbox.
   
   ### Test Summary
   
   #### [Build and test / lts \(17, 
macos-latest\)](https://github.com/apache/groovy/actions/runs/30829307455/job/91738939007?pr=2755)
 > :test
   
   | Test | Runs | Flakiness |
   |---|---|--:|
   | IntegrationTest > testGroovyClassLoader\(\) | ❌ | 0% 🟢 |
   | IntegrationTest > testGroovyScriptEngine\(\) | ❌ | 0% 🟢 |
   | IntegrationTest > testJavaShell\(\) | ❌ | 0% 🟢 |
   
   🏷️ Commit: c35ffe88d4934aa93fd61cbbf582a545f66c78c6
   ▶️ Tests:  1769 executed
   🟡 Checks: 1/29 completed
   
   ### Test Failures
   
   <details>
   
   <summary><strong>IntegrationTest > testGroovyClassLoader()</strong> (:test 
in <a 
href="https://github.com/apache/groovy/actions/runs/30829307455/job/91738939007?pr=2755";>Build
 and test / lts (17, macos-latest)</a>)</summary>
   
   ```
   java.io.IOException: Invalid argument
        at java.base/java.io.UnixFileSystem.createFileExclusively(Native Method)
        at java.base/java.io.File.createTempFile(File.java:2170)
        at java.base/java.io.File.createTempFile(File.java:2216)
        at TestScript162.run(TestScript162.groovy:2)
        at groovy.lang.GroovyShell.evaluate(GroovyShell.java:553)
        at groovy.lang.GroovyShell.evaluate(GroovyShell.java:588)
        at groovy.lang.GroovyShell.evaluate(GroovyShell.java:572)
        at groovy.test.GroovyAssert.assertScript(GroovyAssert.java:106)
        at groovy.test.GroovyAssert.assertScript(GroovyAssert.java:96)
        at IntegrationTest.testGroovyClassLoader(IntegrationTest.groovy:186)
   ```
   
   </details>
   <details>
   
   <summary><strong>IntegrationTest > testGroovyScriptEngine()</strong> (:test 
in <a 
href="https://github.com/apache/groovy/actions/runs/30829307455/job/91738939007?pr=2755";>Build
 and test / lts (17, macos-latest)</a>)</summary>
   
   ```
   java.nio.file.FileSystemException: 
/var/folders/df/djsxfhc17x95674wsm_g8s980000gn/T/reloadinggse15223087458965026584:
 Invalid argument
        at 
java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:100)
        at 
java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
        at 
java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
        at 
java.base/sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:397)
        at java.base/java.nio.file.Files.createDirectory(Files.java:700)
        at 
java.base/java.nio.file.TempFileHelper.create(TempFileHelper.java:134)
        at 
java.base/java.nio.file.TempFileHelper.createTempDirectory(TempFileHelper.java:171)
        at java.base/java.nio.file.Files.createTempDirectory(Files.java:1017)
        at 
org.codehaus.groovy.runtime.DefaultGroovyStaticMethods.createTempDirNio(DefaultGroovyStaticMethods.java:340)
        at 
org.codehaus.groovy.runtime.DefaultGroovyStaticMethods.createTempDir(DefaultGroovyStaticMethods.java:336)
        at TestScript158.run(TestScript158.groovy:1)
        at groovy.lang.GroovyShell.evaluate(GroovyShell.java:553)
        at groovy.lang.GroovyShell.evaluate(GroovyShell.java:588)
        at groovy.lang.GroovyShell.evaluate(GroovyShell.java:572)
        at groovy.test.GroovyAssert.assertScript(GroovyAssert.java:106)
        at groovy.test.GroovyAssert.assertScript(GroovyAssert.java:96)
        at IntegrationTest.testGroovyScriptEngine(IntegrationTest.groovy:203)
   ```
   
   </details>
   <details>
   
   <summary><strong>IntegrationTest > testJavaShell()</strong> (:test in <a 
href="https://github.com/apache/groovy/actions/runs/30829307455/job/91738939007?pr=2755";>Build
 and test / lts (17, macos-latest)</a>)</summary>
   
   ```
   org.apache.groovy.util.JavaShellCompilationException: /demo/Foo.java:2: 
error: cannot access demo
       package demo;
       ^
     Illegal byte sequence
   1 error
   
        at org.apache.groovy.util.JavaShell.doCompile(JavaShell.java:217)
        at org.apache.groovy.util.JavaShell.compile(JavaShell.java:148)
        at org.apache.groovy.util.JavaShell.compile(JavaShell.java:160)
        at 
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at 
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at 
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:569)
        at 
org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:379)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:298)
        at 
org.codehaus.groovy.vmplugin.v8.IndyInterface.invokeColdReflective(IndyInterface.java:518)
        at TestScript159.run(TestScript159.groovy:11)
        at groovy.lang.GroovyShell.evaluate(GroovyShell.java:553)
        at groovy.lang.GroovyShell.evaluate(GroovyShell.java:588)
        at groovy.lang.GroovyShell.evaluate(GroovyShell.java:572)
        at groovy.test.GroovyAssert.assertScript(GroovyAssert.java:106)
        at groovy.test.GroovyAssert.assertScript(GroovyAssert.java:96)
        at IntegrationTest.testJavaShell(IntegrationTest.groovy:262)
   ```
   
   </details>
   
   ### Muted Tests
   > [!NOTE]
   > Checks are currently running using the configuration below.
   
   Select tests to mute in this pull request:
   
   🔲 IntegrationTest > testGroovyClassLoader\(\) <!

> Introduce hidden class support
> ------------------------------
>
>                 Key: GROOVY-12223
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12223
>             Project: Groovy
>          Issue Type: Improvement
>            Reporter: Daniel Sun
>            Priority: Major
>
> h2. Background
> Groovy generates many short-lived synthetic classes at runtime, including:
> * map/interface proxies ({{ProxyGeneratorAdapter}})
> * reflection dispatch helpers ({{Reflector}} / {{ReflectorLoader}})
> * per-class meta-method artifacts ({{ClassLoaderForClassArtifacts}})
> Today these are defined with {{ClassLoader#defineClass}} as ordinary *named* 
> classes. That has three practical downsides:
> # *Name pollution* — the synthetic types are discoverable via 
> {{Class.forName}} / {{ClassLoader#loadClass}}.
> # *Metaspace pressure* — their lifetime is tied to the defining class loader; 
> long-running applications that generate many artifacts retain them until the 
> loader itself is collected.
> # *Access friction* — without nest membership, generated code cannot share 
> private access with the host class the way a true nestmate can.
> JDK 15 introduced *hidden classes* ([JEP 371|https://openjdk.org/jeps/371]): 
> classes defined through {{Lookup#defineHiddenClass}} that are 
> non-discoverable by name, may join an access-control nest ({{NESTMATE}}), and 
> may be unloaded independently of the defining loader when not marked 
> {{STRONG}}.
> Groovy 6 requires JDK 17+, so the API is always present on supported runtimes.
> h2. Proposal
> Centralise hidden-class definition behind a single utility and prefer it for 
> the dynamic class-generation sites listed above, with a transparent fallback 
> to the existing {{ClassLoader#defineClass}} path.
> h3. New API
> {{org.apache.groovy.util.HiddenClassDefiner}} — the only call-site that 
> invokes {{Lookup#defineHiddenClass}}:
> * {{defineHiddenClass(lookup, bytes, initialize, nestmate, strong)}} — full 
> control
> * {{defineNestmateClass(lookup, bytes, initialize)}} — nestmate + weak 
> lifecycle (default for proxies / reflectors / artifacts)
> * {{defineStrongHiddenClass(lookup, bytes, initialize)}} — non-discoverable, 
> loader-tied lifetime
> * helpers: {{privateLookupIn(hostClass)}}, {{findConstructor(hiddenClass, 
> ...parameterTypes)}}
> Kill-switch (evaluated once at class-init for hot-path cost):
> {noformat}
> -Dgroovy.hidden.classes.disable=true
> {noformat}
> When disabled (or when private lookup / definition fails), callers fall back 
> to defining a normal visible class.
> h3. Integration points
> || Site || Nest host || Preferred options || Fallback ||
> | {{ClassLoaderForClassArtifacts#define}} | target (klazz) | nestmate, weak | 
> {{ClassLoader#defineClass}} + protection domain |
> | {{ProxyGeneratorAdapter}} | non-{{Object}} superclass if present; else 
> {{ProxyGeneratorAdapter}} | nestmate, weak | {{InnerLoader#defineClass}} |
> | {{ReflectorLoader#defineClass}} | {{Reflector}} | nestmate, weak | 
> {{ClassLoader#defineClass}} + protection domain |
> Behaviour for callers of these generators is unchanged: proxies still 
> implement the requested interfaces, reflectors still dispatch, artifacts 
> still construct. The only observable differences when the hidden path 
> succeeds are the synthetic name form (contains {{/}}) and {{Class#isHidden() 
> == true}}.
> h2. Benefits
> * Non-discoverable synthetic types (cleaner class-space / tooling view).
> * Nestmate private access where the nest host can be opened for private 
> lookup.
> * Eager unloading of weak hidden classes reduces long-run metaspace retention 
> for short-lived proxies and artifacts.
> * One policy / upgrade point if future JDKs add further 
> {{Lookup.ClassOption}} values.
> h2. Compatibility
> * Default-on when the JVM can obtain a full-privilege lookup for the chosen 
> nest host; silent fallback otherwise (e.g. sealed / unopened module packages).
> * Opt-out: {{-Dgroovy.hidden.classes.disable=true}}.
> * No public language-surface change; no change to successful proxy / 
> reflector / artifact *behaviour*, only to how the {{Class}} is defined.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to