HHH-7996 arquillian-based OSGi unit test, minor CL fixes

This commit is contained in:
Brett Meyer 2013-06-12 16:50:06 -04:00
parent 17d9a2c1fc
commit 58622f3e10
27 changed files with 886 additions and 85 deletions

View File

@ -51,7 +51,7 @@ jar {
manifest {
instruction 'Bundle-Description', 'Hibernate ORM Core'
instruction 'Import-Package',
instructionFirst 'Import-Package',
'javax.security.auth;resolution:=optional',
'javax.security.jacc;resolution:=optional',
'javax.validation;resolution:=optional',

View File

@ -77,7 +77,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
public ClassLoaderServiceImpl(Collection<ClassLoader> providedClassLoaders) {
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 ) {
for ( ClassLoader classLoader : providedClassLoaders ) {
if ( classLoader != null ) {
@ -87,8 +87,9 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
}
// normalize adding known class-loaders...
// first, the Hibernate class loader
// then the Hibernate class loader
orderedClassLoaderSet.add( ClassLoaderServiceImpl.class.getClassLoader() );
// then the TCCL, if one...
final ClassLoader tccl = locateTCCL();
if ( tccl != null ) {

View File

@ -23,6 +23,11 @@
*/
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.FileNotFoundException;
import java.io.IOException;
@ -33,37 +38,32 @@ import java.sql.SQLWarning;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Set;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.transaction.Synchronization;
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.LockMode;
import org.hibernate.cache.CacheException;
import org.hibernate.dialect.Dialect;
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.EntityLoadContext;
import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.engine.spi.SessionFactoryImplementor;
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.SerializationException;
import org.hibernate.type.Type;
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 org.jboss.logging.BasicLogger;
import org.jboss.logging.Cause;
import org.jboss.logging.LogMessage;
import org.jboss.logging.Message;
import org.jboss.logging.MessageLogger;
/**
* 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)
@Message( value = "'javax.persistence.validation.mode' named multiple values : %s", id = 448 )
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);
}

View File

@ -75,6 +75,10 @@ public class HibernatePersistenceProvider implements PersistenceProvider {
}
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 );
final Map integration = wrap( properties );
@ -118,7 +122,7 @@ public class HibernatePersistenceProvider implements PersistenceProvider {
continue;
}
return Bootstrap.getEntityManagerFactoryBuilder( persistenceUnit, integration );
return Bootstrap.getEntityManagerFactoryBuilder( persistenceUnit, integration, providedClassLoader );
}
log.debug( "Found no matching persistence units" );

View File

@ -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 {
compile( project( ':hibernate-core' ) )
compile( 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
compile( "org.osgi:org.osgi.core:4.3.1" )
compile( project( ':hibernate-core' ) )
compile( 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
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() {
return 'Hibernate OSGi Support'
return 'Hibernate OSGi Support'
}
def pomDescription() {
return 'Support for running Hibernate O/RM in OSGi environments'
return 'Support for running Hibernate O/RM in OSGi environments'
}
jar {
manifest {
instruction 'Bundle-Activator', 'org.hibernate.osgi.HibernateBundleActivator'
instruction 'Bundle-Description', 'Hibernate ORM OSGi'
manifest {
instruction 'Bundle-Activator', 'org.hibernate.osgi.HibernateBundleActivator'
instruction 'Bundle-Description', 'Hibernate ORM OSGi'
instruction 'Import-Package',
// TODO: Shouldn't have to explicitly list this, but the plugin
// generates it with a [1.0,2) version.
'javax.persistence;version="2.1.0"',
'javax.persistence.spi;version="2.1.0"'
}
instruction 'Import-Package',
// TODO: Shouldn't have to explicitly list this, but the plugin
// generates it with a [1.0,2) version.
'javax.persistence;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

View File

@ -26,7 +26,6 @@ import java.util.Collection;
import javax.persistence.PersistenceException;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.jpa.boot.archive.spi.ArchiveContext;
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptor;
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry;
@ -43,10 +42,7 @@ import org.osgi.framework.wiring.BundleWiring;
* @author Tim Ward
*/
public class OsgiArchiveDescriptor implements ArchiveDescriptor {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
OsgiArchiveDescriptor.class.getName()
);
private static final Logger LOG = Logger.getLogger( OsgiArchiveDescriptor.class );
private final Bundle persistenceBundle;
private final BundleWiring bundleWiring;
@ -119,7 +115,7 @@ public class OsgiArchiveDescriptor implements ArchiveDescriptor {
context.obtainArchiveEntryHandler( entry ).handleEntry( entry, context );
}
catch ( Exception e ) {
LOG.unableToLoadScannedClassOrResource( e );
LOG.warn( "Exception while loading a class or resource found during scanning", e );
}
}
}

View File

@ -52,40 +52,45 @@ public class OsgiClassLoader extends ClassLoader {
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
* classes were found? Naming collisions can and do happen in OSGi...
*/
@Override
@SuppressWarnings("rawtypes")
protected Class<?> findClass(String name) throws ClassNotFoundException {
if ( classCache.containsKey( name ) ) {
return classCache.get( name );
}
for ( Bundle bundle : bundles ) {
try {
final Class clazz = bundle.loadClass( name );
if ( clazz != null ) {
classCache.put( name, clazz );
return clazz;
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
if ( classCache.containsKey( name ) ) {
return classCache.get( name );
}
for ( Bundle bundle : bundles ) {
try {
final Class clazz = bundle.loadClass( name );
if ( clazz != null ) {
classCache.put( name, clazz );
return clazz;
}
}
catch ( Exception ignore ) {
}
}
catch ( Exception ignore ) {
}
}
for ( ClassLoader classLoader : classLoaders ) {
try {
final Class clazz = classLoader.loadClass( name );
if ( clazz != null ) {
classCache.put( name, clazz );
return clazz;
for ( ClassLoader classLoader : classLoaders ) {
try {
final Class clazz = classLoader.loadClass( name );
if ( clazz != null ) {
classCache.put( name, clazz );
return clazz;
}
}
catch ( Exception ignore ) {
}
}
catch ( Exception ignore ) {
}
}
}
throw new ClassNotFoundException( "Could not load requested class : " + name );
}

View File

@ -35,6 +35,8 @@ import org.hibernate.cfg.AvailableSettings;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.jpa.HibernatePersistenceProvider;
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.StrategyRegistrationProviderList;
import org.hibernate.jpa.boot.spi.TypeContributorList;
@ -90,7 +92,8 @@ public class OsgiPersistenceProvider extends HibernatePersistenceProvider {
osgiClassLoader.addBundle( requestingBundle );
return super.createEntityManagerFactory( persistenceUnitName, settings );
final EntityManagerFactoryBuilder builder = getEntityManagerFactoryBuilderOrNull( persistenceUnitName, settings, osgiClassLoader );
return builder == null ? null : builder.build();
}
@Override
@ -106,7 +109,7 @@ public class OsgiPersistenceProvider extends HibernatePersistenceProvider {
osgiClassLoader.addClassLoader( info.getClassLoader() );
return super.createContainerEntityManagerFactory( info, settings );
return Bootstrap.getEntityManagerFactoryBuilder( info, settings, osgiClassLoader ).build();
}
@SuppressWarnings("unchecked")
@ -138,7 +141,7 @@ public class OsgiPersistenceProvider extends HibernatePersistenceProvider {
settings.put( EntityManagerFactoryBuilderImpl.STRATEGY_REGISTRATION_PROVIDERS, strategyRegistrationProviderList );
final List<TypeContributor> typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context );
TypeContributorList typeContributorList = new TypeContributorList() {
final TypeContributorList typeContributorList = new TypeContributorList() {
@Override
public List<TypeContributor> getTypeContributors() {
return typeContributors;

View File

@ -24,7 +24,6 @@ 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;
@ -35,10 +34,7 @@ import org.osgi.framework.ServiceReference;
* @author Brett Meyer
*/
public class OsgiServiceUtil {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
OsgiServiceUtil.class.getName()
);
private static final Logger LOG = Logger.getLogger( OsgiServiceUtil.class );
/**
* Locate all implementors of the given service contract in the given OSGi buindle context
@ -58,7 +54,7 @@ public class OsgiServiceUtil {
}
}
catch ( Exception e ) {
LOG.unableToDiscoverOsgiService( contract.getName(), e );
LOG.warnf( e, "Exception while discovering OSGi service implementations : %s", contract.getName() );
}
return serviceImpls;
}

View File

@ -97,10 +97,10 @@ public class OsgiSessionFactoryService implements ServiceFactory {
builder.withStrategySelectors( strategyRegistrationProvider );
}
final List<TypeContributor> typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context );
for (TypeContributor typeContributor : typeContributors) {
configuration.registerTypeContributor( typeContributor );
}
final List<TypeContributor> typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context );
for ( TypeContributor typeContributor : typeContributors ) {
configuration.registerTypeContributor( typeContributor );
}
final ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder( builder.build() )
.applySettings( configuration.getProperties() ).build();

View File

@ -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() );
}
}

View File

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

View File

@ -0,0 +1,4 @@
Bundle-SymbolicName: cdi-api
Bundle-Version: 1.1
Include-Resource: @../cdi-api-1.1-PFD.jar
-exportcontents: *

View File

@ -0,0 +1,5 @@
Bundle-SymbolicName: el-api
Bundle-Version: 2.2
Include-Resource: @../el-api-2.2.jar
-exportcontents: *

View File

@ -0,0 +1,5 @@
Bundle-SymbolicName: jandex
Bundle-Version: 1.1.0
Include-Resource: @../jandex-1.1.0.Alpha1.jar
-exportcontents: *

View File

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

View File

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

View File

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

View File

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

View File

@ -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 );
}
}
}

View File

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

View File

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

View File

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

View File

@ -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();
}

View File

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