Package: org.apache.groovy.util

## [Java] Class HiddenClassDefiner

- org.apache.groovy.util.HiddenClassDefiner

-     public final class HiddenClassDefiner
      extends Object

  Central facility for defining hidden classes (JEP 371).

  ## Lookup ownership

  MethodHandles.lookup is caller-sensitive: it returns a full-privilege lookup only for the class that literally contains the call. Production call sites capture a lookup on the intended nest host:

      private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
       Class<?> hidden = HiddenClassDefiner.tryDefineNestmate(LOOKUP, bytecode, false);

  Lookup#lookupClass()#lookupClass() fixes the hidden class's defining loader, package, protection domain, and nest host. Lookups from different runtime classes are not interchangeable as nest hosts even though they share the same module rights (see below).

  The lookup captured inside this class is used only as the caller argument to MethodHandles.privateLookupIn for the foreign-host overload — never as a production nest host.

  ## Module rights vs nest host

  Every production call site lives in the Groovy runtime, so `lookup()` always grants the same module-level access. Capturing it in different runtime classes does not open a third-party module that never opened itself to the runtime. What differs is the nest host (package / loader / nest membership), which still matters for unloadability and linkage.

  ## What nestmates cover (modules A / B / C)

  With modules A (Java library), B (Groovy program), C (Groovy runtime):

  1. Caller-owned lookup (tryDefineNestmate(Lookup, byte[], boolean)): nestmate of a runtime class. Works when every type named by the bytecode is resolvable from the runtime loader. No private access into foreign modules.
  2. Foreign host (tryDefineNestmate(Class, byte[], boolean)): best-effort `privateLookupIn`. Succeeds when the host package is open to the runtime (typical for unnamed-module application classes); not for strongly encapsulated packages such as `java.lang` (String is the counter-example). Callers must handle `null` and fall back to ClassLoader.defineClass.
  Nestmates cover C and often open/unnamed B. They do not tunnel private access into A. Visible `defineClass` is the intentional safety net.

  ## Soft-fail contract

  `try*` methods return `null` on expected failures (IllegalAccessException, SecurityException, LinkageError, invalid class-file / ASM exceptions, GraalVM `UnsupportedFeatureError` matched by class name). Other Errors are rethrown.

  ## Enablement

  isEnabled() is evaluated per call so `-Dgroovy.hidden.classes.disable=true` works under native-image build-time init, and is always `false` when `org.graalvm.nativeimage.imagecode=runtime`.

  Since:
    6.0.0
  See Also:
    Lookup#defineHiddenClass(byte[], boolean, Lookup.ClassOption...)

- - ### Field Summary

    Fields
    Modifiers | Name | Description
    --- | --- | ---
    `static String` | `PROPERTY_DISABLE` | System property that disables hidden-class definitions at run time.

  - ### Methods Summary

    Methods
    Type Params | Return Type | Name and description
    --- | --- | ---
    `` | `public static boolean` | `isEnabled()` Whether hidden-class definition may be attempted in this process.
    `` | `public static Class<?>` | `tryDefineNestmate(Lookup lookup, byte[] bytes, boolean initialize)` Defines `bytes` as a hidden nestmate of `lookup.lookupClass()` with a weak lifecycle.
    `` | `public static Class<?>` | `tryDefineNestmate(Class<?> host, byte[] bytes, boolean initialize)` Best-effort definition of a hidden nestmate of a foreign host.

  - ### Inherited Methods Summary

    Inherited Methods
    Methods inherited from class | Name
    --- | ---
    `class Object` | `equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### public static final String PROPERTY_DISABLE

      System property that disables hidden-class definitions at run time.

  - ### Method Detail

    - #### public static boolean isEnabled()

      Whether hidden-class definition may be attempted in this process.

      Returns:
        `false` when the kill switch is set or when running inside a GraalVM native image at run time

    - #### public static Class<?> tryDefineNestmate(Lookup lookup, byte[] bytes, boolean initialize)

      Defines `bytes` as a hidden nestmate of `lookup.lookupClass()` with a weak lifecycle. The class-file package is rewritten to match the lookup class before definition.

      Parameters:
        `lookup` - full-privilege lookup for the nest host
        `bytes` - class-file bytes
        `initialize` - `true` to run `<clinit>` immediately
      Returns:
        the hidden class, or `null` if definition is not possible

    - #### public static Class<?> tryDefineNestmate(Class<?> host, byte[] bytes, boolean initialize)

      Best-effort definition of a hidden nestmate of a foreign host. Uses `privateLookupIn` from this class; gated by canAttemptPrivateLookup(Class). Not a substitute for a host-owned lookup.

      Parameters:
        `host` - nest host and class-loader / package donor
        `bytes` - class-file bytes
        `initialize` - `true` to run `<clinit>` immediately
      Returns:
        the hidden class, or `null` if private lookup or definition fails