HHH-7996 arquillian-based OSGi unit test, minor CL fixes
This commit is contained in:
parent
17d9a2c1fc
commit
58622f3e10
|
@ -51,7 +51,7 @@ jar {
|
||||||
manifest {
|
manifest {
|
||||||
instruction 'Bundle-Description', 'Hibernate ORM Core'
|
instruction 'Bundle-Description', 'Hibernate ORM Core'
|
||||||
|
|
||||||
instruction 'Import-Package',
|
instructionFirst 'Import-Package',
|
||||||
'javax.security.auth;resolution:=optional',
|
'javax.security.auth;resolution:=optional',
|
||||||
'javax.security.jacc;resolution:=optional',
|
'javax.security.jacc;resolution:=optional',
|
||||||
'javax.validation;resolution:=optional',
|
'javax.validation;resolution:=optional',
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
||||||
public ClassLoaderServiceImpl(Collection<ClassLoader> providedClassLoaders) {
|
public ClassLoaderServiceImpl(Collection<ClassLoader> providedClassLoaders) {
|
||||||
final LinkedHashSet<ClassLoader> orderedClassLoaderSet = new LinkedHashSet<ClassLoader>();
|
final LinkedHashSet<ClassLoader> orderedClassLoaderSet = new LinkedHashSet<ClassLoader>();
|
||||||
|
|
||||||
// first add all provided class loaders, if any
|
// first, add all provided class loaders, if any
|
||||||
if ( providedClassLoaders != null ) {
|
if ( providedClassLoaders != null ) {
|
||||||
for ( ClassLoader classLoader : providedClassLoaders ) {
|
for ( ClassLoader classLoader : providedClassLoaders ) {
|
||||||
if ( classLoader != null ) {
|
if ( classLoader != null ) {
|
||||||
|
@ -87,8 +87,9 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// normalize adding known class-loaders...
|
// normalize adding known class-loaders...
|
||||||
// first, the Hibernate class loader
|
// then the Hibernate class loader
|
||||||
orderedClassLoaderSet.add( ClassLoaderServiceImpl.class.getClassLoader() );
|
orderedClassLoaderSet.add( ClassLoaderServiceImpl.class.getClassLoader() );
|
||||||
|
|
||||||
// then the TCCL, if one...
|
// then the TCCL, if one...
|
||||||
final ClassLoader tccl = locateTCCL();
|
final ClassLoader tccl = locateTCCL();
|
||||||
if ( tccl != null ) {
|
if ( tccl != null ) {
|
||||||
|
|
|
@ -23,6 +23,11 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.internal;
|
package org.hibernate.internal;
|
||||||
|
|
||||||
|
import static org.jboss.logging.Logger.Level.DEBUG;
|
||||||
|
import static org.jboss.logging.Logger.Level.ERROR;
|
||||||
|
import static org.jboss.logging.Logger.Level.INFO;
|
||||||
|
import static org.jboss.logging.Logger.Level.WARN;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -33,37 +38,32 @@ import java.sql.SQLWarning;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.naming.NameNotFoundException;
|
import javax.naming.NameNotFoundException;
|
||||||
import javax.naming.NamingException;
|
import javax.naming.NamingException;
|
||||||
import javax.transaction.Synchronization;
|
import javax.transaction.Synchronization;
|
||||||
import javax.transaction.SystemException;
|
import javax.transaction.SystemException;
|
||||||
|
|
||||||
import org.jboss.logging.BasicLogger;
|
|
||||||
import org.jboss.logging.Cause;
|
|
||||||
import org.jboss.logging.LogMessage;
|
|
||||||
import org.jboss.logging.Message;
|
|
||||||
import org.jboss.logging.MessageLogger;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.cache.CacheException;
|
import org.hibernate.cache.CacheException;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
|
||||||
|
import org.hibernate.engine.jndi.JndiException;
|
||||||
|
import org.hibernate.engine.jndi.JndiNameException;
|
||||||
import org.hibernate.engine.loading.internal.CollectionLoadContext;
|
import org.hibernate.engine.loading.internal.CollectionLoadContext;
|
||||||
import org.hibernate.engine.loading.internal.EntityLoadContext;
|
import org.hibernate.engine.loading.internal.EntityLoadContext;
|
||||||
import org.hibernate.engine.spi.CollectionKey;
|
import org.hibernate.engine.spi.CollectionKey;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.id.IntegralDataTypeHolder;
|
import org.hibernate.id.IntegralDataTypeHolder;
|
||||||
import org.hibernate.engine.jndi.JndiException;
|
|
||||||
import org.hibernate.engine.jndi.JndiNameException;
|
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.SerializationException;
|
import org.hibernate.type.SerializationException;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
import org.jboss.logging.BasicLogger;
|
||||||
import static org.jboss.logging.Logger.Level.DEBUG;
|
import org.jboss.logging.Cause;
|
||||||
import static org.jboss.logging.Logger.Level.ERROR;
|
import org.jboss.logging.LogMessage;
|
||||||
import static org.jboss.logging.Logger.Level.INFO;
|
import org.jboss.logging.Message;
|
||||||
import static org.jboss.logging.Logger.Level.WARN;
|
import org.jboss.logging.MessageLogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The jboss-logging {@link MessageLogger} for the hibernate-core module. It reserves message ids ranging from
|
* The jboss-logging {@link MessageLogger} for the hibernate-core module. It reserves message ids ranging from
|
||||||
|
@ -1621,12 +1621,4 @@ public interface CoreMessageLogger extends BasicLogger {
|
||||||
@LogMessage(level = INFO)
|
@LogMessage(level = INFO)
|
||||||
@Message( value = "'javax.persistence.validation.mode' named multiple values : %s", id = 448 )
|
@Message( value = "'javax.persistence.validation.mode' named multiple values : %s", id = 448 )
|
||||||
void multipleValidationModes(String modes);
|
void multipleValidationModes(String modes);
|
||||||
|
|
||||||
@LogMessage(level = WARN)
|
|
||||||
@Message(value = "Exception while loading a class or resource found during scanning", id = 449)
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,10 @@ public class HibernatePersistenceProvider implements PersistenceProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected EntityManagerFactoryBuilder getEntityManagerFactoryBuilderOrNull(String persistenceUnitName, Map properties) {
|
protected EntityManagerFactoryBuilder getEntityManagerFactoryBuilderOrNull(String persistenceUnitName, Map properties) {
|
||||||
|
return getEntityManagerFactoryBuilderOrNull( persistenceUnitName, properties, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected EntityManagerFactoryBuilder getEntityManagerFactoryBuilderOrNull(String persistenceUnitName, Map properties, ClassLoader providedClassLoader) {
|
||||||
log.tracef( "Attempting to obtain correct EntityManagerFactoryBuilder for persistenceUnitName : %s", persistenceUnitName );
|
log.tracef( "Attempting to obtain correct EntityManagerFactoryBuilder for persistenceUnitName : %s", persistenceUnitName );
|
||||||
|
|
||||||
final Map integration = wrap( properties );
|
final Map integration = wrap( properties );
|
||||||
|
@ -118,7 +122,7 @@ public class HibernatePersistenceProvider implements PersistenceProvider {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Bootstrap.getEntityManagerFactoryBuilder( persistenceUnit, integration );
|
return Bootstrap.getEntityManagerFactoryBuilder( persistenceUnit, integration, providedClassLoader );
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug( "Found no matching persistence units" );
|
log.debug( "Found no matching persistence units" );
|
||||||
|
|
|
@ -1,28 +1,123 @@
|
||||||
|
configurations {
|
||||||
|
osgiRuntime
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
testResult
|
||||||
|
testClientBundle
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets.test {
|
||||||
|
compileClasspath += sourceSets.testResult.output
|
||||||
|
runtimeClasspath += sourceSets.testResult.output
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets.testClientBundle {
|
||||||
|
compileClasspath += sourceSets.testResult.output
|
||||||
|
runtimeClasspath += sourceSets.testResult.output
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile( project( ':hibernate-core' ) )
|
compile( project( ':hibernate-core' ) )
|
||||||
compile( project( ':hibernate-entitymanager' ) )
|
compile( project( ':hibernate-entitymanager' ) )
|
||||||
// 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" )
|
||||||
|
|
||||||
|
testCompile( libraries.shrinkwrap_api )
|
||||||
|
testCompile( libraries.shrinkwrap )
|
||||||
|
testCompile( "org.jboss.arquillian.junit:arquillian-junit-container:1.0.3.Final" )
|
||||||
|
testCompile( "org.jboss.osgi.metadata:jbosgi-metadata:3.0.0.CR1" )
|
||||||
|
testRuntime( "org.jboss.arquillian.container:arquillian-osgi-felix:2.0.0.CR4" )
|
||||||
|
testRuntime( "org.apache.felix:org.apache.felix.framework:4.0.3" )
|
||||||
|
testRuntime( "org.apache.felix:org.apache.felix.main:4.0.3" )
|
||||||
|
testRuntime( "org.jboss.logmanager:jboss-logmanager:1.4.1.Final" )
|
||||||
|
|
||||||
|
// Local copies of all jars needed fur the OSGi runtime.
|
||||||
|
osgiRuntime( "org.jboss.arquillian.osgi:arquillian-osgi-bundle:1.0.3.Final" )
|
||||||
|
osgiRuntime( "org.ops4j.pax.url:pax-url-wrap:1.5.2" )
|
||||||
|
osgiRuntime( "org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0-SNAPSHOT" )
|
||||||
|
osgiRuntime( "javax.enterprise:cdi-api:1.1-PFD" )
|
||||||
|
osgiRuntime( "org.jboss.spec.javax.interceptor:jboss-interceptors-api_1.2_spec:1.0.0.Alpha1" )
|
||||||
|
osgiRuntime( "org.jboss.spec.javax.transaction:jboss-transaction-api_1.2_spec:1.0.0.Alpha1" )
|
||||||
|
osgiRuntime( "commons-collections:commons-collections:3.2.1" )
|
||||||
|
osgiRuntime( "commons-pool:commons-pool:1.6" )
|
||||||
|
osgiRuntime( "commons-dbcp:commons-dbcp:1.4" )
|
||||||
|
osgiRuntime( "commons-lang:commons-lang:2.6" )
|
||||||
|
osgiRuntime( "net.sourceforge.serp:serp:1.14.1" )
|
||||||
|
osgiRuntime( "com.h2database:h2:1.3.170" )
|
||||||
|
osgiRuntime( "org.apache.servicemix.bundles:org.apache.servicemix.bundles.antlr:2.7.7_5" )
|
||||||
|
osgiRuntime( libraries.javassist )
|
||||||
|
osgiRuntime( "org.apache.servicemix.specs:org.apache.servicemix.specs.jsr303-api-1.0.0:2.2.0" )
|
||||||
|
osgiRuntime( "org.apache.servicemix.bundles:org.apache.servicemix.bundles.ant:1.8.2_2" )
|
||||||
|
osgiRuntime( "org.apache.servicemix.specs:org.apache.servicemix.specs.stax-api-1.2:2.2.0" )
|
||||||
|
osgiRuntime( "org.apache.servicemix.bundles:org.apache.servicemix.bundles.dom4j:1.6.1_5" )
|
||||||
|
osgiRuntime( libraries.commons_annotations )
|
||||||
|
osgiRuntime( libraries.jandex )
|
||||||
|
osgiRuntime( libraries.classmate )
|
||||||
|
osgiRuntime( libraries.logging )
|
||||||
|
|
||||||
|
testClientBundleCompile( project( ':hibernate-core' ) )
|
||||||
|
testClientBundleCompile( project( ':hibernate-entitymanager' ) )
|
||||||
|
// 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
|
||||||
|
testClientBundleCompile( "org.osgi:org.osgi.core:4.3.1" )
|
||||||
}
|
}
|
||||||
|
|
||||||
def pomName() {
|
def pomName() {
|
||||||
return 'Hibernate OSGi Support'
|
return 'Hibernate OSGi Support'
|
||||||
}
|
}
|
||||||
|
|
||||||
def pomDescription() {
|
def pomDescription() {
|
||||||
return 'Support for running Hibernate O/RM in OSGi environments'
|
return 'Support for running Hibernate O/RM in OSGi environments'
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
manifest {
|
manifest {
|
||||||
instruction 'Bundle-Activator', 'org.hibernate.osgi.HibernateBundleActivator'
|
instruction 'Bundle-Activator', 'org.hibernate.osgi.HibernateBundleActivator'
|
||||||
instruction 'Bundle-Description', 'Hibernate ORM OSGi'
|
instruction 'Bundle-Description', 'Hibernate ORM OSGi'
|
||||||
|
|
||||||
instruction 'Import-Package',
|
instruction 'Import-Package',
|
||||||
// TODO: Shouldn't have to explicitly list this, but the plugin
|
// TODO: Shouldn't have to explicitly list this, but the plugin
|
||||||
// generates it with a [1.0,2) version.
|
// generates it with a [1.0,2) version.
|
||||||
'javax.persistence;version="2.1.0"',
|
'javax.persistence;version="2.1.0"',
|
||||||
'javax.persistence.spi;version="2.1.0"'
|
'javax.persistence.spi;version="2.1.0"'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task copyBnd(type: Copy) {
|
||||||
|
into "$buildDir/osgi-lib/bnd"
|
||||||
|
from "src/test/resources/bnd"
|
||||||
|
}
|
||||||
|
|
||||||
|
task runBnd(type: JavaExec){
|
||||||
|
main = "-jar"
|
||||||
|
args "$buildDir/osgi-lib/bnd/bnd.jar", "$buildDir/osgi-lib/bnd/cdi-api.bnd", "$buildDir/osgi-lib/bnd/el-api.bnd", "$buildDir/osgi-lib/bnd/jandex.bnd", "$buildDir/osgi-lib/bnd/javassist.bnd", "$buildDir/osgi-lib/bnd/serp.bnd"
|
||||||
|
}
|
||||||
|
|
||||||
|
task copyToLib(type: Copy) {
|
||||||
|
into "$buildDir/osgi-lib"
|
||||||
|
from configurations.osgiRuntime
|
||||||
|
}
|
||||||
|
|
||||||
|
task testClientBundleJar(type: Jar) {
|
||||||
|
from sourceSets.testClientBundle.output, sourceSets.testResult.output
|
||||||
|
destinationDir new File("$buildDir/osgi-lib")
|
||||||
|
archiveName "testClientBundle.jar"
|
||||||
|
|
||||||
|
// The OSGi plugin acts up when we need to export multiple source sets. Just do it manually.
|
||||||
|
manifest {
|
||||||
|
attributes("Export-Package" : "org.hibernate.osgi.test.client,org.hibernate.osgi.test.result",
|
||||||
|
"Bundle-Name" : "testClientBundle",
|
||||||
|
"Bundle-Activator" : "org.hibernate.osgi.test.client.OsgiTestActivator",
|
||||||
|
"Bundle-ManifestVersion" : "2",
|
||||||
|
"Bundle-SymbolicName" : "testClientBundle",
|
||||||
|
"Import-Package" : "javassist.util.proxy,javax.persistence,javax.persistence.spi,org.h2,org.hibernate,org.hibernate.proxy,org.osgi.framework")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runBnd.dependsOn copyToLib
|
||||||
|
runBnd.dependsOn copyBnd
|
||||||
|
test.dependsOn runBnd
|
||||||
|
test.dependsOn testClientBundleJar
|
||||||
|
test.dependsOn jar
|
||||||
|
|
|
@ -26,7 +26,6 @@ import java.util.Collection;
|
||||||
|
|
||||||
import javax.persistence.PersistenceException;
|
import javax.persistence.PersistenceException;
|
||||||
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
|
||||||
import org.hibernate.jpa.boot.archive.spi.ArchiveContext;
|
import org.hibernate.jpa.boot.archive.spi.ArchiveContext;
|
||||||
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptor;
|
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptor;
|
||||||
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry;
|
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry;
|
||||||
|
@ -43,10 +42,7 @@ import org.osgi.framework.wiring.BundleWiring;
|
||||||
* @author Tim Ward
|
* @author Tim Ward
|
||||||
*/
|
*/
|
||||||
public class OsgiArchiveDescriptor implements ArchiveDescriptor {
|
public class OsgiArchiveDescriptor implements ArchiveDescriptor {
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
private static final Logger LOG = Logger.getLogger( OsgiArchiveDescriptor.class );
|
||||||
CoreMessageLogger.class,
|
|
||||||
OsgiArchiveDescriptor.class.getName()
|
|
||||||
);
|
|
||||||
|
|
||||||
private final Bundle persistenceBundle;
|
private final Bundle persistenceBundle;
|
||||||
private final BundleWiring bundleWiring;
|
private final BundleWiring bundleWiring;
|
||||||
|
@ -119,7 +115,7 @@ public class OsgiArchiveDescriptor implements ArchiveDescriptor {
|
||||||
context.obtainArchiveEntryHandler( entry ).handleEntry( entry, context );
|
context.obtainArchiveEntryHandler( entry ).handleEntry( entry, context );
|
||||||
}
|
}
|
||||||
catch ( Exception e ) {
|
catch ( Exception e ) {
|
||||||
LOG.unableToLoadScannedClassOrResource( e );
|
LOG.warn( "Exception while loading a class or resource found during scanning", e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,40 +52,45 @@ public class OsgiClassLoader extends ClassLoader {
|
||||||
private Map<String, URL> resourceCache = new HashMap<String, URL>();
|
private Map<String, URL> resourceCache = new HashMap<String, URL>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the class and break on first found match.
|
* Load the class and break on first found match. DO NOT use ClassLoader#parent, which is typically the
|
||||||
|
* SystemClassLoader for most containers. Instead, allow the ClassNotFoundException to be thrown.
|
||||||
|
* ClassLoaderServiceImpl will check the SystemClassLoader later on.
|
||||||
|
*
|
||||||
* TODO: Should this throw a different exception or warn if multiple
|
* TODO: Should this throw a different exception or warn if multiple
|
||||||
* classes were found? Naming collisions can and do happen in OSGi...
|
* classes were found? Naming collisions can and do happen in OSGi...
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
||||||
if ( classCache.containsKey( name ) ) {
|
synchronized (getClassLoadingLock(name)) {
|
||||||
return classCache.get( name );
|
if ( classCache.containsKey( name ) ) {
|
||||||
}
|
return classCache.get( name );
|
||||||
|
}
|
||||||
for ( Bundle bundle : bundles ) {
|
|
||||||
try {
|
for ( Bundle bundle : bundles ) {
|
||||||
final Class clazz = bundle.loadClass( name );
|
try {
|
||||||
if ( clazz != null ) {
|
final Class clazz = bundle.loadClass( name );
|
||||||
classCache.put( name, clazz );
|
if ( clazz != null ) {
|
||||||
return clazz;
|
classCache.put( name, clazz );
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception ignore ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch ( Exception ignore ) {
|
|
||||||
}
|
for ( ClassLoader classLoader : classLoaders ) {
|
||||||
}
|
try {
|
||||||
|
final Class clazz = classLoader.loadClass( name );
|
||||||
for ( ClassLoader classLoader : classLoaders ) {
|
if ( clazz != null ) {
|
||||||
try {
|
classCache.put( name, clazz );
|
||||||
final Class clazz = classLoader.loadClass( name );
|
return clazz;
|
||||||
if ( clazz != null ) {
|
}
|
||||||
classCache.put( name, clazz );
|
}
|
||||||
return clazz;
|
catch ( Exception ignore ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch ( Exception ignore ) {
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new ClassNotFoundException( "Could not load requested class : " + name );
|
throw new ClassNotFoundException( "Could not load requested class : " + name );
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.integrator.spi.Integrator;
|
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.internal.EntityManagerFactoryBuilderImpl;
|
||||||
|
import org.hibernate.jpa.boot.spi.Bootstrap;
|
||||||
|
import org.hibernate.jpa.boot.spi.EntityManagerFactoryBuilder;
|
||||||
import org.hibernate.jpa.boot.spi.IntegratorProvider;
|
import org.hibernate.jpa.boot.spi.IntegratorProvider;
|
||||||
import org.hibernate.jpa.boot.spi.StrategyRegistrationProviderList;
|
import org.hibernate.jpa.boot.spi.StrategyRegistrationProviderList;
|
||||||
import org.hibernate.jpa.boot.spi.TypeContributorList;
|
import org.hibernate.jpa.boot.spi.TypeContributorList;
|
||||||
|
@ -90,7 +92,8 @@ public class OsgiPersistenceProvider extends HibernatePersistenceProvider {
|
||||||
|
|
||||||
osgiClassLoader.addBundle( requestingBundle );
|
osgiClassLoader.addBundle( requestingBundle );
|
||||||
|
|
||||||
return super.createEntityManagerFactory( persistenceUnitName, settings );
|
final EntityManagerFactoryBuilder builder = getEntityManagerFactoryBuilderOrNull( persistenceUnitName, settings, osgiClassLoader );
|
||||||
|
return builder == null ? null : builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -106,7 +109,7 @@ public class OsgiPersistenceProvider extends HibernatePersistenceProvider {
|
||||||
|
|
||||||
osgiClassLoader.addClassLoader( info.getClassLoader() );
|
osgiClassLoader.addClassLoader( info.getClassLoader() );
|
||||||
|
|
||||||
return super.createContainerEntityManagerFactory( info, settings );
|
return Bootstrap.getEntityManagerFactoryBuilder( info, settings, osgiClassLoader ).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -138,7 +141,7 @@ public class OsgiPersistenceProvider extends HibernatePersistenceProvider {
|
||||||
settings.put( EntityManagerFactoryBuilderImpl.STRATEGY_REGISTRATION_PROVIDERS, strategyRegistrationProviderList );
|
settings.put( EntityManagerFactoryBuilderImpl.STRATEGY_REGISTRATION_PROVIDERS, strategyRegistrationProviderList );
|
||||||
|
|
||||||
final List<TypeContributor> typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context );
|
final List<TypeContributor> typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context );
|
||||||
TypeContributorList typeContributorList = new TypeContributorList() {
|
final TypeContributorList typeContributorList = new TypeContributorList() {
|
||||||
@Override
|
@Override
|
||||||
public List<TypeContributor> getTypeContributors() {
|
public List<TypeContributor> getTypeContributors() {
|
||||||
return typeContributors;
|
return typeContributors;
|
||||||
|
|
|
@ -24,7 +24,6 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
|
||||||
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.framework.ServiceReference;
|
||||||
|
@ -35,10 +34,7 @@ import org.osgi.framework.ServiceReference;
|
||||||
* @author Brett Meyer
|
* @author Brett Meyer
|
||||||
*/
|
*/
|
||||||
public class OsgiServiceUtil {
|
public class OsgiServiceUtil {
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
private static final Logger LOG = Logger.getLogger( OsgiServiceUtil.class );
|
||||||
CoreMessageLogger.class,
|
|
||||||
OsgiServiceUtil.class.getName()
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
|
@ -58,7 +54,7 @@ public class OsgiServiceUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch ( Exception e ) {
|
catch ( Exception e ) {
|
||||||
LOG.unableToDiscoverOsgiService( contract.getName(), e );
|
LOG.warnf( e, "Exception while discovering OSGi service implementations : %s", contract.getName() );
|
||||||
}
|
}
|
||||||
return serviceImpls;
|
return serviceImpls;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,10 +97,10 @@ public class OsgiSessionFactoryService implements ServiceFactory {
|
||||||
builder.withStrategySelectors( strategyRegistrationProvider );
|
builder.withStrategySelectors( strategyRegistrationProvider );
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<TypeContributor> typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context );
|
final List<TypeContributor> typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context );
|
||||||
for (TypeContributor typeContributor : typeContributors) {
|
for ( TypeContributor typeContributor : typeContributors ) {
|
||||||
configuration.registerTypeContributor( typeContributor );
|
configuration.registerTypeContributor( typeContributor );
|
||||||
}
|
}
|
||||||
|
|
||||||
final ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder( builder.build() )
|
final ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder( builder.build() )
|
||||||
.applySettings( configuration.getProperties() ).build();
|
.applySettings( configuration.getProperties() ).build();
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2013, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.hibernate.osgi.test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.hibernate.osgi.test.result.OsgiTestResults;
|
||||||
|
import org.jboss.arquillian.container.test.api.Deployment;
|
||||||
|
import org.jboss.arquillian.junit.Arquillian;
|
||||||
|
import org.jboss.arquillian.test.api.ArquillianResource;
|
||||||
|
import org.jboss.osgi.metadata.OSGiManifestBuilder;
|
||||||
|
import org.jboss.shrinkwrap.api.ShrinkWrap;
|
||||||
|
import org.jboss.shrinkwrap.api.asset.Asset;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.JavaArchive;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.osgi.framework.Bundle;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
import org.osgi.framework.ServiceReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A separate sourceset, testClientBundle, contains a persistence unit and multiple uses of Native and JPA functionality.
|
||||||
|
* Any failures that occur are logged in the OsgiTestResult service, contained in another sourceset (testResult).
|
||||||
|
*
|
||||||
|
* The "unit tests" MUST reside in testClientBundle, rather than attempting to programmatically create a bundle and obtain an SF/EMF here. There are
|
||||||
|
* MANY ClassLoader issues with that sort of setup. JPA annotations are "stripped", since one ClassLoader is used here
|
||||||
|
* to create the entity's stream and another is used to parse it within core. Further, the entire Felix framework
|
||||||
|
* is given to hibernate-osgi as the "requestingBundle" in that setup, regardless of Arquillian vs. Pax Exam. That
|
||||||
|
* causes another slew of ClassLoader issues as well.
|
||||||
|
*
|
||||||
|
* It is also important to keep OsgiTestResult in a third sourceset, rather than attempting to put it in test or
|
||||||
|
* testClientBundle. Adding testClientBundle to test's classpath causes more ClassLoader issues during runtime (and
|
||||||
|
* vice versa), similar to the above.
|
||||||
|
*
|
||||||
|
* The bottom line is that many, many alternatives were prototyped and all of them eventually hit brick walls.
|
||||||
|
* Regardless, this is the most "realistic" type of test anyway with a *real* client bundle.
|
||||||
|
*
|
||||||
|
* IMPORTANT: There are a few maintenance points that need addressed for new versions of Hibernate and library upgrades:
|
||||||
|
* 1.) Updated library versions in hibernate-osgi.gradle and src/test/resources/felix-framework.properties. Some
|
||||||
|
* of this may be automatable with Gradle scripts.
|
||||||
|
* 2.) If a new version of Felix is used, download and start it manually in the command line. Run
|
||||||
|
* "felix:headers 0" to obtain the list of packages exported and used by the framework. As of this writing,
|
||||||
|
* the framework has javax.transaction.* and javax.xml.stream.* in "uses" attributes. I had to remove all instances
|
||||||
|
* of those packages in the "uses" to correct dependency conflicts that are fairly well documented in the community.
|
||||||
|
* "org.osgi.framework.BundleException: Uses constraint violation..." occurs when a specific version of a package is exported
|
||||||
|
* by a bundle (ex: our JPA 2.1), the same package is exported by another bundle (without a version), and the package appears in a
|
||||||
|
* "uses" attribute (without a version). Rather than do something hacky in the hibernate-osgi manifest itself,
|
||||||
|
* src/test/resources/felix-framework.properties contains the entire list as a property ("org.osgi.framework.system.packages"),
|
||||||
|
* stripped of the javax.transaction nonsense. This may need to be repeated if Felix is ever updated in ORM
|
||||||
|
* (should be rare).
|
||||||
|
*
|
||||||
|
* This should largerly be considered an integration test, rather than a granular unit test. Depending on how you setup
|
||||||
|
* the source directories and classpaths, this may not work in your IDE.
|
||||||
|
*
|
||||||
|
* @author Brett Meyer
|
||||||
|
*/
|
||||||
|
@RunWith(Arquillian.class)
|
||||||
|
public class OsgiTestCase {
|
||||||
|
|
||||||
|
@ArquillianResource
|
||||||
|
BundleContext context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up the Arquillian "deployment", creating a bundle with this test class and the framework.
|
||||||
|
*
|
||||||
|
* @return JavaArchive
|
||||||
|
*/
|
||||||
|
@Deployment
|
||||||
|
public static JavaArchive deployment() {
|
||||||
|
final JavaArchive archive = ShrinkWrap.create( JavaArchive.class, "hibernate-osgi-test" );
|
||||||
|
|
||||||
|
archive.setManifest( new Asset() {
|
||||||
|
@Override
|
||||||
|
public InputStream openStream() {
|
||||||
|
final OSGiManifestBuilder builder = OSGiManifestBuilder.newInstance();
|
||||||
|
builder.addBundleSymbolicName( archive.getName() );
|
||||||
|
builder.addBundleManifestVersion( 2 );
|
||||||
|
builder.addImportPackages( OsgiTestResults.class );
|
||||||
|
return builder.openStream();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
return archive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the persistence unit bundle.
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testClientBundle() throws Exception {
|
||||||
|
assertNotNull( "BundleContext injected", context );
|
||||||
|
assertEquals( "System Bundle ID", 0, context.getBundle().getBundleId() );
|
||||||
|
|
||||||
|
testHibernateBundle( "org.hibernate.core" );
|
||||||
|
testHibernateBundle( "org.hibernate.entitymanager" );
|
||||||
|
|
||||||
|
final Bundle testClientBundle = findHibernateBundle( "testClientBundle" );
|
||||||
|
assertNotNull( "The test client bundle was not found!", testClientBundle );
|
||||||
|
testClientBundle.start();
|
||||||
|
assertEquals( "The test client bundle was not activated!", Bundle.ACTIVE, testClientBundle.getState() );
|
||||||
|
|
||||||
|
final ServiceReference serviceReference = context.getServiceReference( OsgiTestResults.class.getName() );
|
||||||
|
final OsgiTestResults testResults = (OsgiTestResults) context.getService( serviceReference );
|
||||||
|
|
||||||
|
if ( testResults.getFailures().size() > 0 ) {
|
||||||
|
fail( testResults.getFailures().get( 0 ).getFailure() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bundle findHibernateBundle(String symbolicName) {
|
||||||
|
for ( Bundle bundle : context.getBundles() ) {
|
||||||
|
if ( bundle.getSymbolicName().equals( symbolicName ) ) {
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testHibernateBundle(String symbolicName) {
|
||||||
|
final Bundle bundle = findHibernateBundle( symbolicName );
|
||||||
|
|
||||||
|
assertNotNull( "Bundle " + symbolicName + " was not found!", bundle );
|
||||||
|
assertEquals( "Bundle " + symbolicName + " was not activated!", Bundle.ACTIVE, bundle.getState() );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<arquillian xmlns="http://jboss.org/schema/arquillian" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
|
||||||
|
|
||||||
|
<container qualifier="jboss" default="true">
|
||||||
|
<configuration>
|
||||||
|
<property name="frameworkProperties">src/test/resources/felix-framework.properties</property>
|
||||||
|
</configuration>
|
||||||
|
</container>
|
||||||
|
</arquillian>
|
Binary file not shown.
|
@ -0,0 +1,4 @@
|
||||||
|
Bundle-SymbolicName: cdi-api
|
||||||
|
Bundle-Version: 1.1
|
||||||
|
Include-Resource: @../cdi-api-1.1-PFD.jar
|
||||||
|
-exportcontents: *
|
|
@ -0,0 +1,5 @@
|
||||||
|
Bundle-SymbolicName: el-api
|
||||||
|
Bundle-Version: 2.2
|
||||||
|
|
||||||
|
Include-Resource: @../el-api-2.2.jar
|
||||||
|
-exportcontents: *
|
|
@ -0,0 +1,5 @@
|
||||||
|
Bundle-SymbolicName: jandex
|
||||||
|
Bundle-Version: 1.1.0
|
||||||
|
|
||||||
|
Include-Resource: @../jandex-1.1.0.Alpha1.jar
|
||||||
|
-exportcontents: *
|
|
@ -0,0 +1,6 @@
|
||||||
|
Bundle-SymbolicName: javassist
|
||||||
|
Bundle-Version: 3.18.0
|
||||||
|
|
||||||
|
Include-Resource: @../javassist-3.18.0-GA.jar
|
||||||
|
Import-Package: com.sun.jdi;resolution:=optional,com.sun.jdi.connect;resolution:=optional,com.sun.jdi.event;resolution:=optional,com.sun.jdi.request;resolution:=optional
|
||||||
|
-exportcontents: javassist,javassist.bytecode,javassist.bytecode.analysis,javassist.bytecode.annotation,javassist.bytecode.stackmap,javassist.compiler,javassist.compiler.ast,javassist.convert,javassist.expr,javassist.runtime,javassist.scopedpool,javassist.tools,javassist.tools.reflect,javassist.tools.rmi,javassist.tools.web,javassist.util,javassist.util.proxy
|
|
@ -0,0 +1,5 @@
|
||||||
|
Bundle-SymbolicName: serp
|
||||||
|
Bundle-Version: 1.14.1
|
||||||
|
|
||||||
|
Include-Resource: @../serp-1.14.1.jar
|
||||||
|
-exportcontents: *
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,55 @@
|
||||||
|
#
|
||||||
|
# JBoss, Home of Professional Open Source.
|
||||||
|
# Copyright 2010, Red Hat, Inc., and individual contributors
|
||||||
|
# as indicated by the @author tags. See the copyright.txt file in the
|
||||||
|
# distribution for a full listing of individual contributors.
|
||||||
|
#
|
||||||
|
# This is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU Lesser General Public License as
|
||||||
|
# published by the Free Software Foundation; either version 2.1 of
|
||||||
|
# the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This software 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 software; if not, write to the Free
|
||||||
|
# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
# 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Additional logger names to configure (root logger is always configured)
|
||||||
|
loggers=org.jboss.modules,org.jboss.osgi.resolver
|
||||||
|
#logger.org.jboss.shrinkwrap.level=TRACE
|
||||||
|
logger.org.jboss.osgi.resolver.level=TRACE
|
||||||
|
logger.org.jboss.modules.level=TRACE
|
||||||
|
|
||||||
|
# Root logger level
|
||||||
|
logger.level=TRACE
|
||||||
|
|
||||||
|
# Root logger handlers
|
||||||
|
logger.handlers=FILE
|
||||||
|
#logger.handlers=FILE,CONSOLE
|
||||||
|
|
||||||
|
# Console handler configuration
|
||||||
|
handler.CONSOLE=org.jboss.logmanager.handlers.ConsoleHandler
|
||||||
|
handler.CONSOLE.properties=autoFlush
|
||||||
|
handler.CONSOLE.level=TRACE
|
||||||
|
handler.CONSOLE.autoFlush=true
|
||||||
|
handler.CONSOLE.formatter=PATTERN
|
||||||
|
|
||||||
|
|
||||||
|
# Console handler configuration
|
||||||
|
handler.FILE=org.jboss.logmanager.handlers.FileHandler
|
||||||
|
handler.FILE.properties=autoFlush,fileName
|
||||||
|
handler.FILE.level=TRACE
|
||||||
|
handler.FILE.autoFlush=true
|
||||||
|
handler.FILE.fileName=./target/test.log
|
||||||
|
handler.FILE.formatter=PATTERN
|
||||||
|
|
||||||
|
# Formatter pattern configuration
|
||||||
|
formatter.PATTERN=org.jboss.logmanager.formatters.PatternFormatter
|
||||||
|
formatter.PATTERN.properties=pattern
|
||||||
|
formatter.PATTERN.pattern=%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* 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.test.client;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entity
|
||||||
|
*
|
||||||
|
* @author Brett Meyer
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
public class DataPoint {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,192 @@
|
||||||
|
/*
|
||||||
|
* 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.test.client;
|
||||||
|
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.spi.PersistenceProvider;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.osgi.test.result.OsgiTestResults;
|
||||||
|
import org.hibernate.osgi.test.result.OsgiTestResultsImpl;
|
||||||
|
import org.osgi.framework.BundleActivator;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
import org.osgi.framework.ServiceReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a BundleActivate for the testClientBundle, but realistically it's the actual unit test. See the note on
|
||||||
|
* OsgiTestCase.
|
||||||
|
*
|
||||||
|
* @author Brett Meyer
|
||||||
|
*/
|
||||||
|
public class OsgiTestActivator implements BundleActivator {
|
||||||
|
|
||||||
|
private OsgiTestResults testResult = new OsgiTestResultsImpl();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(BundleContext context) throws Exception {
|
||||||
|
|
||||||
|
context.registerService( OsgiTestResults.class, testResult, new Hashtable() );
|
||||||
|
|
||||||
|
testUnmanagedJpa( context );
|
||||||
|
testUnmanagedNative( context );
|
||||||
|
testLazyLoading( context );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop(BundleContext context) throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testUnmanagedJpa(BundleContext context) {
|
||||||
|
try {
|
||||||
|
final ServiceReference serviceReference = context.getServiceReference( PersistenceProvider.class.getName() );
|
||||||
|
final PersistenceProvider persistenceProvider = (PersistenceProvider) context.getService( serviceReference );
|
||||||
|
final EntityManagerFactory emf = persistenceProvider.createEntityManagerFactory( "hibernate-osgi-test", null );
|
||||||
|
final EntityManager em = emf.createEntityManager();
|
||||||
|
|
||||||
|
DataPoint dp = new DataPoint();
|
||||||
|
dp.setName( "Brett" );
|
||||||
|
em.getTransaction().begin();
|
||||||
|
em.persist( dp );
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.clear();
|
||||||
|
|
||||||
|
em.getTransaction().begin();
|
||||||
|
List<DataPoint> results = em.createQuery( "from DataPoint" ).getResultList();
|
||||||
|
if ( results.size() == 0 || !results.get( 0 ).getName().equals( "Brett" ) ) {
|
||||||
|
testResult.addFailure( "Unmanaged JPA: Unexpected data returned!" );
|
||||||
|
}
|
||||||
|
dp = results.get( 0 );
|
||||||
|
dp.setName( "Brett2" );
|
||||||
|
em.merge( dp );
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.clear();
|
||||||
|
|
||||||
|
em.getTransaction().begin();
|
||||||
|
results = em.createQuery( "from DataPoint" ).getResultList();
|
||||||
|
if ( results.size() == 0 || !results.get( 0 ).getName().equals( "Brett2" ) ) {
|
||||||
|
testResult.addFailure( "Unmanaged JPA: The update/merge failed!" );
|
||||||
|
}
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.clear();
|
||||||
|
|
||||||
|
em.getTransaction().begin();
|
||||||
|
em.createQuery( "delete from DataPoint" ).executeUpdate();
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.clear();
|
||||||
|
|
||||||
|
em.getTransaction().begin();
|
||||||
|
results = em.createQuery( "from DataPoint" ).getResultList();
|
||||||
|
if ( results.size() > 0 ) {
|
||||||
|
testResult.addFailure( "Unmanaged JPA: The delete failed!" );
|
||||||
|
}
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
catch ( Exception e ) {
|
||||||
|
testResult.addFailure( "Exception: " + e.getMessage(), e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testUnmanagedNative(BundleContext context) {
|
||||||
|
try {
|
||||||
|
final ServiceReference sr = context.getServiceReference( SessionFactory.class.getName() );
|
||||||
|
final SessionFactory sf = (SessionFactory) context.getService( sr );
|
||||||
|
final Session s = sf.openSession();
|
||||||
|
|
||||||
|
DataPoint dp = new DataPoint();
|
||||||
|
dp.setName( "Brett" );
|
||||||
|
s.getTransaction().begin();
|
||||||
|
s.persist( dp );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.clear();
|
||||||
|
|
||||||
|
s.getTransaction().begin();
|
||||||
|
List<DataPoint> results = s.createQuery( "from DataPoint" ).list();
|
||||||
|
if ( results.size() == 0 || !results.get( 0 ).getName().equals( "Brett" ) ) {
|
||||||
|
testResult.addFailure( "Native Hibernate: Unexpected data returned!" );
|
||||||
|
}
|
||||||
|
dp = results.get( 0 );
|
||||||
|
dp.setName( "Brett2" );
|
||||||
|
s.update( dp );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.clear();
|
||||||
|
|
||||||
|
s.getTransaction().begin();
|
||||||
|
results = s.createQuery( "from DataPoint" ).list();
|
||||||
|
if ( results.size() == 0 || !results.get( 0 ).getName().equals( "Brett2" ) ) {
|
||||||
|
testResult.addFailure( "Native Hibernate: The update/merge failed!" );
|
||||||
|
}
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.clear();
|
||||||
|
|
||||||
|
s.getTransaction().begin();
|
||||||
|
s.createQuery( "delete from DataPoint" ).executeUpdate();
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.clear();
|
||||||
|
|
||||||
|
s.getTransaction().begin();
|
||||||
|
results = s.createQuery( "from DataPoint" ).list();
|
||||||
|
if ( results.size() > 0 ) {
|
||||||
|
testResult.addFailure( "Native Hibernate: The delete failed!" );
|
||||||
|
}
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
catch ( Exception e ) {
|
||||||
|
testResult.addFailure( "Exception: " + e.getMessage(), e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testLazyLoading(BundleContext context) {
|
||||||
|
try {
|
||||||
|
final ServiceReference sr = context.getServiceReference( SessionFactory.class.getName() );
|
||||||
|
final SessionFactory sf = (SessionFactory) context.getService( sr );
|
||||||
|
final Session s = sf.openSession();
|
||||||
|
|
||||||
|
DataPoint dp = new DataPoint();
|
||||||
|
dp.setName( "Brett" );
|
||||||
|
s.getTransaction().begin();
|
||||||
|
s.persist( dp );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.clear();
|
||||||
|
|
||||||
|
s.getTransaction().begin();
|
||||||
|
// ensure the proxy comes through ok
|
||||||
|
dp = (DataPoint) s.load( DataPoint.class, new Long( dp.getId() ) );
|
||||||
|
// initialize and test
|
||||||
|
if ( dp == null || !dp.getName().equals( "Brett" ) ) {
|
||||||
|
testResult.addFailure( "Native Hibernate: Lazy loading/proxy failed!" );
|
||||||
|
}
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
catch ( Exception e ) {
|
||||||
|
testResult.addFailure( "Exception: " + e.getMessage(), e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
version="1.0">
|
||||||
|
<persistence-unit name="hibernate-osgi-test">
|
||||||
|
<class>org.hibernate.osgi.test.client.DataPoint</class>
|
||||||
|
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||||
|
<properties>
|
||||||
|
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
|
||||||
|
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
|
||||||
|
<property name="hibernate.connection.url" value="jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE"/>
|
||||||
|
<property name="hibernate.connection.username" value="sa"/>
|
||||||
|
<property name="hibernate.connection.password" value=""/>
|
||||||
|
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
||||||
|
|
||||||
|
<property name="hibernate.cache.use_second_level_cache" value="false"/>
|
||||||
|
|
||||||
|
<property name="hibernate.archive.autodetection" value=""/>
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
</persistence>
|
|
@ -0,0 +1,16 @@
|
||||||
|
<!DOCTYPE hibernate-configuration PUBLIC
|
||||||
|
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
|
||||||
|
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
|
||||||
|
|
||||||
|
<hibernate-configuration>
|
||||||
|
<session-factory>
|
||||||
|
<property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
|
||||||
|
<property name="hibernate.connection.driver_class">org.h2.Driver</property>
|
||||||
|
<property name="hibernate.connection.username">sa</property>
|
||||||
|
<property name="hibernate.connection.password"></property>
|
||||||
|
<property name="hibernate.connection.url">jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE</property>
|
||||||
|
<property name="hibernate.hbm2ddl.auto">create-drop</property>
|
||||||
|
<property name="hibernate.cache.use_second_level_cache">false</property>
|
||||||
|
<mapping class="org.hibernate.osgi.test.client.DataPoint"/>
|
||||||
|
</session-factory>
|
||||||
|
</hibernate-configuration>
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* 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.test.result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brett Meyer
|
||||||
|
*/
|
||||||
|
public class OsgiTestFailure {
|
||||||
|
|
||||||
|
private String failure;
|
||||||
|
|
||||||
|
private Throwable cause;
|
||||||
|
|
||||||
|
public OsgiTestFailure( String failure ) {
|
||||||
|
this.failure = failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OsgiTestFailure( String failure, Throwable cause ) {
|
||||||
|
this( failure );
|
||||||
|
this.cause = cause;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFailure() {
|
||||||
|
return failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFailure(String failure) {
|
||||||
|
this.failure = failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Throwable getCause() {
|
||||||
|
return cause;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCause(Throwable cause) {
|
||||||
|
this.cause = cause;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* 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.test.result;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines an OSGi service to provide test results to the main test class, without mucking up the classpath
|
||||||
|
* and causing ClassLoader issues.
|
||||||
|
*
|
||||||
|
* @author Brett Meyer
|
||||||
|
*/
|
||||||
|
public interface OsgiTestResults {
|
||||||
|
|
||||||
|
public void addFailure(String failure);
|
||||||
|
|
||||||
|
public void addFailure(String failure, Throwable cause);
|
||||||
|
|
||||||
|
public List<OsgiTestFailure> getFailures();
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* 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.test.result;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of the OsgiTestResult OSGi service.
|
||||||
|
*
|
||||||
|
* @author Brett Meyer
|
||||||
|
*/
|
||||||
|
public class OsgiTestResultsImpl implements OsgiTestResults {
|
||||||
|
|
||||||
|
private List<OsgiTestFailure> failures = new ArrayList<OsgiTestFailure>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addFailure(String failure) {
|
||||||
|
failures.add( new OsgiTestFailure( failure ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addFailure(String failure, Throwable cause) {
|
||||||
|
failures.add( new OsgiTestFailure( failure, cause) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<OsgiTestFailure> getFailures() {
|
||||||
|
return failures;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue