HHH-14306 - Passed TcclLookupPrecedence parameter in JPA properties is ignored

This commit is contained in:
Steve Ebersole 2023-08-11 08:19:41 -05:00
parent 317334f14d
commit 4666d774e4
3 changed files with 100 additions and 54 deletions

View File

@ -41,7 +41,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
private static final String CLASS_PATH_SCHEME = "classpath://"; private static final String CLASS_PATH_SCHEME = "classpath://";
private final ConcurrentMap<Class, AggregatedServiceLoader<?>> serviceLoaders = new ConcurrentHashMap<>(); private final ConcurrentMap<Class<?>, AggregatedServiceLoader<?>> serviceLoaders = new ConcurrentHashMap<>();
private volatile AggregatedClassLoader aggregatedClassLoader; private volatile AggregatedClassLoader aggregatedClassLoader;
/** /**
@ -110,7 +110,10 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
providedClassLoaders.addAll( classLoaders ); providedClassLoaders.addAll( classLoaders );
} }
return new ClassLoaderServiceImpl( providedClassLoaders,TcclLookupPrecedence.AFTER ); return new ClassLoaderServiceImpl(
providedClassLoaders,
TcclLookupPrecedence.from( configValues, TcclLookupPrecedence.AFTER )
);
} }
@Override @Override
@ -119,10 +122,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
try { try {
return (Class<T>) Class.forName( className, true, getAggregatedClassLoader() ); return (Class<T>) Class.forName( className, true, getAggregatedClassLoader() );
} }
catch (Exception e) { catch (Exception | LinkageError e) {
throw new ClassLoadingException( "Unable to load class [" + className + "]", e );
}
catch (LinkageError e) {
throw new ClassLoadingException( "Unable to load class [" + className + "]", e ); throw new ClassLoadingException( "Unable to load class [" + className + "]", e );
} }
} }

View File

@ -6,6 +6,10 @@
*/ */
package org.hibernate.boot.registry.classloading.internal; package org.hibernate.boot.registry.classloading.internal;
import java.util.Map;
import org.hibernate.cfg.AvailableSettings;
/** /**
* Defines when the lookup in the current thread context {@link ClassLoader} should be * Defines when the lookup in the current thread context {@link ClassLoader} should be
* done according to the other ones. * done according to the other ones.
@ -30,5 +34,40 @@ public enum TcclLookupPrecedence {
* the former hasn't been found in the other {@code ClassLoader}s. * the former hasn't been found in the other {@code ClassLoader}s.
* This is the default value. * This is the default value.
*/ */
AFTER AFTER;
/**
* Resolves the precedence from a Map of settings.
*
* @return The precedence, or {@code null} if none was specified.
* @throws IllegalArgumentException If there is a setting defined for
* precedence, but it is not a legal value
*/
public static TcclLookupPrecedence from(Map<?,?> settings) {
return from( settings, null );
}
/**
* Resolves the precedence from a Map of settings
*
* @return The precedence, or {@code defaultValue} if none was specified.
* @throws IllegalArgumentException If there is a setting defined for
* precedence, but it is not a legal value
*/
public static TcclLookupPrecedence from(Map<?,?> settings, TcclLookupPrecedence defaultValue) {
final String explicitSetting = (String) settings.get( AvailableSettings.TC_CLASSLOADER );
if ( explicitSetting == null ) {
return defaultValue;
}
if ( NEVER.name().equalsIgnoreCase( explicitSetting ) ) {
return NEVER;
}
if ( BEFORE.name().equalsIgnoreCase( explicitSetting ) ) {
return BEFORE;
}
throw new IllegalArgumentException( "Unknown TcclLookupPrecedence - " + explicitSetting );
}
} }

View File

