Skip to content

Commit

Permalink
Allow AnonymousClassDefiner class initializer complete normally if ru…
Browse files Browse the repository at this point in the history
…nning on JDK >=17 with Unsafe.defineAnonymousClass removed.

PiperOrigin-RevId: 632544907
  • Loading branch information
java-team-github-bot authored and Guice Team committed May 10, 2024
1 parent 42fbaf5 commit 2b37f02
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 4 deletions.
22 changes: 19 additions & 3 deletions core/src/com/google/inject/internal/aop/AnonymousClassDefiner.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,36 @@ final class AnonymousClassDefiner implements ClassDefiner {
private static final sun.misc.Unsafe THE_UNSAFE;
private static final Method ANONYMOUS_DEFINE_METHOD;

/** True if this class err'd during initialization and should not be used. */
static final boolean HAS_ERROR;

static {
sun.misc.Unsafe theUnsafe;
Method anonymousDefineMethod;
try {
THE_UNSAFE = UnsafeGetter.getUnsafe();
theUnsafe = UnsafeGetter.getUnsafe();
// defineAnonymousClass was removed in JDK17, so we must refer to it reflectively.
ANONYMOUS_DEFINE_METHOD =
anonymousDefineMethod =
sun.misc.Unsafe.class.getMethod(
"defineAnonymousClass", Class.class, byte[].class, Object[].class);
} catch (ReflectiveOperationException e) {
throw new ExceptionInInitializerError(e);
theUnsafe = null;
anonymousDefineMethod = null;
}

THE_UNSAFE = theUnsafe;
ANONYMOUS_DEFINE_METHOD = anonymousDefineMethod;
HAS_ERROR = theUnsafe == null;
}

@Override
public Class<?> define(Class<?> hostClass, byte[] bytecode) throws Exception {
if (HAS_ERROR) {
throw new IllegalStateException(
"Should not be called. An earlier error occurred during AnonymousClassDefiner static"
+ " initialization.");
}

return (Class<?>) ANONYMOUS_DEFINE_METHOD.invoke(THE_UNSAFE, hostClass, bytecode, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ final class UnsafeClassDefiner implements ClassDefiner {
static {
ClassDefiner unsafeDefiner =
tryPrivileged(AnonymousClassDefiner::new, "Cannot bind Unsafe.defineAnonymousClass");
if (unsafeDefiner == null) {

if (AnonymousClassDefiner.HAS_ERROR || unsafeDefiner == null) {
unsafeDefiner =
tryPrivileged(
HiddenClassDefiner::new, "Cannot bind MethodHandles.Lookup.defineHiddenClass");
Expand Down

0 comments on commit 2b37f02

Please sign in to comment.