HHH-12857 Avoid using a static ByteBuddy object

In the end, it does not change anything as the BytecodeProvider is still
static but it helps as a general cleanup for the following commits.
This commit is contained in:
Guillaume Smet 2018-07-25 11:53:32 +02:00
parent c9de4b8ce7
commit 129530e464
10 changed files with 237 additions and 183 deletions

View File

@ -68,7 +68,7 @@ public class EnhancerImpl implements Enhancer {
private static final CoreMessageLogger log = CoreLogging.messageLogger( Enhancer.class );
protected final ByteBuddyEnhancementContext enhancementContext;
private final ByteBuddyState bytebuddy;
private final ByteBuddyState byteBuddyState;
private final TypePool classPool;
@ -77,11 +77,11 @@ public class EnhancerImpl implements Enhancer {
*
* @param enhancementContext Describes the context in which enhancement will occur so as to give access
* to contextual/environmental information.
* @param bytebuddy refers to the ByteBuddy instance to use
* @param byteBuddyState refers to the ByteBuddy instance to use
*/
public EnhancerImpl(final EnhancementContext enhancementContext, final ByteBuddyState bytebuddy) {
public EnhancerImpl(final EnhancementContext enhancementContext, final ByteBuddyState byteBuddyState) {
this.enhancementContext = new ByteBuddyEnhancementContext( enhancementContext );
this.bytebuddy = bytebuddy;
this.byteBuddyState = byteBuddyState;
this.classPool = buildClassPool( this.enhancementContext );
}
@ -103,7 +103,7 @@ public class EnhancerImpl implements Enhancer {
try {
final TypeDescription managedCtClass = classPool.describe( safeClassName ).resolve();
DynamicType.Builder<?> builder = doEnhance(
bytebuddy.getCurrentyByteBuddy().ignore( isDefaultFinalizer() ).redefine( managedCtClass, ClassFileLocator.Simple.of( safeClassName, originalBytes ) ),
byteBuddyState.getCurrentByteBuddy().ignore( isDefaultFinalizer() ).redefine( managedCtClass, ClassFileLocator.Simple.of( safeClassName, originalBytes ) ),
managedCtClass
);
if ( builder == null ) {

View File

@ -36,7 +36,7 @@ public class BasicProxyFactoryImpl implements BasicProxyFactory {
final Class<?> superClassOrMainInterface = superClass != null ? superClass : interfaces[0];
this.proxyClass = bytebuddy.getCurrentyByteBuddy()
this.proxyClass = bytebuddy.getCurrentByteBuddy()
.with( new NamingStrategy.SuffixingRandom( PROXY_NAMING_SUFFIX, new NamingStrategy.SuffixingRandom.BaseNameResolver.ForFixedValue( superClassOrMainInterface.getName() ) ) )
.subclass( superClass == null ? Object.class : superClass, ConstructorStrategy.Default.DEFAULT_CONSTRUCTOR )
.implement( interfaces == null ? NO_INTERFACES : interfaces )

View File

@ -31,42 +31,34 @@ 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.
*/
private static final ByteBuddy buddy = new ByteBuddy().with( TypeValidation.DISABLED );
private final ByteBuddy byteBuddy;
/**
* This currently needs to be static: the BytecodeProvider is a static field of Environment and
* is being accessed from static methods.
* It will be easier to maintain the cache and its state when it will no longer be static
* in Hibernate ORM 6+.
* Opted for WEAK keys to avoid leaking the classloader in case the SessionFactory isn't closed.
* Avoiding Soft keys as they are prone to cause issues with unstable performance.
*/
private static final TypeCache<TypeCache.SimpleKey> CACHE = new TypeCache.WithInlineExpunction<TypeCache.SimpleKey>(
TypeCache.Sort.WEAK );
private final TypeCache<TypeCache.SimpleKey> typeCache;
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
ByteBuddyState() {
this.byteBuddy = new ByteBuddy().with( TypeValidation.DISABLED );
this.typeCache = new TypeCache.WithInlineExpunction<TypeCache.SimpleKey>( TypeCache.Sort.WEAK );
}
/**
* 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.
* @return
*/
public ByteBuddy getCurrentyByteBuddy() {
return buddy;
public ByteBuddy getCurrentByteBuddy() {
return byteBuddy;
}
/**
* @deprecated as we should not need static access to this state.
* This will be removed with no replacement.
* It's actually likely that this whole class becomes unnecessary in the near future.
*/
@Deprecated
public static TypeCache<TypeCache.SimpleKey> getCacheForProxies() {
return CACHE;
public TypeCache<TypeCache.SimpleKey> getCacheForProxies() {
return typeCache;
}
/**
@ -78,17 +70,7 @@ public final class ByteBuddyState {
* of re-creating the small helpers should be negligible.
*/
void clearState() {
CACHE.clear();
}
/**
* @deprecated as we should not need static access to this state.
* This will be removed with no replacement.
* It's actually likely that this whole class becomes unnecessary in the near future.
*/
@Deprecated
public static ByteBuddy getStaticByteBuddyInstance() {
return buddy;
typeCache.clear();
}
public static ClassLoadingStrategy<ClassLoader> resolveClassLoadingStrategy(Class<?> originalClass) {

View File

@ -18,6 +18,7 @@ import org.hibernate.bytecode.enhance.spi.Enhancer;
import org.hibernate.bytecode.spi.BytecodeProvider;
import org.hibernate.bytecode.spi.ProxyFactoryFactory;
import org.hibernate.bytecode.spi.ReflectionOptimizer;
import org.hibernate.proxy.pojo.bytebuddy.ByteBuddyProxyHelper;
import net.bytebuddy.NamingStrategy;
import net.bytebuddy.description.method.MethodDescription;
@ -37,7 +38,6 @@ import net.bytebuddy.matcher.ElementMatchers;
public class BytecodeProviderImpl implements BytecodeProvider {
private static final ByteBuddyState bytebuddy = new ByteBuddyState();
private static final String INSTANTIATOR_PROXY_NAMING_SUFFIX = "HibernateInstantiator";
private static final String OPTIMIZER_PROXY_NAMING_SUFFIX = "HibernateAccessOptimizer";
private static final ElementMatcher.Junction newInstanceMethodName = ElementMatchers.named( "newInstance" );
@ -45,9 +45,18 @@ public class BytecodeProviderImpl implements BytecodeProvider {
private static final ElementMatcher.Junction setPropertyValuesMethodName = ElementMatchers.named( "setPropertyValues" );
private static final ElementMatcher.Junction getPropertyNamesMethodName = ElementMatchers.named( "getPropertyNames" );
private final ByteBuddyState byteBuddyState;
private final ByteBuddyProxyHelper byteBuddyProxyHelper;
public BytecodeProviderImpl() {
this.byteBuddyState = new ByteBuddyState();
this.byteBuddyProxyHelper = new ByteBuddyProxyHelper( byteBuddyState );
}
@Override
public ProxyFactoryFactory getProxyFactoryFactory() {
return new ProxyFactoryFactoryImpl( bytebuddy );
return new ProxyFactoryFactoryImpl( byteBuddyState, byteBuddyProxyHelper );
}
@Override
@ -61,7 +70,7 @@ public class BytecodeProviderImpl implements BytecodeProvider {
// we only provide a fast class instantiator if the class can be instantiated
final Constructor<?> constructor = findConstructor( clazz );
fastClass = bytebuddy.getCurrentyByteBuddy()
fastClass = byteBuddyState.getCurrentByteBuddy()
.with( new NamingStrategy.SuffixingRandom( INSTANTIATOR_PROXY_NAMING_SUFFIX,
new NamingStrategy.SuffixingRandom.BaseNameResolver.ForFixedValue( clazz.getName() ) ) )
.subclass( ReflectionOptimizer.InstantiationOptimizer.class )
@ -79,7 +88,7 @@ public class BytecodeProviderImpl implements BytecodeProvider {
final Method[] setters = new Method[setterNames.length];
findAccessors( clazz, getterNames, setterNames, types, getters, setters );
final Class bulkAccessor = bytebuddy.getCurrentyByteBuddy()
final Class bulkAccessor = byteBuddyState.getCurrentByteBuddy()
.with( new NamingStrategy.SuffixingRandom( OPTIMIZER_PROXY_NAMING_SUFFIX,
new NamingStrategy.SuffixingRandom.BaseNameResolver.ForFixedValue( clazz.getName() ) ) )
.subclass( ReflectionOptimizer.AccessOptimizer.class )
@ -104,6 +113,10 @@ public class BytecodeProviderImpl implements BytecodeProvider {
}
}
public ByteBuddyProxyHelper getByteBuddyProxyHelper() {
return byteBuddyProxyHelper;
}
private static class GetPropertyValues implements ByteCodeAppender {
private final Class clazz;
@ -271,11 +284,12 @@ public class BytecodeProviderImpl implements BytecodeProvider {
@Override
public Enhancer getEnhancer(EnhancementContext enhancementContext) {
return new EnhancerImpl( enhancementContext, bytebuddy );
return new EnhancerImpl( enhancementContext, byteBuddyState );
}
@Override
public void resetCaches() {
bytebuddy.clearState();
byteBuddyState.clearState();
}
}

View File

@ -11,22 +11,26 @@ import org.hibernate.bytecode.spi.ProxyFactoryFactory;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.proxy.ProxyFactory;
import org.hibernate.proxy.pojo.bytebuddy.ByteBuddyProxyFactory;
import org.hibernate.proxy.pojo.bytebuddy.ByteBuddyProxyHelper;
public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory {
private final ByteBuddyState bytebuddy;
private final ByteBuddyState byteBuddyState;
public ProxyFactoryFactoryImpl(ByteBuddyState bytebuddy) {
this.bytebuddy = bytebuddy;
private final ByteBuddyProxyHelper byteBuddyProxyHelper;
public ProxyFactoryFactoryImpl(ByteBuddyState byteBuddyState, ByteBuddyProxyHelper byteBuddyProxyHelper) {
this.byteBuddyState = byteBuddyState;
this.byteBuddyProxyHelper = byteBuddyProxyHelper;
}
@Override
public ProxyFactory buildProxyFactory(SessionFactoryImplementor sessionFactory) {
return new ByteBuddyProxyFactory();
return new ByteBuddyProxyFactory( byteBuddyProxyHelper );
}
@Override
public BasicProxyFactory buildBasicProxyFactory(Class superClass, Class[] interfaces) {
return new BasicProxyFactoryImpl( superClass, interfaces, bytebuddy );
return new BasicProxyFactoryImpl( superClass, interfaces, byteBuddyState );
}
}

View File

@ -6,16 +6,13 @@
*/
package org.hibernate.proxy.pojo.bytebuddy;
import static org.hibernate.internal.CoreLogging.messageLogger;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.bytecode.internal.bytebuddy.ByteBuddyState;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.CoreMessageLogger;
@ -26,28 +23,11 @@ import org.hibernate.proxy.ProxyConfiguration;
import org.hibernate.proxy.ProxyFactory;
import org.hibernate.type.CompositeType;
import net.bytebuddy.NamingStrategy;
import net.bytebuddy.TypeCache;
import net.bytebuddy.description.modifier.Visibility;
import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy;
import net.bytebuddy.implementation.FieldAccessor;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.SuperMethodCall;
import net.bytebuddy.implementation.bytecode.assign.Assigner;
import static net.bytebuddy.matcher.ElementMatchers.isFinalizer;
import static net.bytebuddy.matcher.ElementMatchers.isSynthetic;
import static net.bytebuddy.matcher.ElementMatchers.isVirtual;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.returns;
import static org.hibernate.internal.CoreLogging.messageLogger;
public class ByteBuddyProxyFactory implements ProxyFactory, Serializable {
private static final CoreMessageLogger LOG = messageLogger( ByteBuddyProxyFactory.class );
private static final String PROXY_NAMING_SUFFIX = Environment.useLegacyProxyClassnames() ? "HibernateProxy$" : "HibernateProxy";
private final ByteBuddyProxyHelper byteBuddyProxyHelper;
private Class persistentClass;
private String entityName;
@ -59,6 +39,10 @@ public class ByteBuddyProxyFactory implements ProxyFactory, Serializable {
private Class proxyClass;
public ByteBuddyProxyFactory(ByteBuddyProxyHelper byteBuddyProxyHelper) {
this.byteBuddyProxyHelper = byteBuddyProxyHelper;
}
@Override
public void postInstantiate(
String entityName,
@ -75,7 +59,7 @@ public class ByteBuddyProxyFactory implements ProxyFactory, Serializable {
this.componentIdType = componentIdType;
this.overridesEquals = ReflectHelper.overridesEquals( persistentClass );
this.proxyClass = buildProxy( persistentClass, this.interfaces );
this.proxyClass = byteBuddyProxyHelper.buildProxy( persistentClass, this.interfaces );
}
private Class[] toArray(Set<Class> interfaces) {
@ -86,35 +70,6 @@ public class ByteBuddyProxyFactory implements ProxyFactory, Serializable {
return interfaces.toArray( new Class[interfaces.size()] );
}
public static Class buildProxy(
final Class persistentClass,
final Class[] interfaces) {
Set<Class<?>> key = new HashSet<Class<?>>();
if ( interfaces.length == 1 ) {
key.add( persistentClass );
}
key.addAll( Arrays.<Class<?>>asList( interfaces ) );
final TypeCache<TypeCache.SimpleKey> cacheForProxies = ByteBuddyState.getCacheForProxies();
return cacheForProxies.findOrInsert( persistentClass.getClassLoader(), new TypeCache.SimpleKey(key), () ->
ByteBuddyState.getStaticByteBuddyInstance()
.ignore( isSynthetic().and( named( "getMetaClass" ).and( returns( td -> "groovy.lang.MetaClass".equals( td.getName() ) ) ) ) )
.with( new NamingStrategy.SuffixingRandom( PROXY_NAMING_SUFFIX, new NamingStrategy.SuffixingRandom.BaseNameResolver.ForFixedValue( persistentClass.getName() ) ) )
.subclass( interfaces.length == 1 ? persistentClass : Object.class, ConstructorStrategy.Default.IMITATE_SUPER_CLASS_OPENING )
.implement( (Type[]) interfaces )
.method( isVirtual().and( not( isFinalizer() ) ) )
.intercept( MethodDelegation.to( ProxyConfiguration.InterceptorDispatcher.class ) )
.method( nameStartsWith( "$$_hibernate_" ).and( isVirtual() ) )
.intercept( SuperMethodCall.INSTANCE )
.defineField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME, ProxyConfiguration.Interceptor.class, Visibility.PRIVATE )
.implement( ProxyConfiguration.class )
.intercept( FieldAccessor.ofField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME ).withAssigner( Assigner.DEFAULT, Assigner.Typing.DYNAMIC ) )
.make()
.load( persistentClass.getClassLoader(), ByteBuddyState.resolveClassLoadingStrategy( persistentClass ) )
.getLoaded(), cacheForProxies );
}
@Override
public HibernateProxy getProxy(
Serializable id,
@ -142,83 +97,4 @@ public class ByteBuddyProxyFactory implements ProxyFactory, Serializable {
throw new HibernateException( LOG.bytecodeEnhancementFailed( entityName ), t );
}
}
public static HibernateProxy deserializeProxy(SerializableProxy serializableProxy) {
final ByteBuddyInterceptor interceptor = new ByteBuddyInterceptor(
serializableProxy.getEntityName(),
serializableProxy.getPersistentClass(),
serializableProxy.getInterfaces(),
serializableProxy.getId(),
resolveIdGetterMethod( serializableProxy ),
resolveIdSetterMethod( serializableProxy ),
serializableProxy.getComponentIdType(),
null,
ReflectHelper.overridesEquals( serializableProxy.getPersistentClass() )
);
// note: interface is assumed to already contain HibernateProxy.class
try {
final Class proxyClass = buildProxy(
serializableProxy.getPersistentClass(),
serializableProxy.getInterfaces()
);
final HibernateProxy proxy = (HibernateProxy) proxyClass.newInstance();
( (ProxyConfiguration) proxy ).$$_hibernate_set_interceptor( interceptor );
return proxy;
}
catch (Throwable t) {
final String message = LOG.bytecodeEnhancementFailed( serializableProxy.getEntityName() );
LOG.error( message, t );
throw new HibernateException( message, t );
}
}
@SuppressWarnings("unchecked")
private static Method resolveIdGetterMethod(SerializableProxy serializableProxy) {
if ( serializableProxy.getIdentifierGetterMethodName() == null ) {
return null;
}
try {
return serializableProxy.getIdentifierGetterMethodClass().getDeclaredMethod( serializableProxy.getIdentifierGetterMethodName() );
}
catch (NoSuchMethodException e) {
throw new HibernateException(
String.format(
Locale.ENGLISH,
"Unable to deserialize proxy [%s, %s]; could not locate id getter method [%s] on entity class [%s]",
serializableProxy.getEntityName(),
serializableProxy.getId(),
serializableProxy.getIdentifierGetterMethodName(),
serializableProxy.getIdentifierGetterMethodClass()
)
);
}
}
@SuppressWarnings("unchecked")
private static Method resolveIdSetterMethod(SerializableProxy serializableProxy) {
if ( serializableProxy.getIdentifierSetterMethodName() == null ) {
return null;
}
try {
return serializableProxy.getIdentifierSetterMethodClass().getDeclaredMethod(
serializableProxy.getIdentifierSetterMethodName(),
serializableProxy.getIdentifierSetterMethodParams()
);
}
catch (NoSuchMethodException e) {
throw new HibernateException(
String.format(
Locale.ENGLISH,
"Unable to deserialize proxy [%s, %s]; could not locate id setter method [%s] on entity class [%s]",
serializableProxy.getEntityName(),
serializableProxy.getId(),
serializableProxy.getIdentifierSetterMethodName(),
serializableProxy.getIdentifierSetterMethodClass()
)
);
}
}
}

View File

@ -0,0 +1,168 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.proxy.pojo.bytebuddy;
import static net.bytebuddy.matcher.ElementMatchers.isFinalizer;
import static net.bytebuddy.matcher.ElementMatchers.isSynthetic;
import static net.bytebuddy.matcher.ElementMatchers.isVirtual;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.returns;
import static org.hibernate.internal.CoreLogging.messageLogger;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.bytecode.internal.bytebuddy.ByteBuddyState;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.ProxyConfiguration;
import org.hibernate.proxy.ProxyFactory;
import org.hibernate.type.CompositeType;
import net.bytebuddy.NamingStrategy;
import net.bytebuddy.TypeCache;
import net.bytebuddy.description.modifier.Visibility;
import net.bytebuddy.dynamic.DynamicType.Unloaded;
import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy;
import net.bytebuddy.implementation.FieldAccessor;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.SuperMethodCall;
import net.bytebuddy.implementation.bytecode.assign.Assigner;
public class ByteBuddyProxyHelper implements Serializable {
private static final CoreMessageLogger LOG = messageLogger( ByteBuddyProxyHelper.class );
private static final String PROXY_NAMING_SUFFIX = Environment.useLegacyProxyClassnames() ? "HibernateProxy$" : "HibernateProxy";
private final ByteBuddyState byteBuddyState;
public ByteBuddyProxyHelper(ByteBuddyState byteBuddyState) {
this.byteBuddyState = byteBuddyState;
}
public Class buildProxy(
final Class persistentClass,
final Class[] interfaces) {
Set<Class<?>> key = new HashSet<Class<?>>();
if ( interfaces.length == 1 ) {
key.add( persistentClass );
}
key.addAll( Arrays.<Class<?>>asList( interfaces ) );
final TypeCache<TypeCache.SimpleKey> cacheForProxies = byteBuddyState.getCacheForProxies();
return cacheForProxies.findOrInsert( persistentClass.getClassLoader(), new TypeCache.SimpleKey(key), () ->
byteBuddyState.getCurrentByteBuddy()
.ignore( isSynthetic().and( named( "getMetaClass" ).and( returns( td -> "groovy.lang.MetaClass".equals( td.getName() ) ) ) ) )
.with( new NamingStrategy.SuffixingRandom( PROXY_NAMING_SUFFIX, new NamingStrategy.SuffixingRandom.BaseNameResolver.ForFixedValue( persistentClass.getName() ) ) )
.subclass( interfaces.length == 1 ? persistentClass : Object.class, ConstructorStrategy.Default.IMITATE_SUPER_CLASS_OPENING )
.implement( (Type[]) interfaces )
.method( isVirtual().and( not( isFinalizer() ) ) )
.intercept( MethodDelegation.to( ProxyConfiguration.InterceptorDispatcher.class ) )
.method( nameStartsWith( "$$_hibernate_" ).and( isVirtual() ) )
.intercept( SuperMethodCall.INSTANCE )
.defineField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME, ProxyConfiguration.Interceptor.class, Visibility.PRIVATE )
.implement( ProxyConfiguration.class )
.intercept( FieldAccessor.ofField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME ).withAssigner( Assigner.DEFAULT, Assigner.Typing.DYNAMIC ) )
.make()
.load( persistentClass.getClassLoader(), ByteBuddyState.resolveClassLoadingStrategy( persistentClass ) )
.getLoaded(), cacheForProxies );
}
public HibernateProxy deserializeProxy(SerializableProxy serializableProxy) {
final ByteBuddyInterceptor interceptor = new ByteBuddyInterceptor(
serializableProxy.getEntityName(),
serializableProxy.getPersistentClass(),
serializableProxy.getInterfaces(),
serializableProxy.getId(),
resolveIdGetterMethod( serializableProxy ),
resolveIdSetterMethod( serializableProxy ),
serializableProxy.getComponentIdType(),
null,
ReflectHelper.overridesEquals( serializableProxy.getPersistentClass() )
);
// note: interface is assumed to already contain HibernateProxy.class
try {
final Class proxyClass = buildProxy(
serializableProxy.getPersistentClass(),
serializableProxy.getInterfaces()
);
final HibernateProxy proxy = (HibernateProxy) proxyClass.newInstance();
( (ProxyConfiguration) proxy ).$$_hibernate_set_interceptor( interceptor );
return proxy;
}
catch (Throwable t) {
final String message = LOG.bytecodeEnhancementFailed( serializableProxy.getEntityName() );
LOG.error( message, t );
throw new HibernateException( message, t );
}
}
@SuppressWarnings("unchecked")
private static Method resolveIdGetterMethod(SerializableProxy serializableProxy) {
if ( serializableProxy.getIdentifierGetterMethodName() == null ) {
return null;
}
try {
return serializableProxy.getIdentifierGetterMethodClass().getDeclaredMethod( serializableProxy.getIdentifierGetterMethodName() );
}
catch (NoSuchMethodException e) {
throw new HibernateException(
String.format(
Locale.ENGLISH,
"Unable to deserialize proxy [%s, %s]; could not locate id getter method [%s] on entity class [%s]",
serializableProxy.getEntityName(),
serializableProxy.getId(),
serializableProxy.getIdentifierGetterMethodName(),
serializableProxy.getIdentifierGetterMethodClass()
)
);
}
}
@SuppressWarnings("unchecked")
private static Method resolveIdSetterMethod(SerializableProxy serializableProxy) {
if ( serializableProxy.getIdentifierSetterMethodName() == null ) {
return null;
}
try {
return serializableProxy.getIdentifierSetterMethodClass().getDeclaredMethod(
serializableProxy.getIdentifierSetterMethodName(),
serializableProxy.getIdentifierSetterMethodParams()
);
}
catch (NoSuchMethodException e) {
throw new HibernateException(
String.format(
Locale.ENGLISH,
"Unable to deserialize proxy [%s, %s]; could not locate id setter method [%s] on entity class [%s]",
serializableProxy.getEntityName(),
serializableProxy.getId(),
serializableProxy.getIdentifierSetterMethodName(),
serializableProxy.getIdentifierSetterMethodClass()
)
);
}
}
}

View File

@ -9,6 +9,11 @@ package org.hibernate.proxy.pojo.bytebuddy;
import java.io.Serializable;
import java.lang.reflect.Method;
import org.hibernate.bytecode.internal.bytebuddy.BytecodeProviderImpl;
import org.hibernate.bytecode.internal.bytebuddy.ProxyFactoryFactoryImpl;
import org.hibernate.bytecode.spi.BytecodeProvider;
import org.hibernate.bytecode.spi.ProxyFactoryFactory;
import org.hibernate.cfg.Environment;
import org.hibernate.proxy.AbstractSerializableProxy;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.type.CompositeType;
@ -125,7 +130,12 @@ public final class SerializableProxy extends AbstractSerializableProxy {
}
private Object readResolve() {
HibernateProxy proxy = ByteBuddyProxyFactory.deserializeProxy( this );
BytecodeProvider bytecodeProvider = Environment.getBytecodeProvider();
if ( !( bytecodeProvider instanceof BytecodeProviderImpl ) ) {
throw new IllegalStateException( "The bytecode provider is not ByteBuddy, unable to deserialize a ByteBuddy proxy." );
}
HibernateProxy proxy = ( (BytecodeProviderImpl) bytecodeProvider ).getByteBuddyProxyHelper().deserializeProxy( this );
afterDeserialization( (ByteBuddyInterceptor) proxy.getHibernateLazyInitializer() );
return proxy;
}

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.proxy.bytebuddy;
package org.hibernate.bytecode.internal.bytebuddy;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.bytecode.enhancement.bytebuddy;
package org.hibernate.bytecode.internal.bytebuddy;
import java.io.ByteArrayOutputStream;
import java.io.IOException;