HHH-15790 Refactor filter definition in ByteBuddyProxyHelper

This commit is contained in:
Sanne Grinovero 2022-12-01 15:04:13 +00:00 committed by Sanne Grinovero
parent fbf469830c
commit afc35f6c62
3 changed files with 30 additions and 31 deletions

View File

@ -6,7 +6,7 @@
*/ */
package org.hibernate.bytecode.internal.bytebuddy; package org.hibernate.bytecode.internal.bytebuddy;
import static net.bytebuddy.matcher.ElementMatchers.anyOf; import static net.bytebuddy.matcher.ElementMatchers.isDeclaredBy;
import static net.bytebuddy.matcher.ElementMatchers.isFinalizer; import static net.bytebuddy.matcher.ElementMatchers.isFinalizer;
import static net.bytebuddy.matcher.ElementMatchers.isSynthetic; import static net.bytebuddy.matcher.ElementMatchers.isSynthetic;
import static net.bytebuddy.matcher.ElementMatchers.isVirtual; import static net.bytebuddy.matcher.ElementMatchers.isVirtual;
@ -14,6 +14,7 @@ import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not; import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.returns; import static net.bytebuddy.matcher.ElementMatchers.returns;
import static net.bytebuddy.matcher.ElementMatchers.takesNoArguments;
import static org.hibernate.internal.CoreLogging.messageLogger; import static org.hibernate.internal.CoreLogging.messageLogger;
import java.io.File; import java.io.File;
@ -22,6 +23,8 @@ import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function; import java.util.function.Function;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
@ -283,6 +286,7 @@ public final class ByteBuddyState {
private final ElementMatcher<? super MethodDescription> groovyGetMetaClassFilter; private final ElementMatcher<? super MethodDescription> groovyGetMetaClassFilter;
private final ElementMatcher<? super MethodDescription> virtualNotFinalizerFilter; private final ElementMatcher<? super MethodDescription> virtualNotFinalizerFilter;
private final ElementMatcher<? super MethodDescription> proxyNonInterceptedMethodFilter; private final ElementMatcher<? super MethodDescription> proxyNonInterceptedMethodFilter;
private final List<ElementMatcher<? super MethodDescription>> toFullyIgnore = new ArrayList<>();
private final MethodDelegation delegateToInterceptorDispatcherMethodDelegation; private final MethodDelegation delegateToInterceptorDispatcherMethodDelegation;
private final FieldAccessor.PropertyConfigurable interceptorFieldAccessor; private final FieldAccessor.PropertyConfigurable interceptorFieldAccessor;
@ -296,6 +300,14 @@ public final class ByteBuddyState {
.and( not( nameStartsWith( EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX ) ) ) .and( not( nameStartsWith( EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX ) ) )
.and( not( nameStartsWith( EnhancerConstants.PERSISTENT_FIELD_WRITER_PREFIX ) ) ); .and( not( nameStartsWith( EnhancerConstants.PERSISTENT_FIELD_WRITER_PREFIX ) ) );
// Populate the toFullyIgnore list
for ( Method m : PrimeAmongSecondarySupertypes.class.getMethods() ) {
//We need to ignore both the match of each default method on PrimeAmongSecondarySupertypes
toFullyIgnore.add( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( m.getName() ) ).and( takesNoArguments() ) );
//And the override in the interface it belong to - which we happen to have in the return type
toFullyIgnore.add( isDeclaredBy( m.getReturnType() ).and( named( m.getName() ) ).and( takesNoArguments() ) );
}
PrivilegedAction<MethodDelegation> delegateToInterceptorDispatcherMethodDelegationPrivilegedAction = PrivilegedAction<MethodDelegation> delegateToInterceptorDispatcherMethodDelegationPrivilegedAction =
new PrivilegedAction<MethodDelegation>() { new PrivilegedAction<MethodDelegation>() {
@ -343,6 +355,13 @@ public final class ByteBuddyState {
public FieldAccessor.PropertyConfigurable getInterceptorFieldAccessor() { public FieldAccessor.PropertyConfigurable getInterceptorFieldAccessor() {
return interceptorFieldAccessor; return interceptorFieldAccessor;
} }
public DynamicType.Builder<?> appendIgnoreAlsoAtEnd(DynamicType.Builder<?> builder) {
for ( ElementMatcher<? super MethodDescription> m : toFullyIgnore ) {
builder = builder.ignoreAlso( m );
}
return builder;
}
} }
private interface ClassRewriter { private interface ClassRewriter {

View File

@ -95,7 +95,7 @@ public class ByteBuddyProxyHelper implements Serializable {
private Function<ByteBuddy, DynamicType.Builder<?>> proxyBuilder(TypeDefinition persistentClass, private Function<ByteBuddy, DynamicType.Builder<?>> proxyBuilder(TypeDefinition persistentClass,
Collection<? extends TypeDefinition> interfaces) { Collection<? extends TypeDefinition> interfaces) {
ByteBuddyState.ProxyDefinitionHelpers helpers = byteBuddyState.getProxyDefinitionHelpers(); ByteBuddyState.ProxyDefinitionHelpers helpers = byteBuddyState.getProxyDefinitionHelpers();
return byteBuddy -> byteBuddy return byteBuddy -> helpers.appendIgnoreAlsoAtEnd( byteBuddy
.ignore( helpers.getGroovyGetMetaClassFilter() ) .ignore( helpers.getGroovyGetMetaClassFilter() )
.with( new NamingStrategy.SuffixingRandom( PROXY_NAMING_SUFFIX, new NamingStrategy.SuffixingRandom.BaseNameResolver.ForFixedValue( persistentClass.getTypeName() ) ) ) .with( new NamingStrategy.SuffixingRandom( PROXY_NAMING_SUFFIX, new NamingStrategy.SuffixingRandom.BaseNameResolver.ForFixedValue( persistentClass.getTypeName() ) ) )
.subclass( interfaces.size() == 1 ? persistentClass : TypeDescription.OBJECT, ConstructorStrategy.Default.IMITATE_SUPER_CLASS_OPENING ) .subclass( interfaces.size() == 1 ? persistentClass : TypeDescription.OBJECT, ConstructorStrategy.Default.IMITATE_SUPER_CLASS_OPENING )
@ -107,24 +107,7 @@ public class ByteBuddyProxyHelper implements Serializable {
.defineField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME, ProxyConfiguration.Interceptor.class, Visibility.PRIVATE ) .defineField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME, ProxyConfiguration.Interceptor.class, Visibility.PRIVATE )
.implement( ProxyConfiguration.class ) .implement( ProxyConfiguration.class )
.intercept( helpers.getInterceptorFieldAccessor() ) .intercept( helpers.getInterceptorFieldAccessor() )
.ignoreAlso( isDeclaredBy( ManagedEntity.class ).and( named( "asManagedEntity" ) ) ) );
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asManagedEntity" ) ) )
.ignoreAlso( isDeclaredBy( PersistentAttributeInterceptable.class ).and( named( "asPersistentAttributeInterceptable" ) ) )
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asPersistentAttributeInterceptable" ) ) )
.ignoreAlso( isDeclaredBy( SelfDirtinessTracker.class ).and( named( "asSelfDirtinessTracker" ) ) )
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asSelfDirtinessTracker" ) ) )
.ignoreAlso( isDeclaredBy( Managed.class ).and( named( "asManaged" ) ) )
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asManaged" ) ) )
.ignoreAlso( isDeclaredBy( ManagedComposite.class ).and( named( "asManagedComposite" ) ) )
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asManagedComposite" ) ) )
.ignoreAlso( isDeclaredBy( ManagedMappedSuperclass.class ).and( named( "asManagedMappedSuperclass" ) ) )
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asManagedMappedSuperclass" ) ) )
.ignoreAlso( isDeclaredBy( CompositeOwner.class ).and( named( "asCompositeOwner" ) ) )
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asCompositeOwner" ) ) )
.ignoreAlso( isDeclaredBy( CompositeTracker.class ).and( named( "asCompositeTracker" ) ) )
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asCompositeTracker" ) ) )
.ignoreAlso( isDeclaredBy( HibernateProxy.class ).and( named( "asHibernateProxy" ) ) )
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asHibernateProxy" ) ) );
} }
public HibernateProxy deserializeProxy(SerializableProxy serializableProxy) { public HibernateProxy deserializeProxy(SerializableProxy serializableProxy) {

View File

@ -57,6 +57,13 @@ public class SuperTypesEnhancementTest {
Assert.assertNotNull( m.isDefault() ); Assert.assertNotNull( m.isDefault() );
} }
@ParameterizedTest
@MethodSource("superTypeMethods")
public void testAllsubInterfacesExtendTheSingleparent(Method m) {
final Class<?> returnType = m.getReturnType();
Assert.assertTrue( PrimeAmongSecondarySupertypes.class.isAssignableFrom( returnType ) );
}
@ParameterizedTest @ParameterizedTest
@MethodSource("superTypeMethods") @MethodSource("superTypeMethods")
public void testSubInterfaceOverrides(Method m) throws NoSuchMethodException { public void testSubInterfaceOverrides(Method m) throws NoSuchMethodException {
@ -66,18 +73,8 @@ public class SuperTypesEnhancementTest {
Assert.assertNotNull( subMethod.isDefault() ); Assert.assertNotNull( subMethod.isDefault() );
} }
@ParameterizedTest
@MethodSource("interfaces")
public void testAllProxyGeneration(Class<?> secondarySuper) {
ProxyFactory enhancer = createProxyFactory( SampleClass.class, secondarySuper );
final Object proxy = enhancer.getProxy( Integer.valueOf( 1 ), null );
Assert.assertTrue( secondarySuper.isAssignableFrom( proxy.getClass() ) );
PrimeAmongSecondarySupertypes casted = (PrimeAmongSecondarySupertypes) proxy;
testForLIE( (SampleClass) proxy );
}
@Test @Test
public void testGeneratedHibernateProxy() { public void testHibernateProxyGeneration() {
ProxyFactory enhancer = createProxyFactory( SampleClass.class, HibernateProxy.class ); ProxyFactory enhancer = createProxyFactory( SampleClass.class, HibernateProxy.class );
final Object proxy = enhancer.getProxy( Integer.valueOf( 1 ), null ); final Object proxy = enhancer.getProxy( Integer.valueOf( 1 ), null );
Assert.assertTrue( HibernateProxy.class.isAssignableFrom( proxy.getClass() ) ); Assert.assertTrue( HibernateProxy.class.isAssignableFrom( proxy.getClass() ) );