@ -13,7 +13,6 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.StringTokenizer; import java.util.StringTokenizer;
@ -120,7 +119,6 @@ import static org.hibernate.cfg.AvailableSettings.PASS;
import static org.hibernate.cfg.AvailableSettings.PERSISTENCE_UNIT_NAME; import static org.hibernate.cfg.AvailableSettings.PERSISTENCE_UNIT_NAME;
import static org.hibernate.cfg.AvailableSettings.SCANNER_DISCOVERY; import static org.hibernate.cfg.AvailableSettings.SCANNER_DISCOVERY;
import static org.hibernate.cfg.AvailableSettings.SESSION_FACTORY_NAME; import static org.hibernate.cfg.AvailableSettings.SESSION_FACTORY_NAME;
import static org.hibernate.cfg.AvailableSettings.TC_CLASSLOADER;
import static org.hibernate.cfg.AvailableSettings.TRANSACTION_COORDINATOR_STRATEGY; import static org.hibernate.cfg.AvailableSettings.TRANSACTION_COORDINATOR_STRATEGY;
import static org.hibernate.cfg.AvailableSettings.URL; import static org.hibernate.cfg.AvailableSettings.URL;
import static org.hibernate.cfg.AvailableSettings.USER; import static org.hibernate.cfg.AvailableSettings.USER;
@ -468,15 +466,27 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
} }
} }
configureClassLoading( integrationSettings, providedClassLoader, providedClassLoaderService, bsrBuilder );
// ClassLoaders ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ return bsrBuilder.build();
// NOTE: See BootstrapServiceRegistryBuilder#build. providedClassLoaderService and providedClassLoaders are }
// mutually exclusive concepts, with priority given to the former
/**
* @implNote {@code providedClassLoaderService} and {@code providedClassLoaders}
* are mutually exclusive concepts, with priority given to the former.
*
* @see BootstrapServiceRegistryBuilder#build
*/
private void configureClassLoading(
Map<?, ?> integrationSettings,
ClassLoader providedClassLoader,
ClassLoaderService providedClassLoaderService,
BootstrapServiceRegistryBuilder bsrBuilder) {
if ( providedClassLoaderService != null ) { if ( providedClassLoaderService != null ) {
bsrBuilder.applyClassLoaderService( providedClassLoaderService ); bsrBuilder.applyClassLoaderService( providedClassLoaderService );
return;
} }
else {
if ( persistenceUnit.getClassLoader() != null ) { if ( persistenceUnit.getClassLoader() != null ) {
bsrBuilder.applyClassLoader( persistenceUnit.getClassLoader() ); bsrBuilder.applyClassLoader( persistenceUnit.getClassLoader() );
} }
@ -505,18 +515,15 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
} }
//configurationValues not assigned yet, using directly the properties of the PU //configurationValues not assigned yet, using directly the properties of the PU
Properties puProperties = persistenceUnit.getProperties(); final Properties puProperties = persistenceUnit.getProperties();
if ( puProperties != null ) { if ( puProperties != null ) {
final String tcclLookupPrecedence = puProperties.getProperty( TC_CLASSLOADER ); final TcclLookupPrecedence tcclLookupPrecedence = TcclLookupPrecedence.from( puProperties );
if ( tcclLookupPrecedence != null ) { if ( tcclLookupPrecedence != null ) {
bsrBuilder.applyTcclLookupPrecedence( TcclLookupPrecedence.valueOf( tcclLookupPrecedence.toUpperCase( Locale.ROOT ) ) ); bsrBuilder.applyTcclLookupPrecedence( tcclLookupPrecedence );
} }
} }
} }
return bsrBuilder.build();
}
private void applyIntegrationProvider(Map<?,?> integrationSettings, BootstrapServiceRegistryBuilder bsrBuilder) { private void applyIntegrationProvider(Map<?,?> integrationSettings, BootstrapServiceRegistryBuilder bsrBuilder) {
Object integrationSetting = integrationSettings.get( INTEGRATOR_PROVIDER ); Object integrationSetting = integrationSettings.get( INTEGRATOR_PROVIDER );
if ( integrationSetting == null ) { if ( integrationSetting == null ) {