paulk-asert commented on PR #2755:
URL: https://github.com/apache/groovy/pull/2755#issuecomment-5173819415

   I haven't done a proper review yet, but as part of some other work, I 
assessed whether the PR impacts potential GraalVM support if we try harder to 
support that in the future. It came back with below, I'm not sure we want to do 
what is says yet - but just wanted to capture it somewhere for now:
   
   > Two native-image observations from exercising this branch alongside the 
packed-closure work (GROOVY-12227). Both are small; the first is a genuine easy 
win.
   > 
   > ### 1. The soft-fail contract doesn't hold under native image
   > 
   > `tryDefineNestmate` catches `IllegalAccessException | SecurityException | 
LinkageError` (plus `IllegalArgumentException` and 
`IndexOutOfBoundsException`), and the class javadoc documents the intent as 
returning `null` on the expected failure modes "so call sites fall back to 
`ClassLoader#defineClass` with one null check".
   > 
   > GraalVM signals "this runtime cannot define classes" with 
`com.oracle.svm.core.jdk.UnsupportedFeatureError`, which extends 
`java.lang.Error` **directly**:
   > 
   > ```
   > $ javap com/oracle/svm/core/jdk/UnsupportedFeatureError.class   # from 
lib/svm/builder/svm.jar, GraalVM CE 25.2.4
   > public class com.oracle.svm.core.jdk.UnsupportedFeatureError extends 
java.lang.Error {
   > ```
   > 
   > It is not a `LinkageError`, so it escapes the catch and propagates out of 
the `try*` method — in precisely the environment where the fallback matters 
most.
   > 
   > A blanket `catch (Throwable)` would contradict the javadoc's "unexpected 
failures ... are not swallowed as a blanket `RuntimeException`", so something 
targeted is probably wanted, e.g.:
   > 
   > ```java
   > } catch (Error e) {
   >     // GraalVM native image: runtime class definition is unsupported. 
Name-checked
   >     // to avoid a build-time dependency on org.graalvm.
   >     if 
("com.oracle.svm.core.jdk.UnsupportedFeatureError".equals(e.getClass().getName()))
 {
   >         return null;
   >     }
   >     throw e;
   > }
   > ```
   > 
   > ### 2. The kill switch is baked in at build time
   > 
   > ```java
   > public static final boolean HIDDEN_CLASSES_DISABLED =
   >         SystemUtil.getBooleanSafe(PROPERTY_DISABLE, false);
   > ```
   > 
   > `static final`, documented as "evaluated once at class-init so hot paths 
pay no property-lookup cost". Under native image this class is very likely 
initialized at *build* time, so the value captured is the build JVM's, and 
`-Dgroovy.hidden.classes.disable=true` at run time silently does nothing — the 
one escape hatch a native user would reach for.
   > 
   > This is the same trap I hit in GROOVY-12227: I ended up evaluating the 
equivalent check per link rather than caching it in a static, because a 
build-time-initialized class bakes in the wrong answer (the image-code property 
reports `buildtime` there, not `runtime`).
   > 
   > ### Possibly one fix for both
   > 
   > If `isEnabled()` did a per-call check that also returned `false` when
   > 
`"runtime".equals(System.getProperty("org.graalvm.nativeimage.imagecode"))`, 
then the native path would never attempt the definition at all, the kill switch 
would work at run time, and (1) becomes belt-and-braces rather than 
load-bearing. If the hot-path cost of the property read is the concern, a 
non-final holder initialised on first *use* rather than at class-init keeps 
both properties.
   > 
   > ### Caveat on incidence
   > 
   > I have not observed (1) fire in practice — the coercion I tested (`[run: { 
... }] as Runnable`) goes through `java.lang.reflect.Proxy` and works natively 
on both master and this branch, so it does not reach `HiddenClassDefiner`. This 
is from reading the code plus confirming the class hierarchy, not from a 
reproduced failure. Worth a targeted test if you think the proxy/reflector 
paths are reachable in a native image.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to