HHH-12618 Use MethodHandle lookup when available
This commit is contained in:
parent
562661e0a2
commit
5c6183066e
|
@ -6,8 +6,19 @@
|
|||
*/
|
||||
package org.hibernate.bytecode.internal.bytebuddy;
|
||||
|
||||
import static org.hibernate.internal.CoreLogging.messageLogger;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.proxy.pojo.bytebuddy.ByteBuddyProxyFactory;
|
||||
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.TypeCache;
|
||||
import net.bytebuddy.dynamic.loading.ClassInjector;
|
||||
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
|
||||
import net.bytebuddy.dynamic.scaffold.TypeValidation;
|
||||
|
||||
|
@ -18,6 +29,8 @@ import net.bytebuddy.dynamic.scaffold.TypeValidation;
|
|||
*/
|
||||
public final class ByteBuddyState {
|
||||
|
||||
private static final CoreMessageLogger LOG = messageLogger( ByteBuddyProxyFactory.class );
|
||||
|
||||
/**
|
||||
* Ideally shouldn't be static but it has to until we can remove the
|
||||
* deprecated static methods.
|
||||
|
@ -35,6 +48,8 @@ public final class ByteBuddyState {
|
|||
private static final TypeCache<TypeCache.SimpleKey> CACHE = new TypeCache.WithInlineExpunction<TypeCache.SimpleKey>(
|
||||
TypeCache.Sort.WEAK );
|
||||
|
||||
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
|
||||
|
||||
/**
|
||||
* Access to ByteBuddy. It's almost equivalent to creating a new ByteBuddy instance,
|
||||
* yet slightly preferrable so to be able to reuse the same instance.
|
||||
|
@ -77,7 +92,41 @@ public final class ByteBuddyState {
|
|||
}
|
||||
|
||||
public static ClassLoadingStrategy<?> resolveClassLoadingStrategy(Class<?> originalClass) {
|
||||
return new ClassLoadingStrategy.ForUnsafeInjection( originalClass.getProtectionDomain() );
|
||||
if ( ClassInjector.UsingLookup.isAvailable() ) {
|
||||
// This is only enabled for JDK 9+
|
||||
|
||||
Method privateLookupIn;
|
||||
try {
|
||||
privateLookupIn = MethodHandles.class.getMethod( "privateLookupIn", Class.class, MethodHandles.Lookup.class );
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new HibernateException( LOG.bytecodeEnhancementFailed( originalClass.getName() ), e );
|
||||
}
|
||||
|
||||
try {
|
||||
Object privateLookup;
|
||||
|
||||
try {
|
||||
privateLookup = privateLookupIn.invoke( null, originalClass, LOOKUP );
|
||||
}
|
||||
catch (InvocationTargetException exception) {
|
||||
if ( exception.getCause() instanceof IllegalAccessException ) {
|
||||
return new ClassLoadingStrategy.ForUnsafeInjection( originalClass.getProtectionDomain() );
|
||||
}
|
||||
else {
|
||||
throw new HibernateException( LOG.bytecodeEnhancementFailed( originalClass.getName() ), exception.getCause() );
|
||||
}
|
||||
}
|
||||
|
||||
return ClassLoadingStrategy.UsingLookup.of( privateLookup );
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new HibernateException( LOG.bytecodeEnhancementFailedUnableToGetPrivateLookupFor( originalClass.getName() ), e );
|
||||
}
|
||||
}
|
||||
else {
|
||||
return new ClassLoadingStrategy.ForUnsafeInjection( originalClass.getProtectionDomain() );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1807,4 +1807,8 @@ public interface CoreMessageLogger extends BasicLogger {
|
|||
id = 487)
|
||||
void immutableEntityUpdateQuery(String sourceQuery, String querySpaces);
|
||||
|
||||
@Message(value = "Bytecode enhancement failed for class: %1$s. It might be due to the Java module system preventing Hibernate ORM from defining an enhanced class "
|
||||
+ "in the same package as class %1$s. In this case, the class should be opened and exported to Hibernate ORM.", id = 488)
|
||||
String bytecodeEnhancementFailedUnableToGetPrivateLookupFor(String className);
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue