HHH-16058 Removing Environment#getBytecodeProvider

This commit is contained in:
Sanne Grinovero 2023-01-18 14:41:42 +00:00 committed by Sanne Grinovero
parent 1e21d1c6d1
commit 800873c43d
15 changed files with 191 additions and 100 deletions

View File

@ -8,13 +8,23 @@ package org.hibernate.bytecode.internal;
import java.util.Map; import java.util.Map;
import org.hibernate.Internal;
import org.hibernate.boot.registry.StandardServiceInitiator; import org.hibernate.boot.registry.StandardServiceInitiator;
import org.hibernate.bytecode.spi.BytecodeProvider; import org.hibernate.bytecode.spi.BytecodeProvider;
import org.hibernate.cfg.Environment; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.jboss.logging.Logger;
import static org.hibernate.cfg.AvailableSettings.BYTECODE_PROVIDER;
public final class BytecodeProviderInitiator implements StandardServiceInitiator<BytecodeProvider> { public final class BytecodeProviderInitiator implements StandardServiceInitiator<BytecodeProvider> {
public static final String BYTECODE_PROVIDER_NAME_BYTEBUDDY = "bytebuddy";
public static final String BYTECODE_PROVIDER_NAME_NONE = "none";
public static final String BYTECODE_PROVIDER_NAME_DEFAULT = BYTECODE_PROVIDER_NAME_BYTEBUDDY;
/** /**
* Singleton access * Singleton access
*/ */
@ -22,9 +32,8 @@ public final class BytecodeProviderInitiator implements StandardServiceInitiator
@Override @Override
public BytecodeProvider initiateService(Map<String, Object> configurationValues, ServiceRegistryImplementor registry) { public BytecodeProvider initiateService(Map<String, Object> configurationValues, ServiceRegistryImplementor registry) {
// TODO in 6 this will no longer use Environment, which is configured via global environment variables, String provider = ConfigurationHelper.getString( BYTECODE_PROVIDER, configurationValues, BYTECODE_PROVIDER_NAME_DEFAULT );
// but move to a component which can be reconfigured differently in each registry. return buildBytecodeProvider( provider );
return Environment.getBytecodeProvider();
} }
@Override @Override
@ -32,4 +41,35 @@ public final class BytecodeProviderInitiator implements StandardServiceInitiator
return BytecodeProvider.class; return BytecodeProvider.class;
} }
@Internal
public static BytecodeProvider buildDefaultBytecodeProvider() {
return buildBytecodeProvider( BYTECODE_PROVIDER_NAME_BYTEBUDDY );
}
@Internal
public static BytecodeProvider buildBytecodeProvider(String providerName) {
CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, BytecodeProviderInitiator.class.getName() );
LOG.bytecodeProvider( providerName );
if ( BYTECODE_PROVIDER_NAME_NONE.equals( providerName ) ) {
return new org.hibernate.bytecode.internal.none.BytecodeProviderImpl();
}
if ( BYTECODE_PROVIDER_NAME_BYTEBUDDY.equals( providerName ) ) {
return new org.hibernate.bytecode.internal.bytebuddy.BytecodeProviderImpl();
}
// There is no need to support plugging in a custom BytecodeProvider via FQCN
// as it's possible to plug a custom BytecodeProviderInitiator into the bootstrap.
//
// This also allows integrators to inject a BytecodeProvider instance which has some
// state: particularly useful to inject proxy definitions which have been prepared in
// advance.
// See also https://hibernate.atlassian.net/browse/HHH-13804 and how this was solved in
// Quarkus.
LOG.unknownBytecodeProvider( providerName, BYTECODE_PROVIDER_NAME_DEFAULT );
return new org.hibernate.bytecode.internal.bytebuddy.BytecodeProviderImpl();
}
} }

View File

@ -1533,7 +1533,7 @@ public interface AvailableSettings {
String CHECK_NULLABILITY = "hibernate.check_nullability"; String CHECK_NULLABILITY = "hibernate.check_nullability";
/** /**
* Selects a bytecode enhancment library. * Selects a bytecode enhancement library.
* <p> * <p>
* At present only bytebuddy is supported, bytebuddy being the default since version 5.3. * At present only bytebuddy is supported, bytebuddy being the default since version 5.3.
*/ */

View File

@ -13,6 +13,7 @@ import java.util.Properties;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.Internal; import org.hibernate.Internal;
import org.hibernate.Version; import org.hibernate.Version;
import org.hibernate.bytecode.internal.BytecodeProviderInitiator;
import org.hibernate.bytecode.spi.BytecodeProvider; import org.hibernate.bytecode.spi.BytecodeProvider;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ConfigHelper; import org.hibernate.internal.util.ConfigHelper;
@ -35,8 +36,8 @@ import static org.hibernate.internal.log.DeprecationLogger.DEPRECATION_LOGGER;
* always determined by the {@code Environment} properties in {@link #getProperties()}. * always determined by the {@code Environment} properties in {@link #getProperties()}.
* </ul> * </ul>
* <p> * <p>
* The only system-level properties are {@value #USE_REFLECTION_OPTIMIZER} and * The only system-level property is {@value #USE_REFLECTION_OPTIMIZER},
* {@value #BYTECODE_PROVIDER}. * and it's deprecated.
* <p> * <p>
* {@code Environment} properties are populated by calling {@link System#getProperties()} * {@code Environment} properties are populated by calling {@link System#getProperties()}
* and then from a resource named {@code /hibernate.properties}, if it exists. System * and then from a resource named {@code /hibernate.properties}, if it exists. System
@ -141,7 +142,6 @@ import static org.hibernate.internal.log.DeprecationLogger.DEPRECATION_LOGGER;
public final class Environment implements AvailableSettings { public final class Environment implements AvailableSettings {
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, Environment.class.getName()); private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, Environment.class.getName());
private static final BytecodeProvider BYTECODE_PROVIDER_INSTANCE;
private static final boolean ENABLE_REFLECTION_OPTIMIZER; private static final boolean ENABLE_REFLECTION_OPTIMIZER;
private static final Properties GLOBAL_PROPERTIES; private static final Properties GLOBAL_PROPERTIES;
@ -193,8 +193,6 @@ public final class Environment implements AvailableSettings {
else { else {
DEPRECATION_LOGGER.deprecatedSettingForRemoval( USE_REFLECTION_OPTIMIZER, "true" ); DEPRECATION_LOGGER.deprecatedSettingForRemoval( USE_REFLECTION_OPTIMIZER, "true" );
} }
BYTECODE_PROVIDER_INSTANCE = buildBytecodeProvider( GLOBAL_PROPERTIES );
} }
/** /**
@ -203,12 +201,11 @@ public final class Environment implements AvailableSettings {
* @return True if reflection optimization should be used; false otherwise. * @return True if reflection optimization should be used; false otherwise.
* *
* @see #USE_REFLECTION_OPTIMIZER * @see #USE_REFLECTION_OPTIMIZER
* @see #getBytecodeProvider()
* @see BytecodeProvider#getReflectionOptimizer * @see BytecodeProvider#getReflectionOptimizer
* *
* @deprecated Deprecated to indicate that the method will be moved to * @deprecated Deprecated to indicate that the method will be moved to
* {@link org.hibernate.boot.spi.SessionFactoryOptions} / * {@link org.hibernate.boot.spi.SessionFactoryOptions} /
* {@link org.hibernate.boot.SessionFactoryBuilder} - probably in 6.0. * {@link org.hibernate.boot.SessionFactoryBuilder}.
* See <a href="https://hibernate.atlassian.net/browse/HHH-12194">HHH-12194</a> and * See <a href="https://hibernate.atlassian.net/browse/HHH-12194">HHH-12194</a> and
* <a href="https://hibernate.atlassian.net/browse/HHH-12193">HHH-12193</a> for details * <a href="https://hibernate.atlassian.net/browse/HHH-12193">HHH-12193</a> for details
*/ */
@ -217,23 +214,11 @@ public final class Environment implements AvailableSettings {
return ENABLE_REFLECTION_OPTIMIZER; return ENABLE_REFLECTION_OPTIMIZER;
} }
/**
* @deprecated Deprecated to indicate that the method will be moved to
* {@link org.hibernate.boot.spi.SessionFactoryOptions} /
* {@link org.hibernate.boot.SessionFactoryBuilder} - probably in 6.0.
* See <a href="https://hibernate.atlassian.net/browse/HHH-12194">HHH-12194</a> and
* <a href="https://hibernate.atlassian.net/browse/HHH-12193">HHH-12193</a> for details
*/
@Deprecated
public static BytecodeProvider getBytecodeProvider() {
return BYTECODE_PROVIDER_INSTANCE;
}
/** /**
* Disallow instantiation * Disallow instantiation
*/ */
private Environment() { private Environment() {
throw new UnsupportedOperationException(); //not to be constructed
} }
/** /**
@ -246,36 +231,36 @@ public final class Environment implements AvailableSettings {
return copy; return copy;
} }
/**
* @deprecated Replaced by {@code org.hibernate.bytecode.internal.BytecodeProviderInitiator#BYTECODE_PROVIDER_NAME_BYTEBUDDY},
* however note that that's an internal contract: a different BytecodeProvider Initiator might ignore these constants
* or interpret them differently.
*/
@Deprecated(forRemoval = true)
public static final String BYTECODE_PROVIDER_NAME_BYTEBUDDY = "bytebuddy"; public static final String BYTECODE_PROVIDER_NAME_BYTEBUDDY = "bytebuddy";
public static final String BYTECODE_PROVIDER_NAME_NONE = "none";
public static final String BYTECODE_PROVIDER_NAME_DEFAULT = BYTECODE_PROVIDER_NAME_BYTEBUDDY;
/**
* @deprecated Replaced by {@code org.hibernate.bytecode.internal.BytecodeProviderInitiator#BYTECODE_PROVIDER_NAME_NONE},
* however note that that's an internal contract: a different BytecodeProvider Initiator might ignore these constants
* or interpret them differently.
*/
@Deprecated(forRemoval = true)
public static final String BYTECODE_PROVIDER_NAME_NONE = "none";
/**
* @deprecated Replaced by {@code org.hibernate.bytecode.internal.BytecodeProviderInitiator#BYTECODE_PROVIDER_NAME_DEFAULT}
* however note that that's an internal contract: a different BytecodeProvider Initiator might apply a different default.
*/
@Deprecated(forRemoval = true)
public static final String BYTECODE_PROVIDER_NAME_DEFAULT = BytecodeProviderInitiator.BYTECODE_PROVIDER_NAME_BYTEBUDDY;
/**
* @deprecated this will be removed; retrieval of the BytecodeProvider should be performed via the {@link org.hibernate.service.ServiceRegistry}.
*/
@Deprecated(forRemoval = true)
public static BytecodeProvider buildBytecodeProvider(Properties properties) { public static BytecodeProvider buildBytecodeProvider(Properties properties) {
String provider = ConfigurationHelper.getString( BYTECODE_PROVIDER, properties, BYTECODE_PROVIDER_NAME_DEFAULT ); String provider = ConfigurationHelper.getString( BYTECODE_PROVIDER, properties, BYTECODE_PROVIDER_NAME_DEFAULT );
return buildBytecodeProvider( provider ); return BytecodeProviderInitiator.buildBytecodeProvider( provider );
} }
private static BytecodeProvider buildBytecodeProvider(String providerName) {
if ( BYTECODE_PROVIDER_NAME_NONE.equals( providerName ) ) {
return new org.hibernate.bytecode.internal.none.BytecodeProviderImpl();
}
if ( BYTECODE_PROVIDER_NAME_BYTEBUDDY.equals( providerName ) ) {
return new org.hibernate.bytecode.internal.bytebuddy.BytecodeProviderImpl();
}
LOG.bytecodeProvider( providerName );
// there is no need to support plugging in a custom BytecodeProvider via FQCN:
// - the static helper methods on this class are deprecated
// - it's possible to plug a custom BytecodeProvider directly into the ServiceRegistry
//
// This also allows integrators to inject a BytecodeProvider instance which has some
// state; particularly useful to inject proxy definitions which have been prepared in
// advance.
// See also https://hibernate.atlassian.net/browse/HHH-13804 and how this was solved in
// Quarkus.
LOG.unknownBytecodeProvider( providerName, BYTECODE_PROVIDER_NAME_DEFAULT );
return new org.hibernate.bytecode.internal.bytebuddy.BytecodeProviderImpl();
}
} }

View File

@ -1290,7 +1290,7 @@ public interface CoreMessageLogger extends BasicLogger {
void unexpectedRowCounts(); void unexpectedRowCounts();
@LogMessage(level = WARN) @LogMessage(level = WARN)
@Message(value = "unrecognized bytecode provider [%s], using [%s] by default", id = 382) @Message(value = "Unrecognized bytecode provider [%s]; using the default implementation [%s]", id = 382)
void unknownBytecodeProvider(String providerName, String defaultProvider); void unknownBytecodeProvider(String providerName, String defaultProvider);
@LogMessage(level = WARN) @LogMessage(level = WARN)

View File

@ -7,10 +7,13 @@
package org.hibernate.jpa.internal.enhance; package org.hibernate.jpa.internal.enhance;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
import java.util.Objects;
import org.hibernate.bytecode.enhance.spi.EnhancementContext; import org.hibernate.bytecode.enhance.spi.EnhancementContext;
import org.hibernate.bytecode.enhance.spi.EnhancementContextWrapper; import org.hibernate.bytecode.enhance.spi.EnhancementContextWrapper;
import org.hibernate.bytecode.enhance.spi.Enhancer; import org.hibernate.bytecode.enhance.spi.Enhancer;
import org.hibernate.bytecode.internal.BytecodeProviderInitiator;
import org.hibernate.bytecode.spi.BytecodeProvider;
import org.hibernate.bytecode.spi.ClassTransformer; import org.hibernate.bytecode.spi.ClassTransformer;
import org.hibernate.cfg.Environment; import org.hibernate.cfg.Environment;
@ -23,9 +26,12 @@ import jakarta.persistence.spi.TransformerException;
public class EnhancingClassTransformerImpl implements ClassTransformer { public class EnhancingClassTransformerImpl implements ClassTransformer {
private final EnhancementContext enhancementContext; private final EnhancementContext enhancementContext;
private final BytecodeProvider bytecodeProvider;
public EnhancingClassTransformerImpl(EnhancementContext enhancementContext) { public EnhancingClassTransformerImpl(EnhancementContext enhancementContext) {
Objects.requireNonNull( enhancementContext );
this.enhancementContext = enhancementContext; this.enhancementContext = enhancementContext;
this.bytecodeProvider = BytecodeProviderInitiator.buildDefaultBytecodeProvider();
} }
@Override @Override
@ -41,12 +47,15 @@ public class EnhancingClassTransformerImpl implements ClassTransformer {
// It also assumed that all calls come from the same class loader, which is fair, but this makes it more robust. // It also assumed that all calls come from the same class loader, which is fair, but this makes it more robust.
try { try {
Enhancer enhancer = Environment.getBytecodeProvider().getEnhancer( new EnhancementContextWrapper( enhancementContext, loader ) ); Enhancer enhancer = bytecodeProvider.getEnhancer( new EnhancementContextWrapper( enhancementContext, loader ) );
return enhancer.enhance( className, classfileBuffer ); return enhancer.enhance( className, classfileBuffer );
} }
catch (final Exception e) { catch (final Exception e) {
throw new TransformerException( "Error performing enhancement of " + className, e ); throw new TransformerException( "Error performing enhancement of " + className, e );
} }
finally {
bytecodeProvider.resetCaches();
}
} }
} }

View File

@ -13,13 +13,12 @@ import java.util.function.Supplier;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.boot.registry.selector.spi.StrategySelector; import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.bytecode.spi.BytecodeProvider;
import org.hibernate.bytecode.spi.ProxyFactoryFactory; import org.hibernate.bytecode.spi.ProxyFactoryFactory;
import org.hibernate.bytecode.spi.ReflectionOptimizer; import org.hibernate.bytecode.spi.ReflectionOptimizer;
import org.hibernate.cfg.Environment; import org.hibernate.cfg.Environment;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.mapping.Backref; import org.hibernate.mapping.Backref;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.mapping.IndexBackref; import org.hibernate.mapping.IndexBackref;
@ -33,6 +32,7 @@ import org.hibernate.property.access.internal.PropertyAccessStrategyIndexBackRef
import org.hibernate.property.access.spi.BuiltInPropertyAccessStrategies; import org.hibernate.property.access.spi.BuiltInPropertyAccessStrategies;
import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.property.access.spi.PropertyAccessStrategy; import org.hibernate.property.access.spi.PropertyAccessStrategy;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry; import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.internal.CompositeUserTypeJavaTypeWrapper; import org.hibernate.type.internal.CompositeUserTypeJavaTypeWrapper;
@ -187,8 +187,9 @@ public class EmbeddableRepresentationStrategyPojo extends AbstractEmbeddableRepr
propertyAccessMap.put( property.getName(), getPropertyAccesses()[i] ); propertyAccessMap.put( property.getName(), getPropertyAccesses()[i] );
i++; i++;
} }
final BytecodeProvider bytecodeProvider = creationContext.getServiceRegistry().getService( BytecodeProvider.class );
return Environment.getBytecodeProvider().getReflectionOptimizer( return bytecodeProvider.getReflectionOptimizer(
bootDescriptor.getComponentClass(), bootDescriptor.getComponentClass(),
propertyAccessMap propertyAccessMap
); );

View File

@ -20,7 +20,6 @@ import org.hibernate.bytecode.spi.ReflectionOptimizer;
import org.hibernate.bytecode.spi.ReflectionOptimizer.InstantiationOptimizer; import org.hibernate.bytecode.spi.ReflectionOptimizer.InstantiationOptimizer;
import org.hibernate.cfg.Environment; import org.hibernate.cfg.Environment;
import org.hibernate.classic.Lifecycle; import org.hibernate.classic.Lifecycle;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
@ -140,8 +139,7 @@ public class EntityRepresentationStrategyPojoStandard implements EntityRepresent
identifierPropertyAccess = makePropertyAccess( identifierProperty ); identifierPropertyAccess = makePropertyAccess( identifierProperty );
} }
// final BytecodeProvider bytecodeProvider = creationContext.getBootstrapContext().getBytecodeProvider(); final BytecodeProvider bytecodeProvider = creationContext.getBootstrapContext().getServiceRegistry().getService( BytecodeProvider.class );
final BytecodeProvider bytecodeProvider = Environment.getBytecodeProvider();
final EntityMetamodel entityMetamodel = runtimeDescriptor.getEntityMetamodel(); final EntityMetamodel entityMetamodel = runtimeDescriptor.getEntityMetamodel();
ProxyFactory proxyFactory = null; ProxyFactory proxyFactory = null;

View File

@ -265,15 +265,16 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
/** /**
* Initialize internal state based on the currently attached session, * Initialize internal state based on the currently attached session,
* in order to be ready to load data even after the proxy is detached from the session. * in order to be ready to load data even after the proxy is detached from the session.
*
* This method only has any effect if
* {@link SessionFactoryOptions#isInitializeLazyStateOutsideTransactionsEnabled()} is {@code true}.
*/ */
protected void prepareForPossibleLoadingOutsideTransaction() { protected void prepareForPossibleLoadingOutsideTransaction() {
if ( session != null ) { if ( session != null ) {
allowLoadOutsideTransaction = session.getFactory().getSessionFactoryOptions().isInitializeLazyStateOutsideTransactionsEnabled(); allowLoadOutsideTransaction = session.getFactory().getSessionFactoryOptions().isInitializeLazyStateOutsideTransactionsEnabled();
if ( allowLoadOutsideTransaction && sessionFactoryUuid == null ) { if ( sessionFactoryUuid == null ) {
//we're going to need the UUID even if we the SessionFactory configuration doesn't
// allow any operations on it, as we need it to match deserialized objects with
// the originating SessionFactory: at very least it's useful to actually get
// such configuration, so to know if such operation isn't allowed or configured otherwise.
sessionFactoryUuid = session.getFactory().getUuid(); sessionFactoryUuid = session.getFactory().getUuid();
} }
} }

View File

@ -17,7 +17,7 @@ public abstract class AbstractSerializableProxy implements Serializable {
private final String entityName; private final String entityName;
private final Object id; private final Object id;
private final Boolean readOnly; private final Boolean readOnly;
private final String sessionFactoryUuid; protected final String sessionFactoryUuid;
private final boolean allowLoadOutsideTransaction; private final boolean allowLoadOutsideTransaction;
protected AbstractSerializableProxy( protected AbstractSerializableProxy(

View File

@ -6,12 +6,13 @@
*/ */
package org.hibernate.proxy.pojo.bytebuddy; package org.hibernate.proxy.pojo.bytebuddy;
import java.io.Serializable;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Objects;
import org.hibernate.bytecode.internal.bytebuddy.BytecodeProviderImpl; import org.hibernate.bytecode.internal.bytebuddy.BytecodeProviderImpl;
import org.hibernate.bytecode.spi.BytecodeProvider; import org.hibernate.bytecode.spi.BytecodeProvider;
import org.hibernate.cfg.Environment; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.SessionFactoryRegistry;
import org.hibernate.proxy.AbstractSerializableProxy; import org.hibernate.proxy.AbstractSerializableProxy;
import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.HibernateProxy;
import org.hibernate.type.CompositeType; import org.hibernate.type.CompositeType;
@ -109,13 +110,32 @@ public final class SerializableProxy extends AbstractSerializableProxy {
} }
private Object readResolve() { private Object readResolve() {
BytecodeProvider bytecodeProvider = Environment.getBytecodeProvider(); final SessionFactoryImplementor sessionFactory = retrieveMatchingSessionFactory( this.sessionFactoryUuid );
if ( !( bytecodeProvider instanceof BytecodeProviderImpl ) ) { BytecodeProviderImpl byteBuddyBytecodeProvider = retrieveByteBuddyBytecodeProvider( sessionFactory );
throw new IllegalStateException( "The bytecode provider is not ByteBuddy, unable to deserialize a ByteBuddy proxy." ); HibernateProxy proxy = byteBuddyBytecodeProvider.getByteBuddyProxyHelper().deserializeProxy( this );
}
HibernateProxy proxy = ( (BytecodeProviderImpl) bytecodeProvider ).getByteBuddyProxyHelper().deserializeProxy( this );
afterDeserialization( (ByteBuddyInterceptor) proxy.getHibernateLazyInitializer() ); afterDeserialization( (ByteBuddyInterceptor) proxy.getHibernateLazyInitializer() );
return proxy; return proxy;
} }
private static SessionFactoryImplementor retrieveMatchingSessionFactory(final String sessionFactoryUuid) {
Objects.requireNonNull( sessionFactoryUuid );
final SessionFactoryImplementor sessionFactory = SessionFactoryRegistry.INSTANCE.getSessionFactory( sessionFactoryUuid );
if ( sessionFactory != null ) {
return sessionFactory;
}
else {
throw new IllegalStateException( "Could not identify any active SessionFactory having UUID " + sessionFactoryUuid );
}
}
private static BytecodeProviderImpl retrieveByteBuddyBytecodeProvider(final SessionFactoryImplementor sessionFactory) {
final BytecodeProvider bytecodeProvider = sessionFactory.getServiceRegistry().getService( BytecodeProvider.class );
if ( bytecodeProvider instanceof BytecodeProviderImpl ) {
return (BytecodeProviderImpl) bytecodeProvider;
}
else {
throw new IllegalStateException( "Unable to deserialize a SerializableProxy proxy: the bytecode provider is not ByteBuddy." );
}
}
} }

View File

@ -6,14 +6,17 @@
*/ */
package org.hibernate.orm.test.bytecode; package org.hibernate.orm.test.bytecode;
import static org.hibernate.bytecode.internal.BytecodeProviderInitiator.buildDefaultBytecodeProvider;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import org.hibernate.bytecode.spi.BytecodeProvider; import org.hibernate.bytecode.spi.BytecodeProvider;
import org.hibernate.bytecode.spi.ReflectionOptimizer; import org.hibernate.bytecode.spi.ReflectionOptimizer;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase; import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
/** /**
@ -21,9 +24,23 @@ import org.junit.Test;
*/ */
public class ReflectionOptimizerTest extends BaseUnitTestCase { public class ReflectionOptimizerTest extends BaseUnitTestCase {
private static BytecodeProvider provider;
@BeforeClass
public static void initBytecodeProvider() {
provider = buildDefaultBytecodeProvider();
}
@AfterClass
public static void clearBytecodeProvider() {
if ( provider != null ) {
provider.resetCaches();
provider = null;
}
}
@Test @Test
public void testReflectionOptimization() { public void testReflectionOptimization() {
BytecodeProvider provider = Environment.getBytecodeProvider();
ReflectionOptimizer optimizer = provider.getReflectionOptimizer( ReflectionOptimizer optimizer = provider.getReflectionOptimizer(
Bean.class, Bean.class,
BeanReflectionHelper.getGetterNames(), BeanReflectionHelper.getGetterNames(),
@ -47,18 +64,16 @@ public class ReflectionOptimizerTest extends BaseUnitTestCase {
@Test @Test
@TestForIssue(jiraKey = "HHH-12584") @TestForIssue(jiraKey = "HHH-12584")
public void testAbstractClass() { public void testAbstractClass() {
BytecodeProvider provider = Environment.getBytecodeProvider();
ReflectionOptimizer reflectionOptimizer = provider.getReflectionOptimizer( AbstractClass.class, new String[]{ "getProperty" }, ReflectionOptimizer reflectionOptimizer = provider.getReflectionOptimizer( AbstractClass.class, new String[]{ "getProperty" },
new String[]{ "setProperty" }, new Class[]{ String.class } ); new String[]{ "setProperty" }, new Class[]{ String.class } );
assertNotNull( reflectionOptimizer ); assertNotNull( reflectionOptimizer );
} }
@Test @Test
@TestForIssue(jiraKey = "HHH-12584") @TestForIssue(jiraKey = "HHH-12584")
public void testInterface() { public void testInterface() {
BytecodeProvider provider = Environment.getBytecodeProvider();
ReflectionOptimizer reflectionOptimizer = provider.getReflectionOptimizer( Interface.class, new String[]{ "getProperty" }, ReflectionOptimizer reflectionOptimizer = provider.getReflectionOptimizer( Interface.class, new String[]{ "getProperty" },
new String[]{ "setProperty" }, new Class[]{ String.class } ); new String[]{ "setProperty" }, new Class[]{ String.class } );
assertNotNull( reflectionOptimizer ); assertNotNull( reflectionOptimizer );
} }
@ -88,4 +103,5 @@ public class ReflectionOptimizerTest extends BaseUnitTestCase {
void setProperty(String property); void setProperty(String property);
} }
} }

View File

@ -32,6 +32,8 @@ import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError; import org.junit.runners.model.InitializationError;
import org.junit.runners.model.RunnerBuilder; import org.junit.runners.model.RunnerBuilder;
import static org.hibernate.bytecode.internal.BytecodeProviderInitiator.buildDefaultBytecodeProvider;
/** /**
* @author Luis Barreiro * @author Luis Barreiro
*/ */
@ -182,7 +184,7 @@ public class BytecodeEnhancerRunner extends Suite {
EnhancementContext enhancerContext, EnhancementContext enhancerContext,
List<EnhancementSelector> selectors) { List<EnhancementSelector> selectors) {
return new EnhancingClassLoader( return new EnhancingClassLoader(
Environment.getBytecodeProvider().getEnhancer( enhancerContext ), buildDefaultBytecodeProvider().getEnhancer( enhancerContext ),
selectors selectors
); );
} }

View File

@ -14,6 +14,8 @@ import org.hibernate.bytecode.enhance.spi.EnhancementContext;
import org.hibernate.bytecode.enhance.spi.Enhancer; import org.hibernate.bytecode.enhance.spi.Enhancer;
import org.hibernate.bytecode.enhance.spi.UnloadedClass; import org.hibernate.bytecode.enhance.spi.UnloadedClass;
import org.hibernate.bytecode.enhance.spi.UnloadedField; import org.hibernate.bytecode.enhance.spi.UnloadedField;
import org.hibernate.bytecode.internal.BytecodeProviderInitiator;
import org.hibernate.bytecode.spi.BytecodeProvider;
import org.hibernate.cfg.Environment; import org.hibernate.cfg.Environment;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -30,6 +32,8 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import static org.hibernate.bytecode.internal.BytecodeProviderInitiator.buildDefaultBytecodeProvider;
/** /**
* Ant task for performing build-time enhancement of entity objects. * Ant task for performing build-time enhancement of entity objects.
* *
@ -162,16 +166,21 @@ public class EnhancementTask extends Task {
log( "Extended enhancement is enabled. Classes other than entities may be modified. You should consider access the entities using getter/setter methods and disable this property. Use at your own risk.", Project.MSG_WARN ); log( "Extended enhancement is enabled. Classes other than entities may be modified. You should consider access the entities using getter/setter methods and disable this property. Use at your own risk.", Project.MSG_WARN );
} }
Enhancer enhancer = Environment.getBytecodeProvider().getEnhancer( enhancementContext ); final BytecodeProvider bytecodeProvider = buildDefaultBytecodeProvider();
try {
Enhancer enhancer = bytecodeProvider.getEnhancer( enhancementContext );
for ( File file : sourceSet ) {
byte[] enhancedBytecode = doEnhancement( file, enhancer );
if ( enhancedBytecode == null ) {
continue;
}
writeOutEnhancedClass( enhancedBytecode, file );
for ( File file : sourceSet ) { log( "Successfully enhanced class [" + file + "]", Project.MSG_INFO );
byte[] enhancedBytecode = doEnhancement( file, enhancer );
if ( enhancedBytecode == null ) {
continue;
} }
writeOutEnhancedClass( enhancedBytecode, file ); }
finally {
log( "Successfully enhanced class [" + file + "]", Project.MSG_INFO ); bytecodeProvider.resetCaches();
} }
} }

View File

@ -38,10 +38,12 @@ import org.hibernate.bytecode.enhance.spi.EnhancementContext;
import org.hibernate.bytecode.enhance.spi.Enhancer; import org.hibernate.bytecode.enhance.spi.Enhancer;
import org.hibernate.bytecode.enhance.spi.UnloadedClass; import org.hibernate.bytecode.enhance.spi.UnloadedClass;
import org.hibernate.bytecode.enhance.spi.UnloadedField; import org.hibernate.bytecode.enhance.spi.UnloadedField;
import org.hibernate.cfg.Environment; import org.hibernate.bytecode.spi.BytecodeProvider;
import org.sonatype.plexus.build.incremental.BuildContext; import org.sonatype.plexus.build.incremental.BuildContext;
import static org.hibernate.bytecode.internal.BytecodeProviderInitiator.buildDefaultBytecodeProvider;
/** /**
* This plugin will enhance Entity objects. * This plugin will enhance Entity objects.
* *
@ -153,21 +155,28 @@ public class MavenEnhancePlugin extends AbstractMojo {
log.warn( "Extended enhancement is enabled. Classes other than entities may be modified. You should consider access the entities using getter/setter methods and disable this property. Use at your own risk." ); log.warn( "Extended enhancement is enabled. Classes other than entities may be modified. You should consider access the entities using getter/setter methods and disable this property. Use at your own risk." );
} }
final Enhancer enhancer = Environment.getBytecodeProvider().getEnhancer( enhancementContext ); //TODO allow the Maven plugin to configure the bytecode enhancer?
final BytecodeProvider bytecodeProvider = buildDefaultBytecodeProvider();
try {
final Enhancer enhancer = bytecodeProvider.getEnhancer( enhancementContext );
for ( File file : sourceSet ) { for ( File file : sourceSet ) {
final byte[] enhancedBytecode = doEnhancement( file, enhancer ); final byte[] enhancedBytecode = doEnhancement( file, enhancer );
if ( enhancedBytecode == null ) { if ( enhancedBytecode == null ) {
continue; continue;
} }
writeOutEnhancedClass( enhancedBytecode, file ); writeOutEnhancedClass( enhancedBytecode, file );
if ( log.isDebugEnabled() ) { if ( log.isDebugEnabled() ) {
log.debug( "Successfully enhanced class [" + file + "]" ); log.debug( "Successfully enhanced class [" + file + "]" );
}
} }
} }
finally {
bytecodeProvider.resetCaches();
}
} }
private ClassLoader toClassLoader(List<File> runtimeClasspath) throws MojoExecutionException { private ClassLoader toClassLoader(List<File> runtimeClasspath) throws MojoExecutionException {

View File

@ -25,6 +25,7 @@ import org.hibernate.bytecode.enhance.spi.UnloadedField;
import org.hibernate.cfg.Environment; import org.hibernate.cfg.Environment;
import org.hibernate.orm.tooling.gradle.HibernateOrmSpec; import org.hibernate.orm.tooling.gradle.HibernateOrmSpec;
import static org.hibernate.bytecode.internal.BytecodeProviderInitiator.buildDefaultBytecodeProvider;
import static org.hibernate.orm.tooling.gradle.Helper.determineClassName; import static org.hibernate.orm.tooling.gradle.Helper.determineClassName;
/** /**
@ -130,8 +131,8 @@ public class EnhancementHelper {
} }
}; };
//noinspection deprecation //TODO allow the Gradle plugin to configure the bytecode enhancer?
return Environment.getBytecodeProvider().getEnhancer( enhancementContext ); return buildDefaultBytecodeProvider().getEnhancer( enhancementContext );
} }
private static void writeOutEnhancedClass(byte[] enhancedBytecode, File file, Logger logger) { private static void writeOutEnhancedClass(byte[] enhancedBytecode, File file, Logger logger) {