HHH-7995 Auto-discovery of Hibernate extension points in OSGi
This commit is contained in:
parent
398000517f
commit
30d63bf58f
|
@ -1623,4 +1623,8 @@ public interface CoreMessageLogger extends BasicLogger {
|
||||||
@LogMessage(level = WARN)
|
@LogMessage(level = WARN)
|
||||||
@Message(value = "Exception while loading a class or resource found during scanning", id = 449)
|
@Message(value = "Exception while loading a class or resource found during scanning", id = 449)
|
||||||
void unableToLoadScannedClassOrResource(@Cause Exception e);
|
void unableToLoadScannedClassOrResource(@Cause Exception e);
|
||||||
|
|
||||||
|
@LogMessage(level = WARN)
|
||||||
|
@Message(value = "Exception while discovering OSGi service implementations : %s", id = 450)
|
||||||
|
void unableToDiscoverOsgiService(String service, @Cause Exception e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<blueprint default-activation="eager"
|
||||||
|
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
|
||||||
|
<bean id="integrator" class="org.hibernate.envers.event.spi.EnversIntegrator"/>
|
||||||
|
<service ref="integrator" interface="org.hibernate.integrator.spi.Integrator"/>
|
||||||
|
|
||||||
|
</blueprint>
|
|
@ -1,7 +1,9 @@
|
||||||
dependencies {
|
dependencies {
|
||||||
compile( project( ':hibernate-core' ) )
|
compile( project( ':hibernate-core' ) )
|
||||||
compile( project( ':hibernate-entitymanager' ) )
|
compile( project( ':hibernate-entitymanager' ) )
|
||||||
compile( "org.osgi:org.osgi.core:4.3.0" )
|
// MUST use 4.3.1! 4.3.0 was compiled with "-target jsr14".
|
||||||
|
// http://blog.osgi.org/2012/10/43-companion-code-for-java-7.html
|
||||||
|
compile( "org.osgi:org.osgi.core:4.3.1" )
|
||||||
}
|
}
|
||||||
|
|
||||||
def pomName() {
|
def pomName() {
|
||||||
|
|
|
@ -78,10 +78,10 @@ public class HibernateBundleActivator implements BundleActivator {
|
||||||
// using the legacy provider name.
|
// using the legacy provider name.
|
||||||
properties.put( "javax.persistence.provider", HibernatePersistenceProvider.class.getName() );
|
properties.put( "javax.persistence.provider", HibernatePersistenceProvider.class.getName() );
|
||||||
context.registerService( PersistenceProvider.class.getName(),
|
context.registerService( PersistenceProvider.class.getName(),
|
||||||
new OsgiPersistenceProviderService( osgiClassLoader, osgiJtaPlatform ), properties );
|
new OsgiPersistenceProviderService( osgiClassLoader, osgiJtaPlatform, context ), properties );
|
||||||
|
|
||||||
context.registerService( SessionFactory.class.getName(),
|
context.registerService( SessionFactory.class.getName(),
|
||||||
new OsgiSessionFactoryService( osgiClassLoader, osgiJtaPlatform ), new Hashtable());
|
new OsgiSessionFactoryService( osgiClassLoader, osgiJtaPlatform, context ), new Hashtable());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -24,14 +24,20 @@
|
||||||
package org.hibernate.osgi;
|
package org.hibernate.osgi;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.persistence.EntityManagerFactory;
|
import javax.persistence.EntityManagerFactory;
|
||||||
import javax.persistence.spi.PersistenceUnitInfo;
|
import javax.persistence.spi.PersistenceUnitInfo;
|
||||||
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.integrator.spi.Integrator;
|
||||||
import org.hibernate.jpa.HibernatePersistenceProvider;
|
import org.hibernate.jpa.HibernatePersistenceProvider;
|
||||||
|
import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl;
|
||||||
|
import org.hibernate.jpa.boot.spi.IntegratorProvider;
|
||||||
|
import org.hibernate.osgi.util.OsgiServiceUtil;
|
||||||
import org.osgi.framework.Bundle;
|
import org.osgi.framework.Bundle;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
import org.osgi.framework.BundleReference;
|
import org.osgi.framework.BundleReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,45 +49,42 @@ public class OsgiPersistenceProvider extends HibernatePersistenceProvider {
|
||||||
private OsgiClassLoader osgiClassLoader;
|
private OsgiClassLoader osgiClassLoader;
|
||||||
|
|
||||||
private OsgiJtaPlatform osgiJtaPlatform;
|
private OsgiJtaPlatform osgiJtaPlatform;
|
||||||
|
|
||||||
private Bundle requestingBundle;
|
private Bundle requestingBundle;
|
||||||
|
|
||||||
public OsgiPersistenceProvider (OsgiClassLoader osgiClassLoader,
|
private BundleContext context;
|
||||||
OsgiJtaPlatform osgiJtaPlatform,
|
|
||||||
Bundle requestingBundle ) {
|
public OsgiPersistenceProvider(OsgiClassLoader osgiClassLoader, OsgiJtaPlatform osgiJtaPlatform,
|
||||||
|
Bundle requestingBundle, BundleContext context) {
|
||||||
this.osgiClassLoader = osgiClassLoader;
|
this.osgiClassLoader = osgiClassLoader;
|
||||||
this.osgiJtaPlatform = osgiJtaPlatform;
|
this.osgiJtaPlatform = osgiJtaPlatform;
|
||||||
this.requestingBundle = requestingBundle;
|
this.requestingBundle = requestingBundle;
|
||||||
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Does "hibernate.classloaders" and osgiClassLoader need added to the
|
// TODO: Does "hibernate.classloaders" and osgiClassLoader need added to the
|
||||||
// EMFBuilder somehow?
|
// EMFBuilder somehow?
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) {
|
public EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) {
|
||||||
if ( properties == null ) {
|
generateProperties( properties );
|
||||||
properties = new HashMap();
|
|
||||||
}
|
|
||||||
properties.put( AvailableSettings.JTA_PLATFORM, osgiJtaPlatform );
|
|
||||||
// TODO: This needs tested.
|
// TODO: This needs tested.
|
||||||
properties.put( org.hibernate.jpa.AvailableSettings.SCANNER,
|
properties.put( org.hibernate.jpa.AvailableSettings.SCANNER, new OsgiScanner( requestingBundle ) );
|
||||||
new OsgiScanner( requestingBundle ) );
|
|
||||||
// TODO: This is temporary -- for PersistenceXmlParser's use of
|
// TODO: This is temporary -- for PersistenceXmlParser's use of
|
||||||
// ClassLoaderServiceImpl#fromConfigSettings
|
// ClassLoaderServiceImpl#fromConfigSettings
|
||||||
properties.put( AvailableSettings.ENVIRONMENT_CLASSLOADER, osgiClassLoader );
|
properties.put( AvailableSettings.ENVIRONMENT_CLASSLOADER, osgiClassLoader );
|
||||||
|
|
||||||
osgiClassLoader.addBundle( requestingBundle );
|
osgiClassLoader.addBundle( requestingBundle );
|
||||||
|
|
||||||
return super.createEntityManagerFactory( persistenceUnitName, properties );
|
return super.createEntityManagerFactory( persistenceUnitName, properties );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) {
|
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) {
|
||||||
if ( properties == null ) {
|
generateProperties( properties );
|
||||||
properties = new HashMap();
|
|
||||||
}
|
// OSGi ClassLoaders must implement BundleReference
|
||||||
properties.put( AvailableSettings.JTA_PLATFORM, osgiJtaPlatform );
|
|
||||||
// OSGi ClassLoaders must implement BundleReference
|
|
||||||
properties.put( org.hibernate.jpa.AvailableSettings.SCANNER,
|
properties.put( org.hibernate.jpa.AvailableSettings.SCANNER,
|
||||||
new OsgiScanner( ( (BundleReference) info.getClassLoader() ).getBundle() ) );
|
new OsgiScanner( ( (BundleReference) info.getClassLoader() ).getBundle() ) );
|
||||||
|
|
||||||
|
@ -89,4 +92,23 @@ public class OsgiPersistenceProvider extends HibernatePersistenceProvider {
|
||||||
|
|
||||||
return super.createContainerEntityManagerFactory( info, properties );
|
return super.createContainerEntityManagerFactory( info, properties );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void generateProperties(Map properties) {
|
||||||
|
if ( properties == null ) {
|
||||||
|
properties = new HashMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
properties.put( AvailableSettings.JTA_PLATFORM, osgiJtaPlatform );
|
||||||
|
|
||||||
|
final List<Integrator> integrators = OsgiServiceUtil.getServiceImpls( Integrator.class, context );
|
||||||
|
IntegratorProvider integratorProvider = new IntegratorProvider() {
|
||||||
|
@Override
|
||||||
|
public List<Integrator> getIntegrators() {
|
||||||
|
return integrators;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
properties.put( EntityManagerFactoryBuilderImpl.INTEGRATOR_PROVIDER, integratorProvider );
|
||||||
|
|
||||||
|
// TODO: other types of services?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
package org.hibernate.osgi;
|
package org.hibernate.osgi;
|
||||||
|
|
||||||
import org.osgi.framework.Bundle;
|
import org.osgi.framework.Bundle;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
import org.osgi.framework.ServiceFactory;
|
import org.osgi.framework.ServiceFactory;
|
||||||
import org.osgi.framework.ServiceRegistration;
|
import org.osgi.framework.ServiceRegistration;
|
||||||
|
|
||||||
|
@ -37,14 +38,18 @@ public class OsgiPersistenceProviderService implements ServiceFactory {
|
||||||
|
|
||||||
private OsgiJtaPlatform osgiJtaPlatform;
|
private OsgiJtaPlatform osgiJtaPlatform;
|
||||||
|
|
||||||
public OsgiPersistenceProviderService( OsgiClassLoader osgiClassLoader, OsgiJtaPlatform osgiJtaPlatform ) {
|
private BundleContext context;
|
||||||
|
|
||||||
|
public OsgiPersistenceProviderService( OsgiClassLoader osgiClassLoader,
|
||||||
|
OsgiJtaPlatform osgiJtaPlatform, BundleContext context ) {
|
||||||
this.osgiClassLoader = osgiClassLoader;
|
this.osgiClassLoader = osgiClassLoader;
|
||||||
this.osgiJtaPlatform = osgiJtaPlatform;
|
this.osgiJtaPlatform = osgiJtaPlatform;
|
||||||
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getService(Bundle requestingBundle, ServiceRegistration registration) {
|
public Object getService(Bundle requestingBundle, ServiceRegistration registration) {
|
||||||
return new OsgiPersistenceProvider(osgiClassLoader, osgiJtaPlatform, requestingBundle);
|
return new OsgiPersistenceProvider(osgiClassLoader, osgiJtaPlatform, requestingBundle, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,13 +20,18 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.osgi;
|
package org.hibernate.osgi;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.hibernate.integrator.spi.Integrator;
|
||||||
|
import org.hibernate.osgi.util.OsgiServiceUtil;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.osgi.framework.Bundle;
|
import org.osgi.framework.Bundle;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
import org.osgi.framework.ServiceFactory;
|
import org.osgi.framework.ServiceFactory;
|
||||||
import org.osgi.framework.ServiceRegistration;
|
import org.osgi.framework.ServiceRegistration;
|
||||||
|
|
||||||
|
@ -54,9 +59,13 @@ public class OsgiSessionFactoryService implements ServiceFactory {
|
||||||
|
|
||||||
private OsgiJtaPlatform osgiJtaPlatform;
|
private OsgiJtaPlatform osgiJtaPlatform;
|
||||||
|
|
||||||
public OsgiSessionFactoryService( OsgiClassLoader osgiClassLoader, OsgiJtaPlatform osgiJtaPlatform ) {
|
private BundleContext context;
|
||||||
|
|
||||||
|
public OsgiSessionFactoryService( OsgiClassLoader osgiClassLoader, OsgiJtaPlatform osgiJtaPlatform,
|
||||||
|
BundleContext context ) {
|
||||||
this.osgiClassLoader = osgiClassLoader;
|
this.osgiClassLoader = osgiClassLoader;
|
||||||
this.osgiJtaPlatform = osgiJtaPlatform;
|
this.osgiJtaPlatform = osgiJtaPlatform;
|
||||||
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -70,6 +79,11 @@ public class OsgiSessionFactoryService implements ServiceFactory {
|
||||||
BootstrapServiceRegistryBuilder builder = new BootstrapServiceRegistryBuilder();
|
BootstrapServiceRegistryBuilder builder = new BootstrapServiceRegistryBuilder();
|
||||||
builder.with( osgiClassLoader );
|
builder.with( osgiClassLoader );
|
||||||
|
|
||||||
|
List<Integrator> integrators = OsgiServiceUtil.getServiceImpls( Integrator.class, context );
|
||||||
|
for (Integrator integrator : integrators) {
|
||||||
|
builder.with( integrator );
|
||||||
|
}
|
||||||
|
|
||||||
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder( builder.build() )
|
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder( builder.build() )
|
||||||
.applySettings(configuration.getProperties()).build();
|
.applySettings(configuration.getProperties()).build();
|
||||||
return configuration.buildSessionFactory(serviceRegistry);
|
return configuration.buildSessionFactory(serviceRegistry);
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
import org.osgi.framework.ServiceReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brett Meyer
|
||||||
|
*/
|
||||||
|
public class OsgiServiceUtil {
|
||||||
|
|
||||||
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class,
|
||||||
|
OsgiServiceUtil.class.getName() );
|
||||||
|
|
||||||
|
public static <T> List<T> getServiceImpls(Class<T> contract, BundleContext context) {
|
||||||
|
List<T> serviceImpls = new ArrayList<T>();
|
||||||
|
try {
|
||||||
|
Collection<ServiceReference<T>> serviceRefs = context.getServiceReferences( contract, null );
|
||||||
|
for ( ServiceReference<T> serviceRef : serviceRefs ) {
|
||||||
|
serviceImpls.add( context.getService( serviceRef ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e ) {
|
||||||
|
LOG.unableToDiscoverOsgiService( contract.getName(), e );
|
||||||
|
}
|
||||||
|
return serviceImpls;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue