From 7049221af46b60b812d73ac65ad4769661c1faba Mon Sep 17 00:00:00 2001 From: Jorge Bescos Gascon Date: Thu, 18 Sep 2025 09:16:56 +0200 Subject: [PATCH] HHH-19798 - Graal-VM initialization issues Signed-off-by: Jorge Bescos Gascon --- .../bytebuddy/ByteBuddyEnhancementContext.java | 6 ++++-- .../org/hibernate/internal/util/LazyValue.java | 16 +++++++++++++--- .../pojo/bytebuddy/ByteBuddyProxyHelper.java | 6 ++++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/ByteBuddyEnhancementContext.java b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/ByteBuddyEnhancementContext.java index dd2097ae0bb4..c976708869b7 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/ByteBuddyEnhancementContext.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/ByteBuddyEnhancementContext.java @@ -15,6 +15,7 @@ import org.hibernate.bytecode.enhance.internal.bytebuddy.EnhancerImpl.AnnotatedFieldDescription; import org.hibernate.bytecode.enhance.spi.EnhancementContext; +import org.hibernate.internal.util.LazyValue; import jakarta.persistence.Embedded; import jakarta.persistence.metamodel.Type; @@ -30,7 +31,8 @@ class ByteBuddyEnhancementContext { - private static final ElementMatcher.Junction IS_GETTER = isGetter(); + // Lazy is necessary to not break GraalVM Native Image + private static final LazyValue> IS_GETTER = new LazyValue<>(() -> isGetter()); private final EnhancementContext enhancementContext; @@ -170,7 +172,7 @@ Optional resolveGetter(FieldDescription fieldDescription) { getters = MethodGraph.Compiler.DEFAULT.compile( erasure ) .listNodes() .asMethodList() - .filter( IS_GETTER ) + .filter( IS_GETTER.getValue() ) .stream() .collect( Collectors.toMap( MethodDescription::getActualName, Function.identity() ) ); getterByTypeMap.put( erasure, getters ); diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/LazyValue.java b/hibernate-core/src/main/java/org/hibernate/internal/util/LazyValue.java index 233b4b31bf96..2050484692ec 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/util/LazyValue.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/util/LazyValue.java @@ -7,6 +7,7 @@ package org.hibernate.internal.util; import java.util.Objects; +import java.util.concurrent.locks.ReentrantLock; import java.util.function.Supplier; /** @@ -18,8 +19,9 @@ public class LazyValue { public static final Object NULL = new Object(); + private final ReentrantLock lock = new ReentrantLock(); private final Supplier supplier; - private Object value; + private volatile Object value; public LazyValue(Supplier supplier) { this.supplier = supplier; @@ -27,8 +29,16 @@ public LazyValue(Supplier supplier) { public T getValue() { if ( value == null ) { - final T obtainedValue = supplier.get(); - value = Objects.requireNonNullElse( obtainedValue, NULL ); + lock.lock(); + try { + if (value == null) { + T obtainedValue = supplier.get(); + value = Objects.requireNonNullElse(obtainedValue, NULL); + } + } + finally { + lock.unlock(); + } } //noinspection unchecked diff --git a/hibernate-core/src/main/java/org/hibernate/proxy/pojo/bytebuddy/ByteBuddyProxyHelper.java b/hibernate-core/src/main/java/org/hibernate/proxy/pojo/bytebuddy/ByteBuddyProxyHelper.java index 9916891114b1..f1c330d4df5e 100644 --- a/hibernate-core/src/main/java/org/hibernate/proxy/pojo/bytebuddy/ByteBuddyProxyHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/proxy/pojo/bytebuddy/ByteBuddyProxyHelper.java @@ -25,6 +25,7 @@ import org.hibernate.internal.util.ReflectHelper; import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.ProxyConfiguration; +import org.hibernate.internal.util.LazyValue; import net.bytebuddy.ByteBuddy; import net.bytebuddy.NamingStrategy; @@ -41,7 +42,8 @@ public class ByteBuddyProxyHelper implements Serializable { private static final CoreMessageLogger LOG = messageLogger( ByteBuddyProxyHelper.class ); private static final String PROXY_NAMING_SUFFIX = "HibernateProxy"; - private static final TypeDescription OBJECT = TypeDescription.ForLoadedType.of(Object.class); + // Lazy is necessary to not break GraalVM Native Image + private static final LazyValue OBJECT = new LazyValue<>(() -> TypeDescription.ForLoadedType.of(Object.class)); private final ByteBuddyState byteBuddyState; @@ -96,7 +98,7 @@ private BiFunction> proxyBuild return (byteBuddy, namingStrategy) -> helpers.appendIgnoreAlsoAtEnd( byteBuddy .ignore( helpers.getGroovyGetMetaClassFilter() ) .with( namingStrategy ) - .subclass( interfaces.size() == 1 ? persistentClass : OBJECT, ConstructorStrategy.Default.IMITATE_SUPER_CLASS_OPENING ) + .subclass( interfaces.size() == 1 ? persistentClass : OBJECT.getValue(), ConstructorStrategy.Default.IMITATE_SUPER_CLASS_OPENING ) .implement( interfaces ) .method( helpers.getVirtualNotFinalizerFilter() ) .intercept( helpers.getDelegateToInterceptorDispatcherMethodDelegation() )