HHH-8010 Support app-managed EntityManagerFactory and SessionFactory

creation by OSGi bundles

Conflicts:
	hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/ClassLoaderServiceImpl.java
	hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java
	hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/DriverManagerConnectionProviderImpl.java
	hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
	hibernate-osgi/src/main/java/org/hibernate/osgi/HibernateBundleActivator.java
This commit is contained in:
Brett Meyer 2013-02-28 10:28:02 -05:00
parent 0e6d08d414
commit 394458f6a6
16 changed files with 68 additions and 38 deletions

View File

@ -37,11 +37,11 @@ import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import org.jboss.logging.Logger;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.internal.util.ClassLoaderHelper;
import org.jboss.logging.Logger;
/**
* Standard implementation of the service for interacting with class loaders
@ -74,7 +74,14 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
}
// normalize adding known class-loaders...
// first the Hibernate class loader
// first, the "overridden" classloader provided by an environment (OSGi, etc.)
// TODO: This should probably be wired into BootstrapServiceRegistryBuilder
// instead, however that wasn't available in 4.2. Once JPA 2.1 is testable
// in an OSGi container, move this and re-work.
if ( ClassLoaderHelper.overridenClassLoader != null ) {
orderedClassLoaderSet.add( ClassLoaderHelper.overridenClassLoader );
}
// then the Hibernate class loader
orderedClassLoaderSet.add( ClassLoaderServiceImpl.class.getClassLoader() );
// then the TCCL, if one...
final ClassLoader tccl = locateTCCL();

View File

@ -723,7 +723,7 @@ public class Configuration implements Serializable {
*/
public Configuration addResource(String resourceName) throws MappingException {
LOG.readingMappingsFromResource( resourceName );
ClassLoader contextClassLoader = ClassLoaderHelper.getClassLoader();
ClassLoader contextClassLoader = ClassLoaderHelper.getContextClassLoader();
InputStream resourceInputStream = null;
if ( contextClassLoader != null ) {
resourceInputStream = contextClassLoader.getResourceAsStream( resourceName );
@ -1305,6 +1305,11 @@ public class Configuration implements Serializable {
protected void secondPassCompile() throws MappingException {
LOG.trace( "Starting secondPassCompile() processing" );
// TEMPORARY
// Ensure the correct ClassLoader is used in commons-annotations.
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader( ClassLoaderHelper.getContextClassLoader() );
//process default values first
{
@ -1382,6 +1387,7 @@ public class Configuration implements Serializable {
buildUniqueKeyFromColumnNames( table, keyName, holder.getColumns() );
}
}
for(Table table : jpaIndexHoldersByTable.keySet()){
final List<JPAIndexHolder> jpaIndexHolders = jpaIndexHoldersByTable.get( table );
int uniqueIndexPerTable = 0;
@ -1393,6 +1399,8 @@ public class Configuration implements Serializable {
buildUniqueKeyFromColumnNames( table, keyName, holder.getColumns(), holder.getOrdering(), holder.isUnique() );
}
}
Thread.currentThread().setContextClassLoader( tccl );
}
private void processSecondPassesOfType(Class<? extends SecondPass> type) {

View File

@ -197,7 +197,7 @@ public class BlobProxy implements InvocationHandler {
* @return The class loader appropriate for proxy construction.
*/
private static ClassLoader getProxyClassLoader() {
ClassLoader cl = ClassLoaderHelper.getClassLoader();
ClassLoader cl = ClassLoaderHelper.getContextClassLoader();
if ( cl == null ) {
cl = BlobImplementer.class.getClassLoader();
}

View File

@ -216,7 +216,7 @@ public class ClobProxy implements InvocationHandler {
* @return The class loader appropriate for proxy construction.
*/
protected static ClassLoader getProxyClassLoader() {
ClassLoader cl = ClassLoaderHelper.getClassLoader();
ClassLoader cl = ClassLoaderHelper.getContextClassLoader();
if ( cl == null ) {
cl = ClobImplementer.class.getClassLoader();
}

View File

@ -88,7 +88,7 @@ public class NClobProxy extends ClobProxy {
* @return The class loader appropriate for proxy construction.
*/
protected static ClassLoader getProxyClassLoader() {
ClassLoader cl = ClassLoaderHelper.getClassLoader();
ClassLoader cl = ClassLoaderHelper.getContextClassLoader();
if ( cl == null ) {
cl = NClobImplementer.class.getClassLoader();
}

View File

@ -79,7 +79,7 @@ public class ResultSetWrapperProxy implements InvocationHandler {
* @return The class loader appropriate for proxy construction.
*/
public static ClassLoader getProxyClassLoader() {
ClassLoader cl = ClassLoaderHelper.getClassLoader();
ClassLoader cl = ClassLoaderHelper.getContextClassLoader();
if ( cl == null ) {
cl = ResultSet.class.getClassLoader();
}

View File

@ -102,7 +102,7 @@ public class SerializableBlobProxy implements InvocationHandler, Serializable {
* @return The class loader appropriate for proxy construction.
*/
public static ClassLoader getProxyClassLoader() {
ClassLoader cl = ClassLoaderHelper.getClassLoader();
ClassLoader cl = ClassLoaderHelper.getContextClassLoader();
if ( cl == null ) {
cl = WrappedBlob.class.getClassLoader();
}

View File

@ -101,7 +101,7 @@ public class SerializableClobProxy implements InvocationHandler, Serializable {
* @return The class loader appropriate for proxy construction.
*/
public static ClassLoader getProxyClassLoader() {
ClassLoader cl = ClassLoaderHelper.getClassLoader();
ClassLoader cl = ClassLoaderHelper.getContextClassLoader();
if ( cl == null ) {
cl = WrappedClob.class.getClassLoader();
}

View File

@ -24,6 +24,7 @@
package org.hibernate.engine.jdbc.connections.internal;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
@ -31,9 +32,9 @@ import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
import org.jboss.logging.Logger;
import org.hibernate.HibernateException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
@ -41,12 +42,11 @@ import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.UnknownUnwrapTypeException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.service.spi.Configurable;
import org.hibernate.service.spi.ServiceRegistryAwareService;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.service.spi.Stoppable;
import org.jboss.logging.Logger;
/**
* A connection provider that uses the {@link java.sql.DriverManager} directly to open connections and provides
@ -74,6 +74,8 @@ public class DriverManagerConnectionProviderImpl
private boolean stopped;
private transient ServiceRegistryImplementor serviceRegistry;
private Driver driver;
@Override
public boolean isUnwrappableAs(Class unwrapType) {
@ -102,12 +104,14 @@ public class DriverManagerConnectionProviderImpl
}
else if ( serviceRegistry != null ) {
try {
serviceRegistry.getService( ClassLoaderService.class ).classForName( driverClassName );
driver = (Driver) serviceRegistry.getService(
ClassLoaderService.class ).classForName( driverClassName )
.newInstance();
}
catch ( ClassLoadingException e ) {
catch ( Exception e ) {
throw new ClassLoadingException(
"Specified JDBC Driver " + driverClassName + " class not found",
e
"Specified JDBC Driver " + driverClassName
+ " could not be loaded", e
);
}
}
@ -115,14 +119,14 @@ public class DriverManagerConnectionProviderImpl
else {
try {
// trying via forName() first to be as close to DriverManager's semantics
Class.forName( driverClassName );
driver = (Driver) Class.forName( driverClassName ).newInstance();
}
catch ( ClassNotFoundException cnfe ) {
catch ( Exception e1 ) {
try{
ReflectHelper.classForName( driverClassName );
driver = (Driver) ReflectHelper.classForName( driverClassName ).newInstance();
}
catch ( ClassNotFoundException e ) {
throw new HibernateException( "Specified JDBC Driver " + driverClassName + " class not found", e );
catch ( Exception e2 ) {
throw new HibernateException( "Specified JDBC Driver " + driverClassName + " could not be loaded", e2 );
}
}
}
@ -191,11 +195,22 @@ public class DriverManagerConnectionProviderImpl
}
// otherwise we open a new connection...
final boolean debugEnabled = LOG.isDebugEnabled();
if ( debugEnabled ) LOG.debug( "Opening new JDBC connection" );
Connection conn = DriverManager.getConnection( url, connectionProps );
Connection conn;
if ( driver != null ) {
// If a Driver is available, completely circumvent
// DriverManager#getConnection. It attempts to double check
// ClassLoaders before using a Driver. This does not work well in
// OSGi environments without wonky workarounds.
conn = driver.connect( url, connectionProps );
}
else {
// If no Driver, fall back on the original method.
conn = DriverManager.getConnection( url, connectionProps );
}
if ( isolation != null ) {
conn.setTransactionIsolation( isolation.intValue() );
}

View File

@ -22,7 +22,7 @@ package org.hibernate.internal.util;
/**
* This exists purely to allow custom ClassLoaders to be injected and used
* prior to ServiceRegistry and ClassLoadingService existance. This should be
* prior to ServiceRegistry and ClassLoadingService existence. This should be
* replaced in Hibernate 5.
*
* @author Brett Meyer
@ -31,7 +31,7 @@ public class ClassLoaderHelper {
public static ClassLoader overridenClassLoader = null;
public static ClassLoader getClassLoader() {
public static ClassLoader getContextClassLoader() {
return overridenClassLoader != null ?
overridenClassLoader : Thread.currentThread().getContextClassLoader();
}

View File

@ -78,7 +78,7 @@ public final class ConfigHelper {
// First, try to locate this resource through the current
// context classloader.
ClassLoader contextClassLoader = ClassLoaderHelper.getClassLoader();
ClassLoader contextClassLoader = ClassLoaderHelper.getContextClassLoader();
if (contextClassLoader!=null) {
url = contextClassLoader.getResource(path);
}
@ -159,7 +159,7 @@ public final class ConfigHelper {
resource.substring(1) : resource;
InputStream stream = null;
ClassLoader classLoader = ClassLoaderHelper.getClassLoader();
ClassLoader classLoader = ClassLoaderHelper.getContextClassLoader();
if (classLoader!=null) {
stream = classLoader.getResourceAsStream( stripped );
}
@ -182,7 +182,7 @@ public final class ConfigHelper {
InputStream stream = null;
ClassLoader classLoader = ClassLoaderHelper.getClassLoader();
ClassLoader classLoader = ClassLoaderHelper.getContextClassLoader();
if ( classLoader != null ) {
stream = classLoader.getResourceAsStream( resource );
if ( stream == null && hasLeadingSlash ) {

View File

@ -160,7 +160,7 @@ public final class ReflectHelper {
*/
public static Class classForName(String name, Class caller) throws ClassNotFoundException {
try {
ClassLoader classLoader = ClassLoaderHelper.getClassLoader();
ClassLoader classLoader = ClassLoaderHelper.getContextClassLoader();
if ( classLoader != null ) {
return classLoader.loadClass( name );
}
@ -182,7 +182,7 @@ public final class ReflectHelper {
*/
public static Class classForName(String name) throws ClassNotFoundException {
try {
ClassLoader classLoader = ClassLoaderHelper.getClassLoader();
ClassLoader classLoader = ClassLoaderHelper.getContextClassLoader();
if ( classLoader != null ) {
return classLoader.loadClass(name);
}

View File

@ -191,7 +191,7 @@ public final class SerializationHelper {
* @return The current TCCL
*/
public static ClassLoader defaultClassLoader() {
return ClassLoaderHelper.getClassLoader();
return ClassLoaderHelper.getContextClassLoader();
}
public static ClassLoader hibernateClassLoader() {

View File

@ -82,7 +82,7 @@ public final class XMLHelper {
public static DocumentFactory getDocumentFactory() {
ClassLoader cl = ClassLoaderHelper.getClassLoader();
ClassLoader cl = ClassLoaderHelper.getContextClassLoader();
DocumentFactory factory;
try {
Thread.currentThread().setContextClassLoader( XMLHelper.class.getClassLoader() );

View File

@ -92,7 +92,7 @@ public class DriverManagerRegistrationTest extends BaseUnitTestCase {
}
private static ClassLoader determineClassLoader() {
ClassLoader cl = ClassLoaderHelper.getClassLoader();
ClassLoader cl = ClassLoaderHelper.getContextClassLoader();
if ( cl == null ) {
cl = DriverManagerRegistrationTest.class.getClassLoader();
}

View File

@ -387,7 +387,7 @@ public class InfinispanRegionFactory implements RegionFactory {
try {
String configLoc = ConfigurationHelper.getString(
INFINISPAN_CONFIG_RESOURCE_PROP, properties, DEF_INFINISPAN_CONFIG_RESOURCE);
ClassLoader classLoader = ClassLoaderHelper.getClassLoader();
ClassLoader classLoader = ClassLoaderHelper.getContextClassLoader();
InputStream is = FileLookupFactory.newInstance().lookupFileStrict(
configLoc, classLoader);
ParserRegistry parserRegistry = new ParserRegistry(classLoader);