diff --git a/hibernate-core/hibernate-core.gradle b/hibernate-core/hibernate-core.gradle index af0679f456..aa07a6ccb7 100644 --- a/hibernate-core/hibernate-core.gradle +++ b/hibernate-core/hibernate-core.gradle @@ -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', diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/ClassLoaderServiceImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/ClassLoaderServiceImpl.java index 7e7c4ada58..e6ae31a509 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/ClassLoaderServiceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/ClassLoaderServiceImpl.java @@ -77,7 +77,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService { public ClassLoaderServiceImpl(Collection providedClassLoaders) { final LinkedHashSet orderedClassLoaderSet = new LinkedHashSet(); - // 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 ) { diff --git a/hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java b/hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java index f2026995c4..373d6acda9 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java @@ -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); } diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/HibernatePersistenceProvider.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/HibernatePersistenceProvider.java index 2226d6555c..fcb40d2b12 100755 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/HibernatePersistenceProvider.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/HibernatePersistenceProvider.java @@ -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" ); diff --git a/hibernate-osgi/hibernate-osgi.gradle b/hibernate-osgi/hibernate-osgi.gradle index cefe0b6449..5a364a186c 100644 --- a/hibernate-osgi/hibernate-osgi.gradle +++ b/hibernate-osgi/hibernate-osgi.gradle @@ -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 diff --git a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiArchiveDescriptor.java b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiArchiveDescriptor.java index fc554e4216..a40a0d8769 100644 --- a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiArchiveDescriptor.java +++ b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiArchiveDescriptor.java @@ -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 ); } } } diff --git a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiClassLoader.java b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiClassLoader.java index a748770e2c..555aa327be 100644 --- a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiClassLoader.java +++ b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiClassLoader.java @@ -52,40 +52,45 @@ public class OsgiClassLoader extends ClassLoader { private Map resourceCache = new HashMap(); /** - * 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 ); } diff --git a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiPersistenceProvider.java b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiPersistenceProvider.java index afb8503e06..85f81b4142 100644 --- a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiPersistenceProvider.java +++ b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiPersistenceProvider.java @@ -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 typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context ); - TypeContributorList typeContributorList = new TypeContributorList() { + final TypeContributorList typeContributorList = new TypeContributorList() { @Override public List getTypeContributors() { return typeContributors; diff --git a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiServiceUtil.java b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiServiceUtil.java index 05e4603d92..758e06550d 100644 --- a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiServiceUtil.java +++ b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiServiceUtil.java @@ -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; } diff --git a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiSessionFactoryService.java b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiSessionFactoryService.java index 71b45387c9..10777cb96e 100644 --- a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiSessionFactoryService.java +++ b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiSessionFactoryService.java @@ -97,10 +97,10 @@ public class OsgiSessionFactoryService implements ServiceFactory { builder.withStrategySelectors( strategyRegistrationProvider ); } - final List typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context ); - for (TypeContributor typeContributor : typeContributors) { - configuration.registerTypeContributor( typeContributor ); - } + final List typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context ); + for ( TypeContributor typeContributor : typeContributors ) { + configuration.registerTypeContributor( typeContributor ); + } final ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder( builder.build() ) .applySettings( configuration.getProperties() ).build(); diff --git a/hibernate-osgi/src/test/java/org/hibernate/osgi/test/OsgiTestCase.java b/hibernate-osgi/src/test/java/org/hibernate/osgi/test/OsgiTestCase.java new file mode 100644 index 0000000000..659f664d7c --- /dev/null +++ b/hibernate-osgi/src/test/java/org/hibernate/osgi/test/OsgiTestCase.java @@ -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() ); + } +} diff --git a/hibernate-osgi/src/test/resources/arquillian.xml b/hibernate-osgi/src/test/resources/arquillian.xml new file mode 100644 index 0000000000..dbc7bb461a --- /dev/null +++ b/hibernate-osgi/src/test/resources/arquillian.xml @@ -0,0 +1,10 @@ + + + + + + src/test/resources/felix-framework.properties + + + diff --git a/hibernate-osgi/src/test/resources/bnd/bnd.jar b/hibernate-osgi/src/test/resources/bnd/bnd.jar new file mode 100644 index 0000000000..ea6cb03e70 Binary files /dev/null and b/hibernate-osgi/src/test/resources/bnd/bnd.jar differ diff --git a/hibernate-osgi/src/test/resources/bnd/cdi-api.bnd b/hibernate-osgi/src/test/resources/bnd/cdi-api.bnd new file mode 100644 index 0000000000..63b4aa3e8b --- /dev/null +++ b/hibernate-osgi/src/test/resources/bnd/cdi-api.bnd @@ -0,0 +1,4 @@ +Bundle-SymbolicName: cdi-api +Bundle-Version: 1.1 +Include-Resource: @../cdi-api-1.1-PFD.jar +-exportcontents: * diff --git a/hibernate-osgi/src/test/resources/bnd/el-api.bnd b/hibernate-osgi/src/test/resources/bnd/el-api.bnd new file mode 100644 index 0000000000..f260382311 --- /dev/null +++ b/hibernate-osgi/src/test/resources/bnd/el-api.bnd @@ -0,0 +1,5 @@ + Bundle-SymbolicName: el-api + Bundle-Version: 2.2 + + Include-Resource: @../el-api-2.2.jar +-exportcontents: * diff --git a/hibernate-osgi/src/test/resources/bnd/jandex.bnd b/hibernate-osgi/src/test/resources/bnd/jandex.bnd new file mode 100644 index 0000000000..30be9a213f --- /dev/null +++ b/hibernate-osgi/src/test/resources/bnd/jandex.bnd @@ -0,0 +1,5 @@ + Bundle-SymbolicName: jandex + Bundle-Version: 1.1.0 + + Include-Resource: @../jandex-1.1.0.Alpha1.jar +-exportcontents: * diff --git a/hibernate-osgi/src/test/resources/bnd/javassist.bnd b/hibernate-osgi/src/test/resources/bnd/javassist.bnd new file mode 100644 index 0000000000..f378b24db8 --- /dev/null +++ b/hibernate-osgi/src/test/resources/bnd/javassist.bnd @@ -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 \ No newline at end of file diff --git a/hibernate-osgi/src/test/resources/bnd/serp.bnd b/hibernate-osgi/src/test/resources/bnd/serp.bnd new file mode 100644 index 0000000000..6f9a410de7 --- /dev/null +++ b/hibernate-osgi/src/test/resources/bnd/serp.bnd @@ -0,0 +1,5 @@ + Bundle-SymbolicName: serp + Bundle-Version: 1.14.1 + + Include-Resource: @../serp-1.14.1.jar +-exportcontents: * diff --git a/hibernate-osgi/src/test/resources/felix-framework.properties b/hibernate-osgi/src/test/resources/felix-framework.properties new file mode 100644 index 0000000000..d99ce8802a --- /dev/null +++ b/hibernate-osgi/src/test/resources/felix-framework.properties @@ -0,0 +1,45 @@ +# +# Properties given to the FrameworkFactory +# + +# Properties to configure the Framework +org.osgi.framework.storage=./target/osgi-store +org.osgi.framework.storage.clean=onFirstInit + +# Extra System Packages +#org.osgi.framework.system.packages.extra=\ + +felix.log.level=4 + +felix.auto.install.1=\ + file:target/osgi-lib/testClientBundle.jar + +felix.auto.start.1=\ + file:target/osgi-lib/arquillian-osgi-bundle-1.0.3.Final.jar \ + file:target/osgi-lib/hibernate-jpa-2.1-api-1.0.0-SNAPSHOT.jar \ + file:target/osgi-lib/bnd/el-api-2.2.0.jar \ + file:target/osgi-lib/bnd/cdi-api-1.1.0.jar \ + file:target/osgi-lib/jboss-interceptors-api_1.2_spec-1.0.0.Alpha1.jar \ + file:target/osgi-lib/jboss-transaction-api_1.2_spec-1.0.0.Alpha1.jar \ + file:target/osgi-lib/commons-collections-3.2.1.jar \ + file:target/osgi-lib/commons-pool-1.6.jar \ + file:target/osgi-lib/commons-dbcp-1.4.jar \ + file:target/osgi-lib/commons-lang-2.6.jar \ + file:target/osgi-lib/bnd/serp-1.14.1.jar \ + file:target/osgi-lib/h2-1.3.170.jar \ + file:target/osgi-lib/org.apache.servicemix.bundles.antlr-2.7.7_5.jar \ + file:target/osgi-lib/bnd/javassist-3.18.0.jar \ + file:target/osgi-lib/org.apache.servicemix.specs.jsr303-api-1.0.0-2.2.0.jar \ + file:target/osgi-lib/org.apache.servicemix.bundles.ant-1.8.2_2.jar \ + file:target/osgi-lib/org.apache.servicemix.specs.stax-api-1.2-2.2.0.jar \ + file:target/osgi-lib/org.apache.servicemix.bundles.dom4j-1.6.1_5.jar \ + file:target/osgi-lib/hibernate-commons-annotations-4.0.2.Final.jar \ + file:target/osgi-lib/bnd/jandex-1.1.0.jar \ + file:target/osgi-lib/classmate-0.8.0.jar \ + file:target/osgi-lib/jboss-logging-3.1.0.GA.jar \ + file:../hibernate-core/target/libs/hibernate-core-4.3.0-SNAPSHOT.jar \ + file:../hibernate-entitymanager/target/libs/hibernate-entitymanager-4.3.0-SNAPSHOT.jar \ + file:target/libs/hibernate-osgi-4.3.0-SNAPSHOT.jar + +# See note on OsgiTestCase. +org.osgi.framework.system.packages=org.osgi.framework; version="1.7.0", org.osgi.framework.hooks.bundle; version="1.1.0", org.osgi.framework.hooks.resolver; version="1.0.0", org.osgi.framework.hooks.service; version="1.1.0", org.osgi.framework.hooks.weaving; version="1.0.0", org.osgi.framework.launch; version="1.1.0", org.osgi.framework.namespace; version="1.0.0", org.osgi.framework.startlevel; version="1.0.0", org.osgi.framework.wiring; version="1.1.0", org.osgi.resource; version="1.0.0", org.osgi.service.packageadmin; version="1.2.0", org.osgi.service.startlevel; version="1.1.0", org.osgi.service.url; version="1.0.0", org.osgi.util.tracker; version="1.5.1", javax.accessibility; uses:="javax.swing.text"; version="0.0.0.1_007_JavaSE", javax.activation; version="0.0.0.1_007_JavaSE", javax.activity; version="0.0.0.1_007_JavaSE", javax.annotation.processing; uses:="javax.tools,javax.lang.model,javax.lang.model.element,javax.lang.model.util"; version="0.0.0.1_007_JavaSE", javax.annotation; version="0.0.0.1_007_JavaSE", javax.crypto.interfaces; uses:="javax.crypto.spec,javax.crypto"; version="0.0.0.1_007_JavaSE", javax.crypto.spec; uses:="javax.crypto"; version="0.0.0.1_007_JavaSE", javax.crypto; uses:="javax.crypto.spec"; version="0.0.0.1_007_JavaSE", javax.imageio.event; uses:="javax.imageio"; version="0.0.0.1_007_JavaSE", javax.imageio.metadata; uses:="org.w3c.dom,javax.imageio"; version="0.0.0.1_007_JavaSE", javax.imageio.plugins.bmp; uses:="javax.imageio"; version="0.0.0.1_007_JavaSE", javax.imageio.plugins.jpeg; uses:="javax.imageio"; version="0.0.0.1_007_JavaSE", javax.imageio.spi; uses:="javax.imageio.stream,javax.imageio,javax.imageio.metadata"; version="0.0.0.1_007_JavaSE", javax.imageio.stream; uses:="javax.imageio"; version="0.0.0.1_007_JavaSE", javax.imageio; uses:="javax.imageio.metadata,javax.imageio.stream,javax.imageio.spi,javax.imageio.event"; version="0.0.0.1_007_JavaSE", javax.jws.soap; version="0.0.0.1_007_JavaSE", javax.jws; version="0.0.0.1_007_JavaSE", javax.lang.model.element; uses:="javax.lang.model.type,javax.lang.model"; version="0.0.0.1_007_JavaSE", javax.lang.model.type; uses:="javax.lang.model.element,javax.lang.model"; version="0.0.0.1_007_JavaSE", javax.lang.model.util; uses:="javax.lang.model,javax.lang.model.element,javax.annotation.processing,javax.lang.model.type"; version="0.0.0.1_007_JavaSE", javax.lang.model; version="0.0.0.1_007_JavaSE", javax.management.loading; uses:="javax.management"; version="0.0.0.1_007_JavaSE", javax.management.modelmbean; uses:="javax.management,javax.management.loading"; version="0.0.0.1_007_JavaSE", javax.management.monitor; uses:="javax.management"; version="0.0.0.1_007_JavaSE", javax.management.openmbean; uses:="javax.management"; version="0.0.0.1_007_JavaSE", javax.management.relation; uses:="javax.management"; version="0.0.0.1_007_JavaSE", javax.management.remote.rmi; uses:="javax.management.remote,javax.security.auth,javax.management,javax.management.loading,javax.naming,javax.rmi.ssl,org.omg.CORBA,org.omg.CORBA_2_3.portable,org.omg.CORBA.portable,javax.rmi.CORBA,javax.rmi"; version="0.0.0.1_007_JavaSE", javax.management.remote; uses:="javax.security.auth,javax.management"; version="0.0.0.1_007_JavaSE", javax.management.timer; uses:="javax.management"; version="0.0.0.1_007_JavaSE", javax.management; uses:="javax.management.loading,javax.management.openmbean"; version="0.0.0.1_007_JavaSE", javax.naming.directory; uses:="javax.naming"; version="0.0.0.1_007_JavaSE", javax.naming.event; uses:="javax.naming,javax.naming.directory"; version="0.0.0.1_007_JavaSE", javax.naming.ldap; uses:="javax.naming,javax.naming.directory,javax.net.ssl,javax.naming.event"; version="0.0.0.1_007_JavaSE", javax.naming.spi; uses:="javax.naming,javax.naming.directory"; version="0.0.0.1_007_JavaSE", javax.naming; uses:="javax.naming.spi"; version="0.0.0.1_007_JavaSE", javax.net.ssl; uses:="javax.security.cert,javax.security.auth.x500,javax.net"; version="0.0.0.1_007_JavaSE", javax.net; version="0.0.0.1_007_JavaSE", javax.print.attribute.standard; uses:="javax.print.attribute"; version="0.0.0.1_007_JavaSE", javax.print.attribute; version="0.0.0.1_007_JavaSE", javax.print.event; uses:="javax.print,javax.print.attribute"; version="0.0.0.1_007_JavaSE", javax.print; uses:="javax.print.attribute,javax.print.event,javax.print.attribute.standard"; version="0.0.0.1_007_JavaSE", javax.rmi.CORBA; uses:="org.omg.CORBA,org.omg.CORBA_2_3.portable,org.omg.CORBA.portable,org.omg.SendingContext"; version="0.0.0.1_007_JavaSE", javax.rmi.ssl; uses:="javax.net,javax.net.ssl"; version="0.0.0.1_007_JavaSE", javax.rmi; uses:="org.omg.CORBA,javax.rmi.CORBA"; version="0.0.0.1_007_JavaSE", javax.script; version="0.0.0.1_007_JavaSE", javax.security.auth.callback; version="0.0.0.1_007_JavaSE", javax.security.auth.kerberos; uses:="javax.security.auth,javax.crypto"; version="0.0.0.1_007_JavaSE", javax.security.auth.login; uses:="javax.security.auth,javax.security.auth.callback"; version="0.0.0.1_007_JavaSE", javax.security.auth.spi; uses:="javax.security.auth.callback,javax.security.auth.login,javax.security.auth"; version="0.0.0.1_007_JavaSE", javax.security.auth.x500; uses:="javax.security.auth"; version="0.0.0.1_007_JavaSE", javax.security.auth; version="0.0.0.1_007_JavaSE", javax.security.cert; version="0.0.0.1_007_JavaSE", javax.security.sasl; uses:="javax.security.auth.callback"; version="0.0.0.1_007_JavaSE", javax.sound.midi.spi; uses:="javax.sound.midi"; version="0.0.0.1_007_JavaSE", javax.sound.midi; uses:="javax.sound.midi.spi"; version="0.0.0.1_007_JavaSE", javax.sound.sampled.spi; uses:="javax.sound.sampled"; version="0.0.0.1_007_JavaSE", javax.sound.sampled; uses:="javax.sound.sampled.spi"; version="0.0.0.1_007_JavaSE", javax.sql.rowset.serial; uses:="javax.sql.rowset"; version="0.0.0.1_007_JavaSE", javax.sql.rowset.spi; uses:="javax.sql,javax.naming,javax.sql.rowset"; version="0.0.0.1_007_JavaSE", javax.sql.rowset; uses:="javax.sql,javax.sql.rowset.serial,javax.sql.rowset.spi"; version="0.0.0.1_007_JavaSE", javax.sql; version="0.0.0.1_007_JavaSE", javax.swing.border; uses:="javax.swing"; version="0.0.0.1_007_JavaSE", javax.swing.colorchooser; uses:="javax.swing,javax.swing.border,javax.swing.event,javax.swing.text"; version="0.0.0.1_007_JavaSE", javax.swing.event; uses:="javax.swing,javax.swing.text,javax.swing.table,javax.swing.tree,javax.swing.undo"; version="0.0.0.1_007_JavaSE", javax.swing.filechooser; uses:="javax.swing"; version="0.0.0.1_007_JavaSE", javax.swing.plaf.basic; uses:="javax.swing.border,javax.swing,javax.swing.plaf,javax.swing.text,javax.swing.event,javax.swing.colorchooser,javax.accessibility,javax.swing.filechooser,javax.swing.text.html,javax.sound.sampled,javax.swing.table,javax.swing.plaf.synth,javax.swing.tree"; version="0.0.0.1_007_JavaSE", javax.swing.plaf.metal; uses:="javax.swing.plaf,javax.swing,javax.swing.border,javax.swing.text,javax.swing.plaf.basic,javax.swing.filechooser,javax.swing.event,javax.swing.tree"; version="0.0.0.1_007_JavaSE", javax.swing.plaf.multi; uses:="javax.accessibility,javax.swing,javax.swing.plaf,javax.swing.filechooser,javax.swing.text,javax.swing.tree"; version="0.0.0.1_007_JavaSE", javax.swing.plaf.nimbus; uses:="javax.swing,javax.swing.plaf,javax.swing.border,javax.swing.plaf.synth"; version="0.0.0.1_007_JavaSE", javax.swing.plaf.synth; uses:="javax.swing,javax.swing.plaf,javax.swing.text,javax.swing.border,javax.swing.plaf.basic,javax.swing.colorchooser,javax.swing.event,javax.xml.parsers,org.xml.sax,org.xml.sax.helpers,javax.swing.table,javax.swing.tree"; version="0.0.0.1_007_JavaSE", javax.swing.plaf; uses:="javax.swing,javax.swing.border,javax.accessibility,javax.swing.filechooser,javax.swing.text,javax.swing.tree"; version="0.0.0.1_007_JavaSE", javax.swing.table; uses:="javax.swing.event,javax.swing.plaf,javax.swing.border,javax.swing,javax.accessibility"; version="0.0.0.1_007_JavaSE", javax.swing.text.html.parser; uses:="javax.swing.text,javax.swing.text.html"; version="0.0.0.1_007_JavaSE", javax.swing.text.html; uses:="javax.swing.event,javax.swing.text,javax.accessibility,javax.swing,javax.swing.plaf,javax.swing.border,javax.swing.undo"; version="0.0.0.1_007_JavaSE", javax.swing.text.rtf; uses:="javax.swing.text"; version="0.0.0.1_007_JavaSE", javax.swing.text; uses:="javax.swing.event,javax.swing.tree,javax.swing.undo,javax.swing,javax.swing.plaf,javax.swing.plaf.basic,javax.print,javax.print.attribute,javax.accessibility,javax.swing.text.html"; version="0.0.0.1_007_JavaSE", javax.swing.tree; uses:="javax.swing.event,javax.swing,javax.swing.border,javax.swing.plaf,javax.swing.plaf.basic"; version="0.0.0.1_007_JavaSE", javax.swing.undo; uses:="javax.swing,javax.swing.event"; version="0.0.0.1_007_JavaSE", javax.swing; uses:="javax.swing.event,javax.accessibility,javax.swing.text,javax.swing.plaf,javax.swing.border,javax.swing.tree,javax.swing.table,javax.swing.colorchooser,javax.swing.plaf.basic,javax.swing.text.html,javax.swing.filechooser,javax.print,javax.print.attribute,javax.swing.plaf.metal"; version="0.0.0.1_007_JavaSE", javax.tools; uses:="javax.lang.model.element,javax.annotation.processing,javax.lang.model"; version="0.0.0.1_007_JavaSE", javax.transaction.xa, javax.transaction, javax.xml.bind.annotation.adapters; uses:="javax.xml.bind"; version="0.0.0.1_007_JavaSE", javax.xml.bind.annotation; uses:="javax.xml.transform,javax.xml.bind,javax.xml.parsers,javax.xml.transform.dom,org.w3c.dom"; version="0.0.0.1_007_JavaSE", javax.xml.bind.attachment; uses:="javax.activation"; version="0.0.0.1_007_JavaSE", javax.xml.bind.helpers; uses:="javax.xml.bind.annotation.adapters,javax.xml.transform.dom,org.w3c.dom,org.xml.sax,javax.xml.bind.attachment,javax.xml.transform,javax.xml.transform.stream,javax.xml.validation,javax.xml.transform.sax,javax.xml.bind,javax.xml.parsers"; version="0.0.0.1_007_JavaSE", javax.xml.bind.util; uses:="javax.xml.transform.sax,javax.xml.bind,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers"; version="0.0.0.1_007_JavaSE", javax.xml.bind; uses:="javax.xml.validation,javax.xml.namespace,javax.xml.datatype,javax.xml.transform,javax.xml.bind.annotation,javax.xml.transform.stream,org.w3c.dom,javax.xml.bind.attachment,javax.xml.bind.annotation.adapters,org.xml.sax"; version="0.0.0.1_007_JavaSE", javax.xml.crypto.dom; uses:="javax.xml.crypto,org.w3c.dom"; version="0.0.0.1_007_JavaSE", javax.xml.crypto.dsig.dom; uses:="javax.xml.crypto.dsig,javax.xml.crypto,org.w3c.dom,javax.xml.crypto.dom"; version="0.0.0.1_007_JavaSE", javax.xml.crypto.dsig.keyinfo; uses:="javax.xml.crypto"; version="0.0.0.1_007_JavaSE", javax.xml.crypto.dsig.spec; uses:="javax.xml.crypto"; version="0.0.0.1_007_JavaSE", javax.xml.crypto.dsig; uses:="javax.xml.crypto,javax.xml.crypto.dsig.spec,javax.xml.crypto.dsig.keyinfo"; version="0.0.0.1_007_JavaSE", javax.xml.crypto; uses:="javax.xml.crypto.dsig.keyinfo"; version="0.0.0.1_007_JavaSE", javax.xml.datatype; uses:="javax.xml.namespace"; version="0.0.0.1_007_JavaSE", javax.xml.namespace; version="0.0.0.1_007_JavaSE", javax.xml.parsers; uses:="javax.xml.validation,org.w3c.dom,org.xml.sax,org.xml.sax.helpers"; version="0.0.0.1_007_JavaSE", javax.xml.soap; uses:="javax.activation,javax.xml.namespace,org.w3c.dom,javax.xml.transform.dom,javax.xml.transform"; version="0.0.0.1_007_JavaSE", javax.xml.stream.events; uses:="javax.xml.namespace"; version="0.0.0.1_007_JavaSE", javax.xml.stream.util; uses:="javax.xml.namespace"; version="0.0.0.1_007_JavaSE", javax.xml.stream; uses:="javax.xml.namespace,javax.xml.transform"; version="0.0.0.1_007_JavaSE", javax.xml.transform.dom; uses:="javax.xml.transform,org.w3c.dom"; version="0.0.0.1_007_JavaSE", javax.xml.transform.sax; uses:="org.xml.sax.ext,javax.xml.transform,org.xml.sax,javax.xml.transform.stream"; version="0.0.0.1_007_JavaSE", javax.xml.transform.stax; uses:="javax.xml.transform"; version="0.0.0.1_007_JavaSE", javax.xml.transform.stream; uses:="javax.xml.transform"; version="0.0.0.1_007_JavaSE", javax.xml.transform; version="0.0.0.1_007_JavaSE", javax.xml.validation; uses:="org.w3c.dom.ls,javax.xml.transform,javax.xml.transform.stream,org.xml.sax,org.w3c.dom"; version="0.0.0.1_007_JavaSE", javax.xml.ws.handler.soap; uses:="javax.xml.ws.handler,javax.xml.namespace,javax.xml.soap,javax.xml.bind"; version="0.0.0.1_007_JavaSE", javax.xml.ws.handler; uses:="javax.xml.ws,javax.xml.namespace"; version="0.0.0.1_007_JavaSE", javax.xml.ws.http; uses:="javax.xml.ws"; version="0.0.0.1_007_JavaSE", javax.xml.ws.soap; uses:="javax.xml.ws.spi,javax.xml.ws,javax.xml.soap"; version="0.0.0.1_007_JavaSE", javax.xml.ws.spi.http; version="0.0.0.1_007_JavaSE", javax.xml.ws.spi; uses:="javax.xml.ws,javax.xml.ws.wsaddressing,javax.xml.transform,org.w3c.dom,javax.xml.namespace,javax.xml.ws.handler,javax.xml.bind"; version="0.0.0.1_007_JavaSE", javax.xml.ws.wsaddressing; uses:="javax.xml.bind.annotation,javax.xml.namespace,org.w3c.dom,javax.xml.transform,javax.xml.bind,javax.xml.ws,javax.xml.ws.spi"; version="0.0.0.1_007_JavaSE", javax.xml.ws; uses:="javax.xml.ws.handler,javax.xml.ws.spi,javax.xml.ws.spi.http,javax.xml.transform,org.w3c.dom,javax.xml.bind.annotation,javax.xml.transform.stream,javax.xml.bind,javax.xml.namespace"; version="0.0.0.1_007_JavaSE", javax.xml.xpath; uses:="org.xml.sax,javax.xml.namespace"; version="0.0.0.1_007_JavaSE", javax.xml; version="0.0.0.1_007_JavaSE", org.ietf.jgss; version="0.0.0.1_007_JavaSE", org.omg.CORBA.DynAnyPackage; uses:="org.omg.CORBA"; version="0.0.0.1_007_JavaSE", org.omg.CORBA.ORBPackage; uses:="org.omg.CORBA"; version="0.0.0.1_007_JavaSE", org.omg.CORBA.TypeCodePackage; uses:="org.omg.CORBA"; version="0.0.0.1_007_JavaSE", org.omg.CORBA.portable; uses:="org.omg.CORBA,org.omg.CORBA_2_3.portable"; version="0.0.0.1_007_JavaSE", org.omg.CORBA; uses:="org.omg.CORBA.portable,org.omg.CORBA.DynAnyPackage,org.omg.CORBA.ORBPackage,org.omg.CORBA_2_3.portable,org.omg.CORBA.TypeCodePackage"; version="0.0.0.1_007_JavaSE", org.omg.CORBA_2_3.portable; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_007_JavaSE", org.omg.CORBA_2_3; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_007_JavaSE", org.omg.CosNaming.NamingContextExtPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_007_JavaSE", org.omg.CosNaming.NamingContextPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.CosNaming"; version="0.0.0.1_007_JavaSE", org.omg.CosNaming; uses:="org.omg.CORBA.portable,org.omg.CORBA,org.omg.PortableServer,org.omg.CosNaming.NamingContextPackage,org.omg.CosNaming.NamingContextExtPackage"; version="0.0.0.1_007_JavaSE", org.omg.Dynamic; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_007_JavaSE", org.omg.DynamicAny.DynAnyFactoryPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_007_JavaSE", org.omg.DynamicAny.DynAnyPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_007_JavaSE", org.omg.DynamicAny; uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.DynamicAny.DynAnyFactoryPackage,org.omg.DynamicAny.DynAnyPackage"; version="0.0.0.1_007_JavaSE", org.omg.IOP.CodecFactoryPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_007_JavaSE", org.omg.IOP.CodecPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_007_JavaSE", org.omg.IOP; uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.IOP.CodecFactoryPackage,org.omg.IOP.CodecPackage"; version="0.0.0.1_007_JavaSE", org.omg.Messaging; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_007_JavaSE", org.omg.PortableInterceptor.ORBInitInfoPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_007_JavaSE", org.omg.PortableInterceptor; uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.IOP,org.omg.PortableInterceptor.ORBInitInfoPackage,org.omg.CORBA_2_3.portable,org.omg.Dynamic"; version="0.0.0.1_007_JavaSE", org.omg.PortableServer.CurrentPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_007_JavaSE", org.omg.PortableServer.POAManagerPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_007_JavaSE", org.omg.PortableServer.POAPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_007_JavaSE", org.omg.PortableServer.ServantLocatorPackage; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_007_JavaSE", org.omg.PortableServer.portable; uses:="org.omg.CORBA,org.omg.PortableServer"; version="0.0.0.1_007_JavaSE", org.omg.PortableServer; uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.PortableServer.CurrentPackage,org.omg.PortableServer.POAManagerPackage,org.omg.PortableServer.POAPackage,org.omg.PortableServer.portable,org.omg.CORBA_2_3,org.omg.PortableServer.ServantLocatorPackage"; version="0.0.0.1_007_JavaSE", org.omg.SendingContext; uses:="org.omg.CORBA,org.omg.CORBA.portable"; version="0.0.0.1_007_JavaSE", org.omg.stub.java.rmi; uses:="javax.rmi.CORBA"; version="0.0.0.1_007_JavaSE", org.w3c.dom.bootstrap; uses:="org.w3c.dom"; version="0.0.0.1_007_JavaSE", org.w3c.dom.events; uses:="org.w3c.dom,org.w3c.dom.views"; version="0.0.0.1_007_JavaSE", org.w3c.dom.ls; uses:="org.w3c.dom,org.w3c.dom.events,org.w3c.dom.traversal"; version="0.0.0.1_007_JavaSE", org.w3c.dom; version="0.0.0.1_007_JavaSE", org.xml.sax.ext; uses:="org.xml.sax,org.xml.sax.helpers"; version="0.0.0.1_007_JavaSE", org.xml.sax.helpers; uses:="org.xml.sax"; version="0.0.0.1_007_JavaSE", org.xml.sax; version="0.0.0.1_007_JavaSE" diff --git a/hibernate-osgi/src/test/resources/logging.properties b/hibernate-osgi/src/test/resources/logging.properties new file mode 100644 index 0000000000..5f74c07f6a --- /dev/null +++ b/hibernate-osgi/src/test/resources/logging.properties @@ -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 diff --git a/hibernate-osgi/src/testClientBundle/java/org/hibernate/osgi/test/client/DataPoint.java b/hibernate-osgi/src/testClientBundle/java/org/hibernate/osgi/test/client/DataPoint.java new file mode 100644 index 0000000000..14f9eb7e77 --- /dev/null +++ b/hibernate-osgi/src/testClientBundle/java/org/hibernate/osgi/test/client/DataPoint.java @@ -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; + } +} diff --git a/hibernate-osgi/src/testClientBundle/java/org/hibernate/osgi/test/client/OsgiTestActivator.java b/hibernate-osgi/src/testClientBundle/java/org/hibernate/osgi/test/client/OsgiTestActivator.java new file mode 100644 index 0000000000..923c581429 --- /dev/null +++ b/hibernate-osgi/src/testClientBundle/java/org/hibernate/osgi/test/client/OsgiTestActivator.java @@ -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 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 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 ); + } + } + +} diff --git a/hibernate-osgi/src/testClientBundle/resources/META-INF/persistence.xml b/hibernate-osgi/src/testClientBundle/resources/META-INF/persistence.xml new file mode 100644 index 0000000000..fdb5232a0e --- /dev/null +++ b/hibernate-osgi/src/testClientBundle/resources/META-INF/persistence.xml @@ -0,0 +1,21 @@ + + + + org.hibernate.osgi.test.client.DataPoint + true + + + + + + + + + + + + + + diff --git a/hibernate-osgi/src/testClientBundle/resources/hibernate.cfg.xml b/hibernate-osgi/src/testClientBundle/resources/hibernate.cfg.xml new file mode 100644 index 0000000000..fb2f5c5f80 --- /dev/null +++ b/hibernate-osgi/src/testClientBundle/resources/hibernate.cfg.xml @@ -0,0 +1,16 @@ + + + + + org.hibernate.dialect.H2Dialect + org.h2.Driver + sa + + jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE + create-drop + false + + + diff --git a/hibernate-osgi/src/testResult/java/org/hibernate/osgi/test/result/OsgiTestFailure.java b/hibernate-osgi/src/testResult/java/org/hibernate/osgi/test/result/OsgiTestFailure.java new file mode 100644 index 0000000000..43a8da3fbe --- /dev/null +++ b/hibernate-osgi/src/testResult/java/org/hibernate/osgi/test/result/OsgiTestFailure.java @@ -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; + } +} diff --git a/hibernate-osgi/src/testResult/java/org/hibernate/osgi/test/result/OsgiTestResults.java b/hibernate-osgi/src/testResult/java/org/hibernate/osgi/test/result/OsgiTestResults.java new file mode 100644 index 0000000000..bc464c9b08 --- /dev/null +++ b/hibernate-osgi/src/testResult/java/org/hibernate/osgi/test/result/OsgiTestResults.java @@ -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 getFailures(); +} diff --git a/hibernate-osgi/src/testResult/java/org/hibernate/osgi/test/result/OsgiTestResultsImpl.java b/hibernate-osgi/src/testResult/java/org/hibernate/osgi/test/result/OsgiTestResultsImpl.java new file mode 100644 index 0000000000..4cee397fbe --- /dev/null +++ b/hibernate-osgi/src/testResult/java/org/hibernate/osgi/test/result/OsgiTestResultsImpl.java @@ -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 failures = new ArrayList(); + + @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 getFailures() { + return failures; + } +}