Skip to content

Commit

Permalink
HHH-12618 Use MethodHandle lookup when available
Browse files Browse the repository at this point in the history
  • Loading branch information
gsmet committed May 24, 2018
1 parent 562661e commit 5c61830
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
Expand Up @@ -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;

Expand All @@ -18,6 +29,8 @@
*/
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.
Expand All @@ -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.
Expand Down Expand Up @@ -77,7 +92,41 @@ public static ByteBuddy getStaticByteBuddyInstance() {
}

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() );
}
}

}
Expand Up @@ -1807,4 +1807,8 @@ void attemptToAssociateProxyWithTwoOpenSessions(
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);

}

2 comments on commit 5c61830

@wtfiwtz
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gsmet does this mean 5.3.0 is the last version to support JDK v8 (see line 96, or line 27 on ClassLoadingStrategyHelper for Hibernate 5.4.22)? I think the documentation needs to be updated as I get errors on ClassInjector.UsingLookup.isAvailable() with ByteBuddy - admitted it looks like there are two versions of BB active - v1.6.14 and v1.10.10, so that might be the reason.

@wtfiwtz
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gsmet don't worry, I think it was the multiple versions of ByteBuddy - due to a springfox dependency (found with mvn dependency:tree)

Please sign in to comment.