Permalink
Browse files

HHH-7527 Enterprise OSGi JPA support

  • Loading branch information...
1 parent 7fe238a commit 94cbc61f04dcf6eed1ea116f4a32d027b08b3684 @brmeyer brmeyer committed Feb 9, 2013
Showing with 650 additions and 68 deletions.
  1. +47 −7 build.gradle
  2. +7 −0 hibernate-c3p0/hibernate-c3p0.gradle
  3. +13 −0 hibernate-core/hibernate-core.gradle
  4. +1 −1 hibernate-core/src/main/java/org/hibernate/engine/spi/CascadeStyle.java
  5. +3 −2 hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java
  6. +13 −7 hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java
  7. +13 −8 hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java
  8. +19 −6 hibernate-core/src/main/java/org/hibernate/internal/util/ReflectHelper.java
  9. +7 −0 hibernate-ehcache/hibernate-ehcache.gradle
  10. +19 −0 hibernate-entitymanager/hibernate-entitymanager.gradle
  11. +32 −9 hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
  12. +3 −1 hibernate-entitymanager/src/main/java/org/hibernate/ejb/HibernatePersistence.java
  13. +6 −1 hibernate-entitymanager/src/main/java/org/hibernate/{ → ejb}/engine/spi/EJB3CascadeStyle.java
  14. +2 −1 hibernate-entitymanager/src/main/java/org/hibernate/{ → ejb}/engine/spi/EJB3CascadingAction.java
  15. +2 −2 hibernate-entitymanager/src/main/java/org/hibernate/ejb/event/EJB3PersistEventListener.java
  16. +6 −0 hibernate-envers/hibernate-envers.gradle
  17. +3 −3 ...n/java/org/hibernate/envers/entities/mapper/relation/lazy/AbstractDelegateSessionImplementor.java
  18. +8 −1 hibernate-infinispan/hibernate-infinispan.gradle
  19. +13 −0 hibernate-osgi/hibernate-osgi.gradle
  20. +113 −0 hibernate-osgi/src/main/java/org/hibernate/osgi/HibernateBundleActivator.java
  21. +168 −0 hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiClassLoader.java
  22. +84 −0 hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiJtaPlatform.java
  23. +7 −1 hibernate-proxool/hibernate-proxool.gradle
  24. +7 −0 hibernate-testing/hibernate-testing.gradle
  25. +2 −3 libraries.gradle
  26. +1 −15 release/release.gradle
  27. +2 −0 settings.gradle
  28. +49 −0 utilities.gradle
View
54 build.gradle
@@ -59,6 +59,8 @@ subprojects { subProject ->
apply plugin: 'java'
apply plugin: 'maven' // for install task as well as deploy dependencies
apply plugin: 'uploadAuth'
+ apply plugin: 'osgi'
+ apply from: "../utilities.gradle"
configurations {
provided {
@@ -155,13 +157,51 @@ subprojects { subProject ->
compileJava.options.define(compilerArgs: ["-proc:none", "-encoding", "UTF-8"])
compileTestJava.options.define(compilerArgs: ["-proc:none", "-encoding", "UTF-8"])
- manifest.mainAttributes(
- provider: 'gradle',
- 'Implementation-Url': 'http://hibernate.org',
- 'Implementation-Version': version,
- 'Implementation-Vendor': 'Hibernate.org',
- 'Implementation-Vendor-Id': 'org.hibernate'
- )
+ jar {
+ Set<String> exportPackages = new HashSet<String>()
+ Set<String> privatePackages = new HashSet<String>()
+
+ // TODO: Could more of this be pulled into utilities.gradle?
+ sourceSets.each { SourceSet sourceSet ->
+ // skip certain source sets
+ if ( ! ['test','matrix'].contains( sourceSet.name ) ) {
+ sourceSet.java.each { javaFile ->
+ // - .util for external module use (especially envers)
+ final String[] temporaryExports = [
+ 'org.hibernate.internal.util' ]
+
+ final String packageName = determinePackageName( sourceSet.java, javaFile );
+ if ( ! temporaryExports.contains( packageName )
+ && ( packageName.endsWith( ".internal" )
+ || packageName.contains( ".internal." )
+ || packageName.endsWith( ".test" )
+ || packageName.contains( ".test." ) ) ) {
+ privatePackages.add( packageName );
+ }
+ else {
+ exportPackages.add( packageName );
+ }
+ }
+ }
+ }
+
+ manifest = osgiManifest {
+ // GRADLE-1411: Even if we override Imports and Exports
+ // auto-generation with instructions, classesDir and classpath
+ // need to be here (temporarily).
+ classesDir = sourceSets.main.output.classesDir
+ classpath = configurations.runtime
+
+ instruction 'Export-Package', exportPackages.toArray(new String[0])
+ instruction 'Private-Package', privatePackages.toArray(new String[0])
+ instruction 'Bundle-Vendor', 'Hibernate.org'
+
+ instruction 'Implementation-Url', 'http://hibernate.org'
+ instruction 'Implementation-Version', version
+ instruction 'Implementation-Vendor', 'Hibernate.org'
+ instruction 'Implementation-Vendor-Id', 'org.hibernate'
+ }
+ }
test {
// pass along command line defined system props (-D) to the test
View
7 hibernate-c3p0/hibernate-c3p0.gradle
@@ -8,4 +8,11 @@ dependencies {
transitive = true
}
testCompile project( ':hibernate-testing' )
+}
+
+jar {
+ manifest {
+ instruction 'Bundle-Description', 'Hibernate ORM C3P0'
+ instruction 'Bundle-SymbolicName', 'org.hibernate.c3p0'
+ }
}
View
13 hibernate-core/hibernate-core.gradle
@@ -37,6 +37,19 @@ manifest.mainAttributes(
'Main-Class': 'org.hibernate.Version'
)
+jar {
+ manifest {
+ instruction 'Bundle-Description', 'Hibernate ORM Core'
+ instruction 'Bundle-SymbolicName', 'org.hibernate.core'
+
+ // TODO: Uncomment once EntityManagerFactoryBuilderImpl no longer
+ // uses ClassLoaderServiceImpl.
+ instruction 'Export-Package',
+ 'org.hibernate.boot.registry.classloading.internal',
+ '*'
+ }
+}
+
sourceSets.main {
ext.jaxbTargetDir = file( "${buildDir}/generated-src/jaxb/main" )
java.srcDir jaxbTargetDir
View
2 hibernate-core/src/main/java/org/hibernate/engine/spi/CascadeStyle.java
@@ -285,7 +285,7 @@ public String toString() {
public CascadeStyle() {
}
- static final Map<String, CascadeStyle> STYLES = new HashMap<String, CascadeStyle>();
+ public static final Map<String, CascadeStyle> STYLES = new HashMap<String, CascadeStyle>();
static {
STYLES.put( "all", ALL );
View
5 hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java
@@ -30,6 +30,7 @@
import java.util.Map;
import org.hibernate.CacheMode;
+import org.hibernate.Criteria;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
@@ -170,11 +171,11 @@ public Object internalLoad(String entityName, Serializable id, boolean eager, bo
/**
* Execute a criteria query
*/
- public ScrollableResults scroll(CriteriaImpl criteria, ScrollMode scrollMode);
+ public ScrollableResults scroll(Criteria criteria, ScrollMode scrollMode);
/**
* Execute a criteria query
*/
- public List list(CriteriaImpl criteria);
+ public List list(Criteria criteria);
/**
* Execute a filter
View
20 hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java
@@ -1561,14 +1561,17 @@ public Criteria createCriteria(String entityName) {
return new CriteriaImpl(entityName, this);
}
- public ScrollableResults scroll(CriteriaImpl criteria, ScrollMode scrollMode) {
+ public ScrollableResults scroll(Criteria criteria, ScrollMode scrollMode) {
+ // TODO: Is this guaranteed to always be CriteriaImpl?
+ CriteriaImpl criteriaImpl = (CriteriaImpl) criteria;
+
errorIfClosed();
checkTransactionSynchStatus();
- String entityName = criteria.getEntityOrClassName();
+ String entityName = criteriaImpl.getEntityOrClassName();
CriteriaLoader loader = new CriteriaLoader(
getOuterJoinLoadable(entityName),
factory,
- criteria,
+ criteriaImpl,
entityName,
getLoadQueryInfluencers()
);
@@ -1582,16 +1585,19 @@ public ScrollableResults scroll(CriteriaImpl criteria, ScrollMode scrollMode) {
}
}
- public List list(CriteriaImpl criteria) throws HibernateException {
- final NaturalIdLoadAccess naturalIdLoadAccess = this.tryNaturalIdLoadAccess( criteria );
+ public List list(Criteria criteria) throws HibernateException {
+ // TODO: Is this guaranteed to always be CriteriaImpl?
+ CriteriaImpl criteriaImpl = (CriteriaImpl) criteria;
+
+ final NaturalIdLoadAccess naturalIdLoadAccess = this.tryNaturalIdLoadAccess( criteriaImpl );
if ( naturalIdLoadAccess != null ) {
// EARLY EXIT!
return Arrays.asList( naturalIdLoadAccess.load() );
}
errorIfClosed();
checkTransactionSynchStatus();
- String[] implementors = factory.getImplementors( criteria.getEntityOrClassName() );
+ String[] implementors = factory.getImplementors( criteriaImpl.getEntityOrClassName() );
int size = implementors.length;
CriteriaLoader[] loaders = new CriteriaLoader[size];
@@ -1601,7 +1607,7 @@ public List list(CriteriaImpl criteria) throws HibernateException {
loaders[i] = new CriteriaLoader(
getOuterJoinLoadable( implementors[i] ),
factory,
- criteria,
+ criteriaImpl,
implementors[i],
getLoadQueryInfluencers()
);
View
21 hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java
@@ -30,8 +30,6 @@
import java.util.List;
import java.util.Map;
-import org.jboss.logging.Logger;
-
import org.hibernate.CacheMode;
import org.hibernate.ConnectionReleaseMode;
import org.hibernate.Criteria;
@@ -73,6 +71,7 @@
import org.hibernate.pretty.MessageHelper;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.type.Type;
+import org.jboss.logging.Logger;
/**
* @author Gavin King
@@ -618,13 +617,16 @@ public Criteria createCriteria(String entityName) {
}
@Override
- public ScrollableResults scroll(CriteriaImpl criteria, ScrollMode scrollMode) {
+ public ScrollableResults scroll(Criteria criteria, ScrollMode scrollMode) {
+ // TODO: Is this guaranteed to always be CriteriaImpl?
+ CriteriaImpl criteriaImpl = (CriteriaImpl) criteria;
+
errorIfClosed();
- String entityName = criteria.getEntityOrClassName();
+ String entityName = criteriaImpl.getEntityOrClassName();
CriteriaLoader loader = new CriteriaLoader(
getOuterJoinLoadable( entityName ),
factory,
- criteria,
+ criteriaImpl,
entityName,
getLoadQueryInfluencers()
);
@@ -633,17 +635,20 @@ public ScrollableResults scroll(CriteriaImpl criteria, ScrollMode scrollMode) {
@Override
@SuppressWarnings( {"unchecked"})
- public List list(CriteriaImpl criteria) throws HibernateException {
+ public List list(Criteria criteria) throws HibernateException {
+ // TODO: Is this guaranteed to always be CriteriaImpl?
+ CriteriaImpl criteriaImpl = (CriteriaImpl) criteria;
+
errorIfClosed();
- String[] implementors = factory.getImplementors( criteria.getEntityOrClassName() );
+ String[] implementors = factory.getImplementors( criteriaImpl.getEntityOrClassName() );
int size = implementors.length;
CriteriaLoader[] loaders = new CriteriaLoader[size];
for( int i=0; i <size; i++ ) {
loaders[i] = new CriteriaLoader(
getOuterJoinLoadable( implementors[i] ),
factory,
- criteria,
+ criteriaImpl,
implementors[i],
getLoadQueryInfluencers()
);
View
25 hibernate-core/src/main/java/org/hibernate/internal/util/ReflectHelper.java
@@ -72,6 +72,9 @@
OBJECT_EQUALS = eq;
OBJECT_HASHCODE = hash;
}
+
+ // TODO: Better way to do this?
+ public static ClassLoader overridenClassLoader = null;
/**
* Disallow instantiation of ReflectHelper.
@@ -160,9 +163,14 @@ public static boolean implementsInterface(Class clazz, Class intf) {
*/
public static Class classForName(String name, Class caller) throws ClassNotFoundException {
try {
- ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
- if ( contextClassLoader != null ) {
- return contextClassLoader.loadClass( name );
+ if (overridenClassLoader != null) {
+ return overridenClassLoader.loadClass( name );
+ }
+ else {
+ ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+ if ( contextClassLoader != null ) {
+ return contextClassLoader.loadClass( name );
+ }
}
}
catch ( Throwable ignore ) {
@@ -182,9 +190,14 @@ public static Class classForName(String name, Class caller) throws ClassNotFound
*/
public static Class classForName(String name) throws ClassNotFoundException {
try {
- ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
- if ( contextClassLoader != null ) {
- return contextClassLoader.loadClass(name);
+ if (overridenClassLoader != null) {
+ return overridenClassLoader.loadClass( name );
+ }
+ else {
+ ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+ if ( contextClassLoader != null ) {
+ return contextClassLoader.loadClass(name);
+ }
}
}
catch ( Throwable ignore ) {
View
7 hibernate-ehcache/hibernate-ehcache.gradle
@@ -4,3 +4,10 @@ dependencies {
testCompile project( ':hibernate-testing' )
}
+
+jar {
+ manifest {
+ instruction 'Bundle-Description', 'Hibernate ORM EHCache'
+ instruction 'Bundle-SymbolicName', 'org.hibernate.ehcache'
+ }
+}
View
19 hibernate-entitymanager/hibernate-entitymanager.gradle
@@ -16,6 +16,25 @@ dependencies {
testRuntime( libraries.validator )
}
+jar {
+ manifest {
+ instruction 'Bundle-Description', 'Hibernate ORM JPA Entity Manager'
+ instruction 'Bundle-SymbolicName', 'org.hibernate.entitymanager'
+
+ // A cdi-api OSGi bundle does not currently exist. For now, explicitly
+ // ignore its packages. This will only cause issues if an app tries
+ // to use the BeanManagerListenerFactory functionality.
+ // NOTE: The "!" negates the package, keeping it out of Import-Package
+ // and including it in Ignore-Package. Also note that '*' does not mean
+ // <Import-Package>*</ImportPackage> will occur. This is simply a
+ // BND instruction -- the auto-discovery of imported packages still
+ // occurs.
+ instruction 'Import-Package',
+ '!javax.enterprise*',
+ '*'
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////////
// JPA model-gen set up
////////////////////////////////////////////////////////////////////////////////////////////////////////
View
41 hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
@@ -169,6 +169,12 @@ public void handleEntityNotFound(String entityName, Serializable id) {
public Ejb3Configuration() {
+ this(null);
+ }
+
+
+ public Ejb3Configuration(ClassLoader overridenClassLoader) {
+ this.overridenClassLoader = overridenClassLoader;
cfg = new Configuration();
cfg.setEntityNotFoundDelegate( ejb3EntityNotFoundDelegate );
}
@@ -541,20 +547,27 @@ public Ejb3Configuration configure(PersistenceUnitInfo info, Map integration) {
// set the classloader, passed in by the container in info, to set as the TCCL so that
// Hibernate uses it to properly resolve class references.
- if ( info.getClassLoader() == null ) {
- throw new IllegalStateException(
- "[PersistenceUnit: " + info.getPersistenceUnitName() == null ? "" : info.getPersistenceUnitName()
- + "] " + "PersistenceUnitInfo.getClassLoader() id null" );
- }
Thread thread = Thread.currentThread();
ClassLoader contextClassLoader = thread.getContextClassLoader();
- boolean sameClassLoader = info.getClassLoader().equals( contextClassLoader );
- if ( ! sameClassLoader ) {
- overridenClassLoader = info.getClassLoader();
+ boolean sameClassLoader = true;
+ if (overridenClassLoader != null) {
thread.setContextClassLoader( overridenClassLoader );
+ sameClassLoader = false;
}
else {
- overridenClassLoader = null;
+ if ( info.getClassLoader() == null ) {
+ throw new IllegalStateException(
+ "[PersistenceUnit: " + info.getPersistenceUnitName() == null ? "" : info.getPersistenceUnitName()
+ + "] " + "PersistenceUnitInfo.getClassLoader() id null" );
+ }
+ sameClassLoader = info.getClassLoader().equals( contextClassLoader );
+ if ( ! sameClassLoader ) {
+ overridenClassLoader = info.getClassLoader();
+ thread.setContextClassLoader( overridenClassLoader );
+ }
+ else {
+ overridenClassLoader = null;
+ }
}
// Best I can tell, 'workingVars' is some form of additional configuration contract.
@@ -848,6 +861,12 @@ private void scanForClasses(ScanningContext scanningContext, List<String> packag
LOG.containerProvidingNullPersistenceUnitRootUrl();
return;
}
+ if ( scanningContext.url.getProtocol().equalsIgnoreCase( "bundle" ) ) {
+ // TODO: Is there a way to scan the root bundle URL in OSGi containers?
+ // Although the URL provides a stream handler that works for finding
+ // resources in a specific Bundle, the root one does not work.
+ return;
+ }
try {
addScannedEntries( scanningContext, entities, packages, hbmFiles, null );
}
@@ -898,6 +917,10 @@ public EntityManagerFactory buildEntityManagerFactory(BootstrapServiceRegistryBu
thread = Thread.currentThread();
contextClassLoader = thread.getContextClassLoader();
thread.setContextClassLoader( overridenClassLoader );
+ builder.withApplicationClassLoader( overridenClassLoader );
+ builder.withEnvironmentClassLoader( overridenClassLoader );
+ builder.withHibernateClassLoader( overridenClassLoader );
+ builder.withResourceClassLoader( overridenClassLoader );
}
try {
View
4 hibernate-entitymanager/src/main/java/org/hibernate/ejb/HibernatePersistence.java
@@ -24,6 +24,7 @@
package org.hibernate.ejb;
import java.util.Map;
+
import javax.persistence.EntityManagerFactory;
import javax.persistence.spi.LoadState;
import javax.persistence.spi.PersistenceProvider;
@@ -38,8 +39,9 @@
* @author Gavin King
*/
public class HibernatePersistence extends AvailableSettings implements PersistenceProvider {
+
private final PersistenceUtilHelper.MetadataCache cache = new PersistenceUtilHelper.MetadataCache();
-
+
/**
* Get an entity manager factory by its entity manager name, using the specified
* properties (they override any found in the peristence.xml file).
View
7 ...ibernate/engine/spi/EJB3CascadeStyle.java → ...nate/ejb/engine/spi/EJB3CascadeStyle.java
@@ -19,7 +19,12 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.engine.spi;
+package org.hibernate.ejb.engine.spi;
+
+import static org.hibernate.engine.spi.CascadeStyle.STYLES;
+
+import org.hibernate.engine.spi.CascadeStyle;
+import org.hibernate.engine.spi.CascadingAction;
/**
* Becasue CascadeStyle is not opened and package protected,
View
3 ...rnate/engine/spi/EJB3CascadingAction.java → ...e/ejb/engine/spi/EJB3CascadingAction.java
@@ -19,7 +19,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.engine.spi;
+package org.hibernate.ejb.engine.spi;
import java.util.Iterator;
import java.util.Map;
@@ -28,6 +28,7 @@
import org.hibernate.HibernateException;
import org.hibernate.ejb.internal.EntityManagerMessageLogger;
+import org.hibernate.engine.spi.CascadingAction;
import org.hibernate.event.spi.EventSource;
import org.hibernate.type.CollectionType;
View
4 hibernate-entitymanager/src/main/java/org/hibernate/ejb/event/EJB3PersistEventListener.java
@@ -25,9 +25,9 @@
import java.io.Serializable;
+import org.hibernate.ejb.engine.spi.EJB3CascadeStyle;
+import org.hibernate.ejb.engine.spi.EJB3CascadingAction;
import org.hibernate.engine.spi.CascadingAction;
-import org.hibernate.engine.spi.EJB3CascadeStyle;
-import org.hibernate.engine.spi.EJB3CascadingAction;
import org.hibernate.event.internal.DefaultPersistEventListener;
import org.hibernate.event.spi.EventSource;
View
6 hibernate-envers/hibernate-envers.gradle
@@ -37,3 +37,9 @@ task generateJpaMetamodelClasses(type: Compile) {
}
compileJava.dependsOn generateJpaMetamodelClasses
+jar {
+ manifest {
+ instruction 'Bundle-Description', 'Hibernate ORM Envers'
+ instruction 'Bundle-SymbolicName', 'org.hibernate.envers'
+ }
+}
View
6 ...rg/hibernate/envers/entities/mapper/relation/lazy/AbstractDelegateSessionImplementor.java
@@ -30,6 +30,7 @@
import java.util.Map;
import org.hibernate.CacheMode;
+import org.hibernate.Criteria;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
@@ -48,7 +49,6 @@
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
-import org.hibernate.internal.CriteriaImpl;
import org.hibernate.loader.custom.CustomQuery;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.Type;
@@ -160,12 +160,12 @@ public ScrollableResults scroll(String query, QueryParameters queryParameters) t
}
@Override
- public ScrollableResults scroll(CriteriaImpl criteria, ScrollMode scrollMode) {
+ public ScrollableResults scroll(Criteria criteria, ScrollMode scrollMode) {
return delegate.scroll(criteria, scrollMode);
}
@Override
- public List list(CriteriaImpl criteria) {
+ public List list(Criteria criteria) {
return delegate.list(criteria);
}
View
9 hibernate-infinispan/hibernate-infinispan.gradle
@@ -40,4 +40,11 @@ task sourcesTestJar(type: Jar, dependsOn:classes) {
}
artifacts.archives packageTests
-artifacts.archives sourcesTestJar
+artifacts.archives sourcesTestJar
+
+jar {
+ manifest {
+ instruction 'Bundle-Description', 'Hibernate ORM Infinispan'
+ instruction 'Bundle-SymbolicName', 'org.hibernate.infinispan'
+ }
+}
View
13 hibernate-osgi/hibernate-osgi.gradle
@@ -0,0 +1,13 @@
+dependencies {
+ compile( project( ':hibernate-core' ) )
+ compile( project( ':hibernate-entitymanager' ) )
+ compile( "org.osgi:org.osgi.core:4.2.0" )
+}
+
+jar {
+ manifest {
+ instruction 'Bundle-Activator', 'org.hibernate.osgi.HibernateBundleActivator'
+ instruction 'Bundle-Description', 'Hibernate ORM OSGi'
+ instruction 'Bundle-SymbolicName', 'org.hibernate.osgi'
+ }
+}
View
113 hibernate-osgi/src/main/java/org/hibernate/osgi/HibernateBundleActivator.java
@@ -0,0 +1,113 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * 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, as published by the Free Software Foundation.
+ *
+ * This program 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 distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.osgi;
+
+import java.util.Map;
+import java.util.Properties;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.spi.PersistenceProvider;
+import javax.persistence.spi.PersistenceUnitInfo;
+import javax.persistence.spi.PersistenceUnitTransactionType;
+
+import org.hibernate.cfg.AvailableSettings;
+import org.hibernate.ejb.Ejb3Configuration;
+import org.hibernate.ejb.HibernatePersistence;
+import org.hibernate.internal.util.ReflectHelper;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+
+/**
+ * @author Brett Meyer
+ * @author Martin Neimeier
+ */
+public class HibernateBundleActivator
+ extends HibernatePersistence
+ implements BundleActivator, /*ServiceListener,*/ BundleListener {
+
+ private BundleContext context;
+
+ private OsgiClassLoader osgiClassLoader;
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+
+ this.context = context;
+
+ // register this instance as a bundle listener to get informed about all
+ // bundle live cycle events
+ context.addBundleListener(this);
+
+ osgiClassLoader = new OsgiClassLoader();
+ ReflectHelper.overridenClassLoader = osgiClassLoader;
+
+ for ( Bundle bundle : context.getBundles() ) {
+ handleBundleChange( bundle );
+ }
+
+ Properties properties = new Properties();
+ properties.put( "javax.persistence.provider", HibernateBundleActivator.class.getName() );
+ context.registerService(
+ PersistenceProvider.class.getName(),
+ this,
+ properties
+ );
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ context.removeBundleListener(this);
+
+ // Nothing else to do. When re-activated, this Activator will be
+ // re-started and the EMF re-created.
+ }
+
+ @Override
+ public void bundleChanged(BundleEvent event) {
+ handleBundleChange( event.getBundle() );
+
+ }
+
+ private void handleBundleChange( Bundle bundle ) {
+ if ( bundle.getState() == Bundle.ACTIVE ) {
+ osgiClassLoader.registerBundle(bundle);
+ } else {
+ osgiClassLoader.unregisterBundle(bundle);
+ }
+ }
+
+ @Override
+ public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map) {
+ Ejb3Configuration cfg = new Ejb3Configuration(osgiClassLoader);
+ if ( info.getTransactionType().equals( PersistenceUnitTransactionType.JTA ) ) {
+ map.put( AvailableSettings.JTA_PLATFORM, new OsgiJtaPlatform( context ) );
+ }
+ Ejb3Configuration configured = cfg.configure( info, map );
+ return configured != null ? configured.buildEntityManagerFactory() : null;
+ }
+
+}
View
168 hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiClassLoader.java
@@ -0,0 +1,168 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * 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, as published by the Free Software Foundation.
+ *
+ * This program 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 distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.osgi;
+
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.HashMap;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * Custom OSGI ClassLoader helper which knows all the "interesting" bundles and
+ * encapsulates the OSGi related capabilities.
+ *
+ * @author Brett Meyer
+ */
+public class OsgiClassLoader extends ClassLoader {
+
+ private HashMap<String, Bundle> bundles;
+
+ public OsgiClassLoader() {
+ bundles = new HashMap<String, Bundle>();
+ }
+
+ /**
+ * Load the class and break on first found match.
+ * TODO: Should this throw a different exception or warn if multiple
+ * classes were found? Naming collisions can and do happen in OSGi...
+ */
+ @SuppressWarnings("rawtypes")
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ // TODO: This is horrible -- we shouldn't iterate over all the
+ // classloaders every time we need to construct an entity, etc. Instead,
+ // keep references to all classes/resources found in active bundles
+ // in memory? Find a way to identify what we "care about" and keep
+ // only those? Discover them the first time and then cache the
+ // reference?
+ for ( Bundle bundle : bundles.values() ) {
+ try {
+ Class clazz = bundle.loadClass( name );
+ if ( clazz != null ) {
+ return clazz;
+ }
+ }
+ catch ( Exception ignore ) {
+ }
+ }
+
+ throw new ClassNotFoundException( "Could not load requested class : " + name );
+ }
+
+ /**
+ * Load the class and break on first found match.
+ * TODO: Should this throw a different exception or warn if multiple
+ * classes were found? Naming collisions can and do happen in OSGi...
+ */
+ @Override
+ protected URL findResource(String name) {
+ // TODO: This is horrible -- we shouldn't iterate over all the
+ // classloaders every time we need to construct an entity, etc. Instead,
+ // keep references to all classes/resources found in active bundles
+ // in memory? Find a way to identify what we "care about" and keep
+ // only those? Discover them the first time and then cache the
+ // reference?
+ for ( Bundle bundle : bundles.values() ) {
+ try {
+ URL resource = bundle.getResource( name );
+ if ( resource != null ) {
+ return resource;
+ }
+ }
+ catch ( Exception ignore ) {
+ }
+ }
+ // TODO: Error?
+ return null;
+ }
+
+ /**
+ * Load the class and break on first found match.
+ * TODO: Should this throw a different exception or warn if multiple
+ * classes were found? Naming collisions can and do happen in OSGi...
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ protected Enumeration<URL> findResources(String name) {
+ // TODO: This is horrible -- we shouldn't iterate over all the
+ // classloaders every time we need to construct an entity, etc. Instead,
+ // keep references to all classes/resources found in active bundles
+ // in memory? Find a way to identify what we "care about" and keep
+ // only those? Discover them the first time and then cache the
+ // reference?
+ for ( Bundle bundle : bundles.values() ) {
+ try {
+ Enumeration<URL> resources = bundle.getResources( name );
+ if ( resources != null ) {
+ return resources;
+ }
+ }
+ catch ( Exception ignore ) {
+ }
+ }
+ // TODO: Error?
+ return null;
+ }
+
+ /**
+ * Register the bundle with this class loader
+ */
+ public void registerBundle(Bundle bundle) {
+ if ( bundle != null ) {
+ synchronized ( bundles ) {
+ // create a bundle classloader and add it to the list of
+ // classloaders
+ String key = getBundleKey( bundle );
+ if ( !bundles.containsKey( key ) ) {
+ bundles.put( key, bundle );
+ }
+ }
+ }
+ }
+
+ /**
+ * Unregister the bundle from this class loader
+ */
+ public void unregisterBundle(Bundle bundle) {
+ if ( bundle != null ) {
+ synchronized ( bundles ) {
+ // remove a bundle classloader for a given bundle
+ String key = getBundleKey( bundle );
+ if ( bundles.containsKey( key ) ) {
+ bundles.remove( key );
+ }
+ }
+ }
+ }
+
+ public void clear() {
+ bundles.clear();
+ }
+
+ protected static String getBundleKey(Bundle bundle) {
+ return bundle.getSymbolicName() + " " + bundle.getVersion().toString();
+ }
+
+}
View
84 hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiJtaPlatform.java
@@ -0,0 +1,84 @@
+/*
+ * 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;
+
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Offers the JTA Platform provided by the OSGi container. The Enterprise
+ * OSGi spec requires all containers to register UserTransaction
+ * and TransactionManager OSGi services.
+ *
+ * @author Brett Meyer
+ */
+public class OsgiJtaPlatform implements JtaPlatform {
+
+ private static final long serialVersionUID = 1L;
+
+ private BundleContext bundleContext;
+
+ public OsgiJtaPlatform(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ @Override
+ public TransactionManager retrieveTransactionManager() {
+ ServiceReference sr = bundleContext.getServiceReference( TransactionManager.class.getName() );
+ return (TransactionManager) bundleContext.getService( sr );
+ }
+
+ @Override
+ public UserTransaction retrieveUserTransaction() {
+ ServiceReference sr = bundleContext.getServiceReference( UserTransaction.class.getName() );
+ return (UserTransaction) bundleContext.getService( sr );
+ }
+
+ @Override
+ public Object getTransactionIdentifier(Transaction transaction) {
+ // AbstractJtaPlatform just uses the transaction itself.
+ return transaction;
+ }
+
+ @Override
+ public boolean canRegisterSynchronization() {
+ // TODO
+ return false;
+ }
+
+ @Override
+ public void registerSynchronization(Synchronization synchronization) {
+ // TODO
+ }
+
+ @Override
+ public int getCurrentStatus() throws SystemException {
+ return retrieveTransactionManager().getStatus();
+ }
+
+}
View
8 hibernate-proxool/hibernate-proxool.gradle
@@ -1,6 +1,12 @@
-
dependencies {
compile project( ':hibernate-core' )
compile( libraries.proxool )
testCompile project( ':hibernate-testing' )
}
+
+jar {
+ manifest {
+ instruction 'Bundle-Description', 'Hibernate ORM Proxool'
+ instruction 'Bundle-SymbolicName', 'org.hibernate.proxool'
+ }
+}
View
7 hibernate-testing/hibernate-testing.gradle
@@ -8,4 +8,11 @@ dependencies {
compile ( libraries.jboss_jta ) {
transitive=false;
}
+}
+
+jar {
+ manifest {
+ instruction 'Bundle-Description', 'Hibernate ORM Testing'
+ instruction 'Bundle-SymbolicName', 'org.hibernate.testing'
+ }
}
View
5 libraries.gradle
@@ -32,7 +32,7 @@ libraries = [
jpa: 'org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.1.Final',
jta: 'org.jboss.spec.javax.transaction:jboss-transaction-api_1.1_spec:1.0.0.Final',
validation: 'javax.validation:validation-api:1.0.0.GA',
- jacc: 'org.jboss.spec.javax.security.jacc:jboss-jacc-api_1.4_spec:1.0.0.Final',
+ jacc: 'org.jboss.spec.javax.security.jacc:jboss-jacc-api_1.4_spec:1.0.2.Final',
// logging
logging: 'org.jboss.logging:jboss-logging:3.1.0.GA',
@@ -77,8 +77,7 @@ libraries = [
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ c3p0
c3p0: "c3p0:c3p0:0.9.1",
ehcache: "net.sf.ehcache:ehcache-core:2.4.3",
- proxool: "proxool:proxool:0.8.3",
-
+ proxool: "proxool:proxool:0.8.3"
]
}
View
16 release/release.gradle
@@ -1,5 +1,6 @@
apply plugin: 'base'
apply plugin: 'idea'
+apply from: "../utilities.gradle"
buildDir = "target"
@@ -83,21 +84,6 @@ task aggregateJavadocs(type: Javadoc) {
}
}
-String determinePackageName(SourceDirectorySet sourceDirectorySet, File javaFile) {
- final javaFileAbsolutePath = javaFile.absolutePath;
- for ( File sourceDirectory : sourceDirectorySet.srcDirs ) {
- final String sourceDirectoryAbsolutePath = sourceDirectory.absolutePath;
- if ( javaFileAbsolutePath.startsWith( sourceDirectoryAbsolutePath ) ) {
- final String javaFileRelativePath = javaFileAbsolutePath.substring(
- sourceDirectoryAbsolutePath.length() + 1,
- javaFileAbsolutePath.lastIndexOf( File.separator )
- );
- return javaFileRelativePath.replace( File.separator, "." );
- }
- }
- throw new RuntimeException( "ugh" );
-}
-
aggregateJavadocs.doLast {
copy {
from new File( projectDir, 'src/javadoc/images' )
View
2 settings.gradle
@@ -3,6 +3,8 @@ include 'hibernate-testing'
include 'hibernate-entitymanager'
include 'hibernate-envers'
+include 'hibernate-osgi'
+
include 'hibernate-c3p0'
include 'hibernate-proxool'
View
49 utilities.gradle
@@ -0,0 +1,49 @@
+
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2012, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * 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, as published by the Free Software Foundation.
+ *
+ * This program 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 distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+
+apply plugin: UtilitiesPlugin
+
+class UtilitiesPlugin implements Plugin {
+ def void apply(Object project) {
+ project.convention.plugins.utilities = new UtilitiesPluginDef()
+ }
+}
+
+class UtilitiesPluginDef {
+ public String determinePackageName(SourceDirectorySet sourceDirectorySet, File javaFile) {
+ final javaFileAbsolutePath = javaFile.absolutePath;
+ for ( File sourceDirectory : sourceDirectorySet.srcDirs ) {
+ final String sourceDirectoryAbsolutePath = sourceDirectory.absolutePath;
+ if ( javaFileAbsolutePath.startsWith( sourceDirectoryAbsolutePath ) ) {
+ final String javaFileRelativePath = javaFileAbsolutePath.substring(
+ sourceDirectoryAbsolutePath.length() + 1,
+ javaFileAbsolutePath.lastIndexOf( File.separator )
+ );
+ return javaFileRelativePath.replace( File.separator, "." );
+ }
+ }
+ throw new RuntimeException( "ugh" );
+ }
+}

0 comments on commit 94cbc61

Please sign in to comment.