HHH-8010 Support app-managed EntityManagerFactory and SessionFactory creation by OSGi bundles

This commit is contained in:
Brett Meyer 2013-02-26 15:33:30 -05:00
parent 797819ff07
commit 5f38be4659
17 changed files with 64 additions and 42 deletions

View File

@ -717,7 +717,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 );
@ -1299,6 +1299,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
{
@ -1376,6 +1381,8 @@ public class Configuration implements Serializable {
buildUniqueKeyFromColumnNames( table, keyName, holder.getColumns() );
}
}
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

@ -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

@ -27,7 +27,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
@ -38,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.internal.util.ClassLoaderHelper;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.classloading.spi.ClassLoadingException;
import org.jboss.logging.Logger;
/**
* Standard implementation of the service for interacting with class loaders
@ -75,7 +74,11 @@ 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.)
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

@ -24,14 +24,13 @@
package org.hibernate.service.jdbc.connections.internal;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Map;
import java.util.Properties;
import org.jboss.logging.Logger;
import org.hibernate.HibernateException;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Environment;
@ -46,6 +45,7 @@ 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
@ -73,6 +73,8 @@ public class DriverManagerConnectionProviderImpl
private boolean stopped;
private transient ServiceRegistryImplementor serviceRegistry;
private Driver driver;
@Override
public boolean isUnwrappableAs(Class unwrapType) {
@ -101,12 +103,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
);
}
}
@ -114,14 +118,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 );
}
}
}
@ -190,7 +194,20 @@ public class DriverManagerConnectionProviderImpl
// otherwise we open a new connection...
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

@ -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

@ -94,6 +94,7 @@ import org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory;
import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
import org.hibernate.id.factory.spi.MutableIdentifierGeneratorFactory;
import org.hibernate.internal.SessionFactoryObserverChain;
import org.hibernate.internal.util.ClassLoaderHelper;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
@ -169,12 +170,7 @@ public class Ejb3Configuration implements Serializable, Referenceable {
public Ejb3Configuration() {
this(null);
}
public Ejb3Configuration(ClassLoader overridenClassLoader) {
this.overridenClassLoader = overridenClassLoader;
overridenClassLoader = ClassLoaderHelper.overridenClassLoader;
cfg = new Configuration();
cfg.setEntityNotFoundDelegate( ejb3EntityNotFoundDelegate );
}
@ -320,8 +316,7 @@ public class Ejb3Configuration implements Serializable, Referenceable {
integration = integration == null ?
CollectionHelper.EMPTY_MAP :
Collections.unmodifiableMap( integration );
Enumeration<URL> xmls = Thread.currentThread()
.getContextClassLoader()
Enumeration<URL> xmls = ClassLoaderHelper.getContextClassLoader()
.getResources( "META-INF/persistence.xml" );
if (!xmls.hasMoreElements()) LOG.unableToFindPersistenceXmlInClasspath();
while ( xmls.hasMoreElements() ) {

View File

@ -103,7 +103,7 @@ public class HibernateBundleActivator
@Override
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map) {
Ejb3Configuration cfg = new Ejb3Configuration(osgiClassLoader);
Ejb3Configuration cfg = new Ejb3Configuration();
if ( info.getTransactionType().equals( PersistenceUnitTransactionType.JTA ) ) {
map.put( AvailableSettings.JTA_PLATFORM, new OsgiJtaPlatform( context ) );
}