HHH-8096 Re-work the OSGi class loading concepts
This commit is contained in:
parent
206a846934
commit
1df99fc066
|
@ -912,7 +912,6 @@ public class Ejb3Configuration implements Serializable, Referenceable {
|
|||
thread = Thread.currentThread();
|
||||
contextClassLoader = thread.getContextClassLoader();
|
||||
thread.setContextClassLoader( overridenClassLoader );
|
||||
builder.with( overridenClassLoader );
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
@ -42,16 +42,6 @@ public class HibernatePersistence extends AvailableSettings implements Persisten
|
|||
|
||||
private final PersistenceUtilHelper.MetadataCache cache = new PersistenceUtilHelper.MetadataCache();
|
||||
|
||||
/**
|
||||
* Used for environment-supplied properties. Ex: hibernate-osgi's
|
||||
* HibernateBundleActivator needs to set a custom JtaPlatform.
|
||||
*/
|
||||
private Map environmentProperties;
|
||||
|
||||
public void setEnvironmentProperties( Map environmentProperties ) {
|
||||
this.environmentProperties = environmentProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an entity manager factory by its entity manager name, using the specified
|
||||
* properties (they override any found in the peristence.xml file).
|
||||
|
@ -64,9 +54,6 @@ public class HibernatePersistence extends AvailableSettings implements Persisten
|
|||
* @return initialized EntityManagerFactory
|
||||
*/
|
||||
public EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) {
|
||||
if ( environmentProperties != null ) {
|
||||
properties.putAll( environmentProperties );
|
||||
}
|
||||
Ejb3Configuration cfg = new Ejb3Configuration();
|
||||
Ejb3Configuration configured = cfg.configure( persistenceUnitName, properties );
|
||||
return configured != null ? configured.buildEntityManagerFactory() : null;
|
||||
|
@ -84,9 +71,6 @@ public class HibernatePersistence extends AvailableSettings implements Persisten
|
|||
* @return initialized EntityManagerFactory
|
||||
*/
|
||||
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) {
|
||||
if ( environmentProperties != null ) {
|
||||
properties.putAll( environmentProperties );
|
||||
}
|
||||
Ejb3Configuration cfg = new Ejb3Configuration();
|
||||
Ejb3Configuration configured = cfg.configure( info, properties );
|
||||
return configured != null ? configured.buildEntityManagerFactory() : null;
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* JBoss, Home of Professional Open Source
|
||||
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @authors tag. All rights reserved.
|
||||
* See the copyright.txt in the distribution for a
|
||||
* full listing of individual contributors.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use,
|
||||
* modify, copy, or redistribute it subject to the terms and conditions
|
||||
* of the GNU Lesser General Public License, v. 2.1.
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT A
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
* You should have received a copy of the GNU Lesser General Public License,
|
||||
* v.2.1 along with this distribution; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
package org.hibernate.osgi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
/**
|
||||
* Integrates a Bundle, its key, and classes/resources that have been found
|
||||
* through its ClassLoader. Primarily used to clear the OsgiClassLoader
|
||||
* caches once the Bundle is deactivated.
|
||||
*
|
||||
* @author Brett Meyer
|
||||
*/
|
||||
public class CachedBundle {
|
||||
|
||||
private Bundle bundle;
|
||||
|
||||
private String key;
|
||||
|
||||
private List<String> classNames = new ArrayList<String>();
|
||||
|
||||
private List<String> resourceNames = new ArrayList<String>();
|
||||
|
||||
private List<String> resourceListNames = new ArrayList<String>();
|
||||
|
||||
public CachedBundle( Bundle bundle, String key ) {
|
||||
this.bundle = bundle;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public Class loadClass(String name) throws ClassNotFoundException {
|
||||
Class clazz = bundle.loadClass( name );
|
||||
if ( clazz != null ) {
|
||||
classNames.add( name );
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public URL getResource(String name) {
|
||||
URL resource = bundle.getResource( name );
|
||||
if ( resource != null ) {
|
||||
resourceNames.add( name );
|
||||
}
|
||||
return resource;
|
||||
}
|
||||
|
||||
public Enumeration getResources(String name) throws IOException {
|
||||
Enumeration resourceList = bundle.getResources( name );
|
||||
if ( resourceList != null ) {
|
||||
resourceListNames.add( name );
|
||||
}
|
||||
return resourceList;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public List<String> getClassNames() {
|
||||
return classNames;
|
||||
}
|
||||
|
||||
public List<String> getResourceNames() {
|
||||
return resourceNames;
|
||||
}
|
||||
|
||||
public List<String> getResourceListNames() {
|
||||
return resourceListNames;
|
||||
}
|
||||
}
|
|
@ -23,75 +23,68 @@
|
|||
*/
|
||||
package org.hibernate.osgi;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.persistence.spi.PersistenceProvider;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.ejb.HibernatePersistence;
|
||||
import org.hibernate.internal.util.ClassLoaderHelper;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.BundleEvent;
|
||||
import org.osgi.framework.BundleListener;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
|
||||
/**
|
||||
* This BundleActivator provides three different uses of Hibernate in OSGi
|
||||
* environments:
|
||||
*
|
||||
* 1.) Enterprise OSGi JPA: The OSGi container/runtime is in charge of managing
|
||||
* all of the client bundles' persistence units. The container/runtime is
|
||||
* also in charge of creating and managing the EntityManagerFactory through a
|
||||
* registered PersistenceProvider (this).
|
||||
* 2.) Un-managed OSGI JPA: Same as #1, but the container does not manage
|
||||
* the persistence units. Client bundles identify a typical
|
||||
* PersistenceProvider, registered by this activator.
|
||||
* 3.) Client bundles create and manage their own SessionFactory. A
|
||||
* SessionFactory is registered as an OSGi ServiceFactory -- each requesting
|
||||
* bundle gets its own instance of a SessionFactory. The use of services,
|
||||
* rather than direct use of Configuration, is necessary to shield users
|
||||
* from ClassLoader issues. See {@link #OsgiSessionFactoryService} for more
|
||||
* information.
|
||||
*
|
||||
* @author Brett Meyer
|
||||
* @author Martin Neimeier
|
||||
* @author Tim Ward
|
||||
*/
|
||||
public class HibernateBundleActivator
|
||||
implements BundleActivator, /*ServiceListener,*/ BundleListener {
|
||||
|
||||
public class HibernateBundleActivator implements BundleActivator {
|
||||
|
||||
private OsgiClassLoader osgiClassLoader;
|
||||
|
||||
@Override
|
||||
public void start(BundleContext context) throws Exception {
|
||||
|
||||
// register this instance as a bundle listener to get informed about all
|
||||
// bundle live cycle events
|
||||
context.addBundleListener(this);
|
||||
|
||||
osgiClassLoader = new OsgiClassLoader();
|
||||
|
||||
ClassLoaderHelper.overridenClassLoader = osgiClassLoader;
|
||||
private OsgiJtaPlatform osgiJtaPlatform;
|
||||
|
||||
for ( Bundle bundle : context.getBundles() ) {
|
||||
handleBundleChange( bundle );
|
||||
}
|
||||
|
||||
HibernatePersistence hp = new HibernatePersistence();
|
||||
Map map = new HashMap();
|
||||
map.put( AvailableSettings.JTA_PLATFORM, new OsgiJtaPlatform( context ) );
|
||||
hp.setEnvironmentProperties( map );
|
||||
|
||||
Properties properties = new Properties();
|
||||
properties.put( "javax.persistence.provider", HibernatePersistence.class.getName() );
|
||||
context.registerService( PersistenceProvider.class.getName(), hp, properties );
|
||||
}
|
||||
@Override
|
||||
public void start(BundleContext context) throws Exception {
|
||||
|
||||
@Override
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
context.removeBundleListener(this);
|
||||
|
||||
// Nothing else to do. When re-activated, this Activator will be
|
||||
// re-started and the EMF re-created.
|
||||
}
|
||||
osgiClassLoader = new OsgiClassLoader();
|
||||
osgiClassLoader.addBundle( FrameworkUtil.getBundle( Session.class ) );
|
||||
osgiClassLoader.addBundle( FrameworkUtil.getBundle( HibernatePersistence.class ) );
|
||||
ClassLoaderHelper.overridenClassLoader = osgiClassLoader;
|
||||
|
||||
@Override
|
||||
public void bundleChanged(BundleEvent event) {
|
||||
handleBundleChange( event.getBundle() );
|
||||
osgiJtaPlatform = new OsgiJtaPlatform( context );
|
||||
|
||||
}
|
||||
|
||||
private void handleBundleChange( Bundle bundle ) {
|
||||
if ( bundle.getState() == Bundle.ACTIVE ) {
|
||||
osgiClassLoader.registerBundle(bundle);
|
||||
} else {
|
||||
osgiClassLoader.unregisterBundle(bundle);
|
||||
}
|
||||
}
|
||||
Properties properties = new Properties();
|
||||
// In order to support existing persistence.xml files, register
|
||||
// using the legacy provider name.
|
||||
properties.put( "javax.persistence.provider", HibernatePersistence.class.getName() );
|
||||
context.registerService( PersistenceProvider.class.getName(),
|
||||
new OsgiPersistenceProviderService( osgiClassLoader, osgiJtaPlatform ), properties );
|
||||
|
||||
context.registerService( SessionFactory.class.getName(),
|
||||
new OsgiSessionFactoryService( osgiClassLoader, osgiJtaPlatform ), new Properties());
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
// Nothing else to do?
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,22 +24,27 @@
|
|||
package org.hibernate.osgi;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
/**
|
||||
* Custom OSGI ClassLoader helper which knows all the "interesting" bundles and
|
||||
* encapsulates the OSGi related capabilities.
|
||||
* Custom OSGI ClassLoader helper which knows all the "interesting"
|
||||
* class loaders and bundles. Encapsulates the OSGi related CL capabilities.
|
||||
*
|
||||
* @author Brett Meyer
|
||||
* @author Tim Ward
|
||||
*/
|
||||
public class OsgiClassLoader extends ClassLoader {
|
||||
|
||||
private Map<String, CachedBundle> bundles = new HashMap<String, CachedBundle>();
|
||||
private List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
|
||||
|
||||
private List<Bundle> bundles = new ArrayList<Bundle>();
|
||||
|
||||
private Map<String, Class<?>> classCache = new HashMap<String, Class<?>>();
|
||||
|
||||
|
@ -59,7 +64,7 @@ public class OsgiClassLoader extends ClassLoader {
|
|||
return classCache.get( name );
|
||||
}
|
||||
|
||||
for ( CachedBundle bundle : bundles.values() ) {
|
||||
for ( Bundle bundle : bundles ) {
|
||||
try {
|
||||
Class clazz = bundle.loadClass( name );
|
||||
if ( clazz != null ) {
|
||||
|
@ -70,6 +75,18 @@ public class OsgiClassLoader extends ClassLoader {
|
|||
catch ( Exception ignore ) {
|
||||
}
|
||||
}
|
||||
|
||||
for ( ClassLoader classLoader : classLoaders ) {
|
||||
try {
|
||||
Class clazz = classLoader.loadClass( name );
|
||||
if ( clazz != null ) {
|
||||
classCache.put( name, clazz );
|
||||
return clazz;
|
||||
}
|
||||
}
|
||||
catch ( Exception ignore ) {
|
||||
}
|
||||
}
|
||||
|
||||
throw new ClassNotFoundException( "Could not load requested class : " + name );
|
||||
}
|
||||
|
@ -85,7 +102,7 @@ public class OsgiClassLoader extends ClassLoader {
|
|||
return resourceCache.get( name );
|
||||
}
|
||||
|
||||
for ( CachedBundle bundle : bundles.values() ) {
|
||||
for ( Bundle bundle : bundles ) {
|
||||
try {
|
||||
URL resource = bundle.getResource( name );
|
||||
if ( resource != null ) {
|
||||
|
@ -96,6 +113,19 @@ public class OsgiClassLoader extends ClassLoader {
|
|||
catch ( Exception ignore ) {
|
||||
}
|
||||
}
|
||||
|
||||
for ( ClassLoader classLoader : classLoaders ) {
|
||||
try {
|
||||
URL resource = classLoader.getResource( name );
|
||||
if ( resource != null ) {
|
||||
resourceCache.put( name, resource );
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
catch ( Exception ignore ) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Error?
|
||||
return null;
|
||||
}
|
||||
|
@ -112,67 +142,69 @@ public class OsgiClassLoader extends ClassLoader {
|
|||
return resourceListCache.get( name );
|
||||
}
|
||||
|
||||
for ( CachedBundle bundle : bundles.values() ) {
|
||||
final List<Enumeration<URL>> enumerations = new ArrayList<Enumeration<URL>>();
|
||||
|
||||
for ( Bundle bundle : bundles ) {
|
||||
try {
|
||||
Enumeration<URL> resources = bundle.getResources( name );
|
||||
if ( resources != null ) {
|
||||
resourceListCache.put( name, resources );
|
||||
return resources;
|
||||
enumerations.add( resources );
|
||||
}
|
||||
}
|
||||
catch ( Exception ignore ) {
|
||||
}
|
||||
}
|
||||
// TODO: Error?
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the bundle with this class loader
|
||||
*/
|
||||
public void registerBundle(Bundle bundle) {
|
||||
if ( bundle != null ) {
|
||||
synchronized ( bundles ) {
|
||||
String key = getBundleKey( bundle );
|
||||
if ( !bundles.containsKey( key ) ) {
|
||||
bundles.put( key, new CachedBundle( bundle, key ) );
|
||||
|
||||
for ( ClassLoader classLoader : classLoaders ) {
|
||||
try {
|
||||
Enumeration<URL> resources = classLoader.getResources( name );
|
||||
if ( resources != null ) {
|
||||
enumerations.add( resources );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister the bundle from this class loader
|
||||
*/
|
||||
public void unregisterBundle(Bundle bundle) {
|
||||
if ( bundle != null ) {
|
||||
synchronized ( bundles ) {
|
||||
String key = getBundleKey( bundle );
|
||||
if ( bundles.containsKey( key ) ) {
|
||||
CachedBundle cachedBundle = bundles.remove( key );
|
||||
clearCache( classCache, cachedBundle.getClassNames() );
|
||||
clearCache( resourceCache, cachedBundle.getResourceNames() );
|
||||
clearCache( resourceListCache, cachedBundle.getResourceListNames() );
|
||||
}
|
||||
catch ( Exception ignore ) {
|
||||
}
|
||||
}
|
||||
|
||||
Enumeration<URL> aggEnumeration = new Enumeration<URL>() {
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
for ( Enumeration<URL> enumeration : enumerations ) {
|
||||
if ( enumeration != null && enumeration.hasMoreElements() ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL nextElement() {
|
||||
for ( Enumeration<URL> enumeration : enumerations ) {
|
||||
if ( enumeration != null && enumeration.hasMoreElements() ) {
|
||||
return enumeration.nextElement();
|
||||
}
|
||||
}
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
};
|
||||
|
||||
resourceListCache.put( name, aggEnumeration );
|
||||
|
||||
return aggEnumeration;
|
||||
}
|
||||
|
||||
private void clearCache( Map cache, List<String> names ) {
|
||||
for ( String name : names ) {
|
||||
cache.remove( name );
|
||||
}
|
||||
|
||||
public void addClassLoader( ClassLoader classLoader ) {
|
||||
classLoaders.add( classLoader );
|
||||
}
|
||||
|
||||
public void addBundle( Bundle bundle ) {
|
||||
bundles.add( bundle );
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
bundles.clear();
|
||||
classCache.clear();
|
||||
resourceCache.clear();
|
||||
resourceListCache.clear();
|
||||
}
|
||||
|
||||
protected static String getBundleKey(Bundle bundle) {
|
||||
return bundle.getSymbolicName() + " " + bundle.getVersion().toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.osgi;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.spi.PersistenceUnitInfo;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.ejb.Ejb3Configuration;
|
||||
import org.hibernate.ejb.HibernatePersistence;
|
||||
import org.hibernate.service.BootstrapServiceRegistryBuilder;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
/**
|
||||
* @author Brett Meyer
|
||||
* @author Tim Ward
|
||||
*/
|
||||
public class OsgiPersistenceProvider extends HibernatePersistence {
|
||||
|
||||
private OsgiClassLoader osgiClassLoader;
|
||||
|
||||
private OsgiJtaPlatform osgiJtaPlatform;
|
||||
|
||||
private Bundle requestingBundle;
|
||||
|
||||
public OsgiPersistenceProvider (OsgiClassLoader osgiClassLoader,
|
||||
OsgiJtaPlatform osgiJtaPlatform,
|
||||
Bundle requestingBundle ) {
|
||||
this.osgiClassLoader = osgiClassLoader;
|
||||
this.osgiJtaPlatform = osgiJtaPlatform;
|
||||
this.requestingBundle = requestingBundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) {
|
||||
if ( properties == null ) {
|
||||
properties = new HashMap();
|
||||
}
|
||||
properties.put( AvailableSettings.JTA_PLATFORM, osgiJtaPlatform );
|
||||
|
||||
osgiClassLoader.addBundle( requestingBundle );
|
||||
|
||||
Ejb3Configuration cfg = new Ejb3Configuration();
|
||||
Ejb3Configuration configured = cfg.configure( persistenceUnitName, properties );
|
||||
return configured != null ? configured.buildEntityManagerFactory( getBuilder( properties ) ) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) {
|
||||
if ( properties == null ) {
|
||||
properties = new HashMap();
|
||||
}
|
||||
properties.put( AvailableSettings.JTA_PLATFORM, osgiJtaPlatform );
|
||||
|
||||
osgiClassLoader.addClassLoader( info.getClassLoader() );
|
||||
|
||||
Ejb3Configuration cfg = new Ejb3Configuration();
|
||||
Ejb3Configuration configured = cfg.configure( info, properties );
|
||||
return configured != null ? configured.buildEntityManagerFactory( getBuilder( properties ) ) : null;
|
||||
}
|
||||
|
||||
private BootstrapServiceRegistryBuilder getBuilder(Map properties) {
|
||||
BootstrapServiceRegistryBuilder builder = new BootstrapServiceRegistryBuilder();
|
||||
final Collection<ClassLoader> classLoaders = (Collection<ClassLoader>) properties
|
||||
.get( AvailableSettings.CLASSLOADERS );
|
||||
if ( classLoaders != null ) {
|
||||
for ( ClassLoader classLoader : classLoaders ) {
|
||||
osgiClassLoader.addClassLoader( classLoader );
|
||||
}
|
||||
}
|
||||
builder.with( osgiClassLoader );
|
||||
return builder;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* JBoss, Home of Professional Open Source
|
||||
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @authors tag. All rights reserved.
|
||||
* See the copyright.txt in the distribution for a
|
||||
* full listing of individual contributors.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use,
|
||||
* modify, copy, or redistribute it subject to the terms and conditions
|
||||
* of the GNU Lesser General Public License, v. 2.1.
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT A
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
* You should have received a copy of the GNU Lesser General Public License,
|
||||
* v.2.1 along with this distribution; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
package org.hibernate.osgi;
|
||||
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.ServiceFactory;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
|
||||
/**
|
||||
* See the description on {@link #OsgiSessionFactoryService}. This class
|
||||
* is similar, providing an PersistenceProvider as an OSGi Service.
|
||||
*
|
||||
* @author Brett Meyer
|
||||
* @author Tim Ward
|
||||
*/
|
||||
public class OsgiPersistenceProviderService implements ServiceFactory {
|
||||
|
||||
private OsgiClassLoader osgiClassLoader;
|
||||
|
||||
private OsgiJtaPlatform osgiJtaPlatform;
|
||||
|
||||
public OsgiPersistenceProviderService( OsgiClassLoader osgiClassLoader, OsgiJtaPlatform osgiJtaPlatform ) {
|
||||
this.osgiClassLoader = osgiClassLoader;
|
||||
this.osgiJtaPlatform = osgiJtaPlatform;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getService(Bundle requestingBundle, ServiceRegistration registration) {
|
||||
return new OsgiPersistenceProvider(osgiClassLoader, osgiJtaPlatform, requestingBundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ungetService(Bundle requestingBundle, ServiceRegistration registration, Object service) {
|
||||
// ?
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* JBoss, Home of Professional Open Source
|
||||
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @authors tag. All rights reserved.
|
||||
* See the copyright.txt in the distribution for a
|
||||
* full listing of individual contributors.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use,
|
||||
* modify, copy, or redistribute it subject to the terms and conditions
|
||||
* of the GNU Lesser General Public License, v. 2.1.
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT A
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
* You should have received a copy of the GNU Lesser General Public License,
|
||||
* v.2.1 along with this distribution; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
package org.hibernate.osgi;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.service.BootstrapServiceRegistryBuilder;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.service.ServiceRegistryBuilder;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.ServiceFactory;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
|
||||
/**
|
||||
* Hibernate 4.2 and 4.3 still heavily rely on TCCL for ClassLoading. Although
|
||||
* our ClassLoaderService removed some of the reliance, the service is
|
||||
* unfortunately not available during Configuration. An OSGi
|
||||
* bundle manually creating a SessionFactory would require numerous ClassLoader
|
||||
* tricks (or may be impossible altogether).
|
||||
*
|
||||
* In order to fully control the TCCL issues and shield users from the
|
||||
* knowledge, we're requiring that bundles use this OSGi ServiceFactory. It
|
||||
* configures and provides a SessionFactory as an OSGi service.
|
||||
*
|
||||
* Note that an OSGi ServiceFactory differs from a Service. The ServiceFactory
|
||||
* allows individual instances of Services to be created and provided to
|
||||
* multiple client Bundles.
|
||||
*
|
||||
* @author Brett Meyer
|
||||
* @author Tim Ward
|
||||
*/
|
||||
public class OsgiSessionFactoryService implements ServiceFactory {
|
||||
|
||||
private OsgiClassLoader osgiClassLoader;
|
||||
|
||||
private OsgiJtaPlatform osgiJtaPlatform;
|
||||
|
||||
public OsgiSessionFactoryService( OsgiClassLoader osgiClassLoader, OsgiJtaPlatform osgiJtaPlatform ) {
|
||||
this.osgiClassLoader = osgiClassLoader;
|
||||
this.osgiJtaPlatform = osgiJtaPlatform;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getService(Bundle requestingBundle, ServiceRegistration registration) {
|
||||
osgiClassLoader.addBundle( requestingBundle );
|
||||
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.getProperties().put( AvailableSettings.JTA_PLATFORM, osgiJtaPlatform );
|
||||
configuration.configure();
|
||||
|
||||
BootstrapServiceRegistryBuilder builder = new BootstrapServiceRegistryBuilder();
|
||||
builder.with( osgiClassLoader );
|
||||
|
||||
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder( builder.build() )
|
||||
.applySettings(configuration.getProperties()).buildServiceRegistry();
|
||||
return configuration.buildSessionFactory(serviceRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ungetService(Bundle requestingBundle, ServiceRegistration registration, Object service) {
|
||||
( (SessionFactory) service).close();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue