HHH-12584 In fact, we can provide a ReflectionOptimizer, just without the fast class instantiator

The fast class instantiator don't make sense for an abstract class or an
interface. I checked the code and we can indeed instantiate a
ReflectionOptimizer without a fast class instantiator.
This commit is contained in:
Guillaume Smet 2018-05-25 10:29:13 +02:00 committed by Chris Cranford
parent 9a3aa99e83
commit 9d4d0ae63b
2 changed files with 20 additions and 18 deletions

View File

@ -56,25 +56,28 @@ public class BytecodeProviderImpl implements BytecodeProvider {
final String[] getterNames,
final String[] setterNames,
final Class[] types) {
if ( clazz.isInterface() || Modifier.isAbstract( clazz.getModifiers() ) ) {
// we don't provide an optimizer for interfaces and abstract classes - similar to what we do with Javassist
return null;
final Class fastClass;
if ( !clazz.isInterface() && !Modifier.isAbstract( clazz.getModifiers() ) ) {
// we only provide a fast class instantiator if the class can be instantiated
final Constructor<?> constructor = findConstructor( clazz );
fastClass = bytebuddy.getCurrentyByteBuddy()
.with( new NamingStrategy.SuffixingRandom( INSTANTIATOR_PROXY_NAMING_SUFFIX,
new NamingStrategy.SuffixingRandom.BaseNameResolver.ForFixedValue( clazz.getName() ) ) )
.subclass( ReflectionOptimizer.InstantiationOptimizer.class )
.method( newInstanceMethodName )
.intercept( MethodCall.construct( constructor ) )
.make()
.load( clazz.getClassLoader(), ByteBuddyState.resolveClassLoadingStrategy( clazz ) )
.getLoaded();
}
else {
fastClass = null;
}
final Method[] getters = new Method[getterNames.length];
final Method[] setters = new Method[setterNames.length];
findAccessors( clazz, getterNames, setterNames, types, getters, setters );
final Constructor<?> constructor = findConstructor( clazz );
final Class fastClass = bytebuddy.getCurrentyByteBuddy()
.with( new NamingStrategy.SuffixingRandom( INSTANTIATOR_PROXY_NAMING_SUFFIX,
new NamingStrategy.SuffixingRandom.BaseNameResolver.ForFixedValue( clazz.getName() ) ) )
.subclass( ReflectionOptimizer.InstantiationOptimizer.class )
.method( newInstanceMethodName )
.intercept( MethodCall.construct( constructor ) )
.make()
.load( clazz.getClassLoader(), ByteBuddyState.resolveClassLoadingStrategy( clazz ) )
.getLoaded();
final Class bulkAccessor = bytebuddy.getCurrentyByteBuddy()
.with( new NamingStrategy.SuffixingRandom( OPTIMIZER_PROXY_NAMING_SUFFIX,
@ -92,7 +95,7 @@ public class BytecodeProviderImpl implements BytecodeProvider {
try {
return new ReflectionOptimizerImpl(
(ReflectionOptimizer.InstantiationOptimizer) fastClass.newInstance(),
fastClass != null ? (ReflectionOptimizer.InstantiationOptimizer) fastClass.newInstance() : null,
(ReflectionOptimizer.AccessOptimizer) bulkAccessor.newInstance()
);
}

View File

@ -8,7 +8,6 @@ package org.hibernate.test.bytecode;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import org.hibernate.bytecode.internal.javassist.BulkAccessor;
import org.hibernate.bytecode.spi.BytecodeProvider;
@ -61,7 +60,7 @@ public class ReflectionOptimizerTest extends BaseUnitTestCase {
BytecodeProvider provider = Environment.getBytecodeProvider();
ReflectionOptimizer reflectionOptimizer = provider.getReflectionOptimizer( AbstractClass.class, new String[]{ "getProperty" },
new String[]{ "setProperty" }, new Class[]{ String.class } );
assertNull( reflectionOptimizer );
assertNotNull( reflectionOptimizer );
}
@Test
@ -70,7 +69,7 @@ public class ReflectionOptimizerTest extends BaseUnitTestCase {
BytecodeProvider provider = Environment.getBytecodeProvider();
ReflectionOptimizer reflectionOptimizer = provider.getReflectionOptimizer( Interface.class, new String[]{ "getProperty" },
new String[]{ "setProperty" }, new Class[]{ String.class } );
assertNull( reflectionOptimizer );
assertNotNull( reflectionOptimizer );
}
private void assertEquivalent(Object[] checkValues, Object[] values) {