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
parent 93fed78f31
commit 3981c14e9e
2 changed files with 25 additions and 25 deletions

View File

@ -53,32 +53,33 @@ 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 = FAST_CLASSES.findOrInsert( clazz.getClassLoader(), clazz.getName(), new Callable<Class<?>>() {
@Override
public Class<?> call() throws Exception {
return new ByteBuddy()
.with(TypeValidation.DISABLED)
.with(new NamingStrategy.SuffixingRandom("HibernateInstantiator"))
.subclass(ReflectionOptimizer.InstantiationOptimizer.class)
.method(ElementMatchers.named("newInstance"))
.intercept(MethodCall.construct(constructor))
.make()
.load(clazz.getClassLoader())
.getLoaded();
}
}, FAST_CLASSES);
}
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 );
Class fastClass = FAST_CLASSES.findOrInsert( clazz.getClassLoader(), clazz.getName(), new Callable<Class<?>>() {
@Override
public Class<?> call() throws Exception {
return new ByteBuddy()
.with(TypeValidation.DISABLED)
.with(new NamingStrategy.SuffixingRandom("HibernateInstantiator"))
.subclass(ReflectionOptimizer.InstantiationOptimizer.class)
.method(ElementMatchers.named("newInstance"))
.intercept(MethodCall.construct(constructor))
.make()
.load(clazz.getClassLoader())
.getLoaded();
}
}, FAST_CLASSES);
fastClass = FAST_CLASSES.insert( clazz.getClassLoader(), clazz.getName(), fastClass );
Class bulkAccessor = BULK_ACCESSORS.findOrInsert( clazz.getClassLoader(), clazz.getName(), new Callable<Class<?>>() {
@Override
@ -101,7 +102,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) {