HHH-7387 - Integrate Draft 6 of the JPA 2.1 spec : CDI via reflection
This commit is contained in:
parent
a9c28bf28f
commit
63a2f0d7dc
|
@ -42,6 +42,10 @@ public class BeanManagerListenerFactory implements ListenerFactory {
|
|||
private final BeanManager beanManager;
|
||||
private final Map<Class,BeanMetaData> listeners = new ConcurrentHashMap<Class, BeanMetaData>();
|
||||
|
||||
public static BeanManagerListenerFactory fromBeanManagerReference(Object beanManagerReference) {
|
||||
return new BeanManagerListenerFactory( ( BeanManager ) beanManagerReference );
|
||||
}
|
||||
|
||||
public BeanManagerListenerFactory(BeanManager beanManager) {
|
||||
this.beanManager = beanManager;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,8 @@
|
|||
*/
|
||||
package org.hibernate.jpa.event.spi;
|
||||
|
||||
import javax.enterprise.inject.spi.BeanManager;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -187,10 +188,10 @@ public class JpaIntegrator implements Integrator {
|
|||
// handle JPA "entity listener classes"...
|
||||
|
||||
this.callbackRegistry = new CallbackRegistryImpl();
|
||||
final BeanManager beanManager = (BeanManager) configuration.getProperties().get( AvailableSettings.CDI_BEAN_MANAGER );
|
||||
this.jpaListenerFactory = beanManager == null
|
||||
final Object beanManagerRef = configuration.getProperties().get( AvailableSettings.CDI_BEAN_MANAGER );
|
||||
this.jpaListenerFactory = beanManagerRef == null
|
||||
? new StandardListenerFactory()
|
||||
: new BeanManagerListenerFactory( beanManager );
|
||||
: buildBeanManagerListenerFactory( beanManagerRef );
|
||||
this.callbackProcessor = new LegacyCallbackProcessor( jpaListenerFactory, configuration.getReflectionManager() );
|
||||
|
||||
Iterator classes = configuration.getClassMappings();
|
||||
|
@ -213,6 +214,34 @@ public class JpaIntegrator implements Integrator {
|
|||
}
|
||||
}
|
||||
|
||||
private ListenerFactory buildBeanManagerListenerFactory(Object beanManagerRef) {
|
||||
try {
|
||||
// specifically using our classloader here...
|
||||
final Class beanManagerListenerFactoryClass = getClass().getClassLoader()
|
||||
.loadClass( "org.hibernate.jpa.event.internal.jpa.BeanManagerListenerFactory" );
|
||||
final Method beanManagerListenerFactoryBuilderMethod = beanManagerListenerFactoryClass.getMethod(
|
||||
"fromBeanManagerReference",
|
||||
Object.class
|
||||
);
|
||||
|
||||
try {
|
||||
return (ListenerFactory) beanManagerListenerFactoryBuilderMethod.invoke( null, beanManagerRef );
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
throw e.getTargetException();
|
||||
}
|
||||
}
|
||||
catch (ReflectiveOperationException e) {
|
||||
throw new HibernateException( "Could not access BeanManagerListenerFactory class to handle CDI extensions", e );
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new HibernateException( "Problem calling BeanManagerListenerFactory class to handle CDI extensions", e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void integrate(
|
||||
MetadataImplementor metadata,
|
||||
|
@ -288,10 +317,10 @@ public class JpaIntegrator implements Integrator {
|
|||
// handle JPA "entity listener classes"...
|
||||
|
||||
this.callbackRegistry = new CallbackRegistryImpl();
|
||||
final BeanManager beanManager = (BeanManager) sessionFactory.getProperties().get( AvailableSettings.CDI_BEAN_MANAGER );
|
||||
this.jpaListenerFactory = beanManager == null
|
||||
final Object beanManagerRef = sessionFactory.getProperties().get( AvailableSettings.CDI_BEAN_MANAGER );
|
||||
this.jpaListenerFactory = beanManagerRef == null
|
||||
? new StandardListenerFactory()
|
||||
: new BeanManagerListenerFactory( beanManager );
|
||||
: buildBeanManagerListenerFactory( beanManagerRef );
|
||||
this.callbackProcessor = new CallbackProcessorImpl( jpaListenerFactory, metadata, serviceRegistry );
|
||||
|
||||
for ( EntityBinding binding : metadata.getEntityBindings() ) {
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
package org.hibernate.jpa.test.cdi;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
|
||||
import org.hibernate.bytecode.spi.ByteCodeHelper;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
import org.hibernate.testing.junit4.ClassLoadingIsolater;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Test JPA bootstrapping when CDI is not available for classloading.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NoCdiAvailableTest extends BaseUnitTestCase {
|
||||
public static final String[] EXCLUDED_PACKAGES = new String[] {
|
||||
"javax.enterprise.inject.",
|
||||
"javax.enterprise.context."
|
||||
};
|
||||
|
||||
private static class CdiClassLoadException extends RuntimeException {
|
||||
private CdiClassLoadException(String message) {
|
||||
super( message );
|
||||
}
|
||||
}
|
||||
|
||||
@Rule public ClassLoadingIsolater isolater = new ClassLoadingIsolater(
|
||||
new ClassLoadingIsolater.IsolatedClassLoaderProvider() {
|
||||
|
||||
@Override
|
||||
public ClassLoader buildIsolatedClassLoader() {
|
||||
return new ClassLoader(NoCdiAvailableTest.class.getClassLoader()) {
|
||||
@Override
|
||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
||||
for ( String excludedPackage : EXCLUDED_PACKAGES ) {
|
||||
if ( name.startsWith( excludedPackage ) ) {
|
||||
throw new CdiClassLoadException( "CDI classes [" + name + "] excluded from load" );
|
||||
}
|
||||
}
|
||||
|
||||
Class c = findLoadedClass( name );
|
||||
if ( c != null ) {
|
||||
return c;
|
||||
}
|
||||
|
||||
final String resourceName = name.replace( '.', '/' ) + ".class";
|
||||
final URL resource = getResource( resourceName );
|
||||
if ( resource == null ) {
|
||||
throw new ClassNotFoundException( name + " not found" );
|
||||
}
|
||||
if ( !"file".equals( resource.getProtocol() ) ) {
|
||||
return getParent().loadClass( name );
|
||||
}
|
||||
|
||||
InputStream is = this.getResourceAsStream( name.replace( '.', '/' ) + ".class" );
|
||||
if ( is == null ) {
|
||||
throw new ClassNotFoundException( name + " not found" );
|
||||
}
|
||||
|
||||
try {
|
||||
byte[] bytecode = ByteCodeHelper.readByteCode( is );
|
||||
return defineClass( name, bytecode, 0, bytecode.length );
|
||||
}
|
||||
catch( Throwable t ) {
|
||||
throw new ClassNotFoundException( "Error reading class file for " + name, t );
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseIsolatedClassLoader(ClassLoader isolatedClassLoader) {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@Test
|
||||
public void testJpaBootstrapWithoutCdiAvailable() throws Exception {
|
||||
Class delegateClass = Thread.currentThread().getContextClassLoader().loadClass(
|
||||
"org.hibernate.jpa.test.cdi.NoCdiAvailableTestDelegate"
|
||||
);
|
||||
Method mainMethod = delegateClass.getMethod( "passingNoBeanManager" );
|
||||
mainMethod.invoke( null );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJpaBootstrapWithoutCdiAvailablePassingCdi() throws Throwable {
|
||||
Class delegateClass = Thread.currentThread().getContextClassLoader().loadClass(
|
||||
"org.hibernate.jpa.test.cdi.NoCdiAvailableTestDelegate"
|
||||
);
|
||||
Method mainMethod = delegateClass.getMethod( "passingBeanManager" );
|
||||
try {
|
||||
mainMethod.invoke( null );
|
||||
fail( "Expecting failure from missing CDI classes" );
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
try {
|
||||
throw e.getTargetException();
|
||||
}
|
||||
catch (CdiClassLoadException expected) {
|
||||
}
|
||||
// catch (ClassCastException expectedAlt) {
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
*/
|
||||
package org.hibernate.jpa.test.cdi;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.hibernate.jpa.AvailableSettings;
|
||||
import org.hibernate.jpa.HibernatePersistenceProvider;
|
||||
import org.hibernate.jpa.test.PersistenceUnitInfoAdapter;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NoCdiAvailableTestDelegate {
|
||||
public static void passingNoBeanManager() {
|
||||
new HibernatePersistenceProvider().createContainerEntityManagerFactory(
|
||||
new PersistenceUnitInfoAdapter(),
|
||||
Collections.emptyMap()
|
||||
);
|
||||
}
|
||||
|
||||
public static void passingBeanManager() {
|
||||
new HibernatePersistenceProvider().createContainerEntityManagerFactory(
|
||||
new PersistenceUnitInfoAdapter(),
|
||||
Collections.singletonMap( AvailableSettings.CDI_BEAN_MANAGER, new Object() )
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue