HHH-15090 Allow passing unloaded types and a TypePool to ByteBuddyProxyHelper#buildUnloadedProxy

This is necessary to solve this bug in Quarkus.
This commit is contained in:
Yoann Rodière 2022-03-01 16:14:38 +01:00
parent f0331f32e9
commit 6ad45e2842
2 changed files with 28 additions and 9 deletions

View File

@ -189,6 +189,10 @@ public final class ByteBuddyState {
return make( makeProxyFunction.apply( byteBuddy ) ); return make( makeProxyFunction.apply( byteBuddy ) );
} }
public Unloaded<?> make(TypePool typePool, Function<ByteBuddy, DynamicType.Builder<?>> makeProxyFunction) {
return make( typePool, makeProxyFunction.apply( byteBuddy ) );
}
private Unloaded<?> make(DynamicType.Builder<?> builder) { private Unloaded<?> make(DynamicType.Builder<?> builder) {
return make( null, builder ); return make( null, builder );
} }

View File

@ -10,8 +10,8 @@ import static org.hibernate.internal.CoreLogging.messageLogger;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
@ -29,9 +29,13 @@ import net.bytebuddy.ByteBuddy;
import net.bytebuddy.NamingStrategy; import net.bytebuddy.NamingStrategy;
import net.bytebuddy.TypeCache; import net.bytebuddy.TypeCache;
import net.bytebuddy.description.modifier.Visibility; import net.bytebuddy.description.modifier.Visibility;
import net.bytebuddy.description.type.TypeDefinition;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.description.type.TypeList;
import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy; import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy;
import net.bytebuddy.implementation.SuperMethodCall; import net.bytebuddy.implementation.SuperMethodCall;
import net.bytebuddy.pool.TypePool;
public class ByteBuddyProxyHelper implements Serializable { public class ByteBuddyProxyHelper implements Serializable {
@ -52,24 +56,35 @@ public class ByteBuddyProxyHelper implements Serializable {
} }
key.addAll( Arrays.<Class<?>>asList( interfaces ) ); key.addAll( Arrays.<Class<?>>asList( interfaces ) );
return byteBuddyState.loadProxy( persistentClass, new TypeCache.SimpleKey( key ), proxyBuilder( persistentClass, interfaces ) ); return byteBuddyState.loadProxy( persistentClass, new TypeCache.SimpleKey( key ),
proxyBuilder( TypeDescription.ForLoadedType.of( persistentClass ), new TypeList.Generic.ForLoadedTypes( interfaces ) ) );
}
/**
* @deprecated Use {@link #buildUnloadedProxy(TypePool, TypeDefinition, Collection)} instead.
*/
@Deprecated
public DynamicType.Unloaded<?> buildUnloadedProxy(final Class<?> persistentClass, final Class<?>[] interfaces) {
return byteBuddyState.make( proxyBuilder( TypeDescription.ForLoadedType.of( persistentClass ),
new TypeList.Generic.ForLoadedTypes( interfaces ) ) );
} }
/** /**
* Do not remove: used by Quarkus * Do not remove: used by Quarkus
*/ */
@SuppressWarnings({ "unchecked", "rawtypes" }) public DynamicType.Unloaded<?> buildUnloadedProxy(TypePool typePool, TypeDefinition persistentClass,
public DynamicType.Unloaded<?> buildUnloadedProxy(final Class persistentClass, final Class[] interfaces) { Collection<? extends TypeDefinition> interfaces) {
return byteBuddyState.make( proxyBuilder( persistentClass, interfaces ) ); return byteBuddyState.make( typePool, proxyBuilder( persistentClass, interfaces ) );
} }
private Function<ByteBuddy, DynamicType.Builder<?>> proxyBuilder(Class persistentClass, Class[] interfaces) { private Function<ByteBuddy, DynamicType.Builder<?>> proxyBuilder(TypeDefinition persistentClass,
Collection<? extends TypeDefinition> interfaces) {
ByteBuddyState.ProxyDefinitionHelpers helpers = byteBuddyState.getProxyDefinitionHelpers(); ByteBuddyState.ProxyDefinitionHelpers helpers = byteBuddyState.getProxyDefinitionHelpers();
return byteBuddy -> byteBuddy return byteBuddy -> byteBuddy
.ignore( helpers.getGroovyGetMetaClassFilter() ) .ignore( helpers.getGroovyGetMetaClassFilter() )
.with( new NamingStrategy.SuffixingRandom( PROXY_NAMING_SUFFIX, new NamingStrategy.SuffixingRandom.BaseNameResolver.ForFixedValue( persistentClass.getName() ) ) ) .with( new NamingStrategy.SuffixingRandom( PROXY_NAMING_SUFFIX, new NamingStrategy.SuffixingRandom.BaseNameResolver.ForFixedValue( persistentClass.getTypeName() ) ) )
.subclass( interfaces.length == 1 ? persistentClass : Object.class, ConstructorStrategy.Default.IMITATE_SUPER_CLASS_OPENING ) .subclass( interfaces.size() == 1 ? persistentClass : TypeDescription.OBJECT, ConstructorStrategy.Default.IMITATE_SUPER_CLASS_OPENING )
.implement( (Type[]) interfaces ) .implement( interfaces )
.method( helpers.getVirtualNotFinalizerFilter() ) .method( helpers.getVirtualNotFinalizerFilter() )
.intercept( helpers.getDelegateToInterceptorDispatcherMethodDelegation() ) .intercept( helpers.getDelegateToInterceptorDispatcherMethodDelegation() )
.method( helpers.getProxyNonInterceptedMethodFilter() ) .method( helpers.getProxyNonInterceptedMethodFilter() )