HHH-8646 use ServiceTracker in OsgiServiceUtil

This commit is contained in:
Brett Meyer 2013-10-28 12:40:06 -04:00
parent 2bac8d8cbe
commit e135566c0e
5 changed files with 69 additions and 29 deletions

View File

@ -24,6 +24,7 @@ dependencies {
// MUST use 4.3.1! 4.3.0 was compiled with "-target jsr14". // 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 // http://blog.osgi.org/2012/10/43-companion-code-for-java-7.html
compile( "org.osgi:org.osgi.core:4.3.1" ) compile( "org.osgi:org.osgi.core:4.3.1" )
compile( "org.osgi:org.osgi.compendium:4.3.1" )
testCompile( libraries.shrinkwrap_api ) testCompile( libraries.shrinkwrap_api )
testCompile( libraries.shrinkwrap ) testCompile( libraries.shrinkwrap )

View File

@ -30,7 +30,6 @@ import org.hibernate.TransactionException;
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper; import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform; import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
/** /**
* Offers the JTA Platform provided by the OSGi container. The Enterprise * Offers the JTA Platform provided by the OSGi container. The Enterprise
@ -55,14 +54,32 @@ public class OsgiJtaPlatform implements JtaPlatform {
@Override @Override
public TransactionManager retrieveTransactionManager() { public TransactionManager retrieveTransactionManager() {
final ServiceReference sr = bundleContext.getServiceReference( TransactionManager.class.getName() ); try {
return sr == null ? null : (TransactionManager) bundleContext.getService( sr ); final TransactionManager transactionManager = OsgiServiceUtil.getServiceImpl(
TransactionManager.class, bundleContext );
if (transactionManager == null) {
throw new TransactionException("Cannot retrieve the TransactionManager OSGi service!");
}
return transactionManager;
}
catch (Exception e) {
throw new TransactionException("Cannot retrieve the TransactionManager OSGi service!", e);
}
} }
@Override @Override
public UserTransaction retrieveUserTransaction() { public UserTransaction retrieveUserTransaction() {
final ServiceReference sr = bundleContext.getServiceReference( UserTransaction.class.getName() ); try {
return sr == null ? null : (UserTransaction) bundleContext.getService( sr ); final UserTransaction userTransaction = OsgiServiceUtil.getServiceImpl(
UserTransaction.class, bundleContext );
if (userTransaction == null) {
throw new TransactionException("Cannot retrieve the UserTransaction OSGi service!");
}
return userTransaction;
}
catch (Exception e) {
throw new TransactionException("Cannot retrieve the UserTransaction OSGi service!", e);
}
} }
@Override @Override
@ -73,7 +90,12 @@ public class OsgiJtaPlatform implements JtaPlatform {
@Override @Override
public boolean canRegisterSynchronization() { public boolean canRegisterSynchronization() {
return JtaStatusHelper.isActive( retrieveTransactionManager() ); try {
return JtaStatusHelper.isActive( retrieveTransactionManager() );
}
catch (Exception e) {
return false;
}
} }
@Override @Override

View File

@ -23,6 +23,7 @@
*/ */
package org.hibernate.osgi; package org.hibernate.osgi;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -121,30 +122,30 @@ public class OsgiPersistenceProvider extends HibernatePersistenceProvider {
settings.put( AvailableSettings.JTA_PLATFORM, osgiJtaPlatform ); settings.put( AvailableSettings.JTA_PLATFORM, osgiJtaPlatform );
final List<Integrator> integrators = OsgiServiceUtil.getServiceImpls( Integrator.class, context ); final Integrator[] integrators = OsgiServiceUtil.getServiceImpls( Integrator.class, context );
final IntegratorProvider integratorProvider = new IntegratorProvider() { final IntegratorProvider integratorProvider = new IntegratorProvider() {
@Override @Override
public List<Integrator> getIntegrators() { public List<Integrator> getIntegrators() {
return integrators; return Arrays.asList( integrators );
} }
}; };
settings.put( EntityManagerFactoryBuilderImpl.INTEGRATOR_PROVIDER, integratorProvider ); settings.put( EntityManagerFactoryBuilderImpl.INTEGRATOR_PROVIDER, integratorProvider );
final List<StrategyRegistrationProvider> strategyRegistrationProviders = OsgiServiceUtil.getServiceImpls( final StrategyRegistrationProvider[] strategyRegistrationProviders = OsgiServiceUtil.getServiceImpls(
StrategyRegistrationProvider.class, context ); StrategyRegistrationProvider.class, context );
final StrategyRegistrationProviderList strategyRegistrationProviderList = new StrategyRegistrationProviderList() { final StrategyRegistrationProviderList strategyRegistrationProviderList = new StrategyRegistrationProviderList() {
@Override @Override
public List<StrategyRegistrationProvider> getStrategyRegistrationProviders() { public List<StrategyRegistrationProvider> getStrategyRegistrationProviders() {
return strategyRegistrationProviders; return Arrays.asList( strategyRegistrationProviders );
} }
}; };
settings.put( EntityManagerFactoryBuilderImpl.STRATEGY_REGISTRATION_PROVIDERS, strategyRegistrationProviderList ); settings.put( EntityManagerFactoryBuilderImpl.STRATEGY_REGISTRATION_PROVIDERS, strategyRegistrationProviderList );
final List<TypeContributor> typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context ); final TypeContributor[] typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context );
final TypeContributorList typeContributorList = new TypeContributorList() { final TypeContributorList typeContributorList = new TypeContributorList() {
@Override @Override
public List<TypeContributor> getTypeContributors() { public List<TypeContributor> getTypeContributors() {
return typeContributors; return Arrays.asList( typeContributors );
} }
}; };
settings.put( EntityManagerFactoryBuilderImpl.TYPE_CONTRIBUTORS, typeContributorList ); settings.put( EntityManagerFactoryBuilderImpl.TYPE_CONTRIBUTORS, typeContributorList );

View File

@ -20,13 +20,11 @@
*/ */
package org.hibernate.osgi; package org.hibernate.osgi;
import java.util.ArrayList; import java.lang.reflect.Array;
import java.util.Collection;
import java.util.List;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTracker;
/** /**
* Utilities for dealing with OSGi environments * Utilities for dealing with OSGi environments
@ -37,28 +35,47 @@ public class OsgiServiceUtil {
private static final Logger LOG = Logger.getLogger( OsgiServiceUtil.class ); private static final Logger LOG = Logger.getLogger( OsgiServiceUtil.class );
/** /**
* Locate all implementors of the given service contract in the given OSGi buindle context * Locate all implementors of the given service contract in the given OSGi buindle context. Utilizes
* {@link ServiceTracker} (best practice, automatically handles a lot of boilerplate and error conditions).
* *
* @param contract The service contract for which to locate implementors * @param contract The service contract for which to locate implementors
* @param context The OSGi bundle context * @param context The OSGi bundle context
* @param <T> The Java type of the service to locate * @param T[] The Java type of the service to locate
* *
* @return All know implementors * @return All know implementors
*/ */
public static <T> List<T> getServiceImpls(Class<T> contract, BundleContext context) { public static <T> T[] getServiceImpls(Class<T> contract, BundleContext bundleContext) {
final List<T> serviceImpls = new ArrayList<T>(); final ServiceTracker<T, T> serviceTracker = new ServiceTracker<T, T>( bundleContext, contract, null );
try { try {
final Collection<ServiceReference<T>> serviceRefs = context.getServiceReferences( contract, null ); T[] services = (T[]) serviceTracker.getServices();
for ( ServiceReference<T> serviceRef : serviceRefs ) { if (services != null) {
serviceImpls.add( context.getService( serviceRef ) ); return services;
} }
} }
catch ( Exception e ) { catch ( Exception e ) {
LOG.warnf( e, "Exception while discovering OSGi service implementations : %s", contract.getName() ); LOG.warnf( e, "Exception while discovering OSGi service implementations : %s", contract.getName() );
} }
return serviceImpls; return (T[]) Array.newInstance(contract, 0);
} }
private OsgiServiceUtil() { /**
* Locate the single implementor of the given service contract in the given OSGi buindle context. Utilizes
* {@link ServiceTracker#waitForService(long)}
*
* @param contract The service contract for which to locate implementors
* @param context The OSGi bundle context
* @param T[] The Java type of the service to locate
*
* @return All know implementors
*/
public static <T> T getServiceImpl(Class<T> contract, BundleContext bundleContext) {
final ServiceTracker<T, T> serviceTracker = new ServiceTracker<T, T>( bundleContext, contract, null );
try {
return (T) serviceTracker.waitForService( 1000 );
}
catch ( Exception e ) {
LOG.warnf( e, "Exception while discovering OSGi service implementations : %s", contract.getName() );
return null;
}
} }
} }

View File

@ -21,7 +21,6 @@
package org.hibernate.osgi; package org.hibernate.osgi;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import org.hibernate.SessionFactory; import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder; import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
@ -107,18 +106,18 @@ public class OsgiSessionFactoryService implements ServiceFactory {
final BootstrapServiceRegistryBuilder builder = new BootstrapServiceRegistryBuilder(); final BootstrapServiceRegistryBuilder builder = new BootstrapServiceRegistryBuilder();
builder.with( osgiClassLoader ); builder.with( osgiClassLoader );
final List<Integrator> integrators = OsgiServiceUtil.getServiceImpls( Integrator.class, context ); final Integrator[] integrators = OsgiServiceUtil.getServiceImpls( Integrator.class, context );
for ( Integrator integrator : integrators ) { for ( Integrator integrator : integrators ) {
builder.with( integrator ); builder.with( integrator );
} }
final List<StrategyRegistrationProvider> strategyRegistrationProviders final StrategyRegistrationProvider[] strategyRegistrationProviders
= OsgiServiceUtil.getServiceImpls( StrategyRegistrationProvider.class, context ); = OsgiServiceUtil.getServiceImpls( StrategyRegistrationProvider.class, context );
for ( StrategyRegistrationProvider strategyRegistrationProvider : strategyRegistrationProviders ) { for ( StrategyRegistrationProvider strategyRegistrationProvider : strategyRegistrationProviders ) {
builder.withStrategySelectors( strategyRegistrationProvider ); builder.withStrategySelectors( strategyRegistrationProvider );
} }
final List<TypeContributor> typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context ); final TypeContributor[] typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context );
for ( TypeContributor typeContributor : typeContributors ) { for ( TypeContributor typeContributor : typeContributors ) {
configuration.registerTypeContributor( typeContributor ); configuration.registerTypeContributor( typeContributor );
} }