Fix classloader isolation tests
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@14494 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
b3428358b7
commit
2052b06d53
|
@ -85,6 +85,11 @@ public abstract class BasicRegionAdapter implements Region {
|
|||
protected abstract Fqn<String> createRegionFqn(String regionName, String regionPrefix);
|
||||
|
||||
protected void activateLocalClusterNode() {
|
||||
|
||||
// Regions can get instantiated in the course of normal work (e.g.
|
||||
// a named query region will be created the first time the query is
|
||||
// executed), so suspend any ongoing tx
|
||||
Transaction tx = suspend();
|
||||
try {
|
||||
Configuration cfg = jbcCache.getConfiguration();
|
||||
if (cfg.isUseRegionBasedMarshalling()) {
|
||||
|
@ -128,6 +133,11 @@ public abstract class BasicRegionAdapter implements Region {
|
|||
catch (Exception e) {
|
||||
throw new CacheException(e.getMessage(), e);
|
||||
}
|
||||
finally {
|
||||
if (tx != null)
|
||||
resume(tx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void establishRegionRootNode()
|
||||
|
|
|
@ -16,9 +16,6 @@
|
|||
|
||||
package org.hibernate.test.cache.jbc2.functional;
|
||||
|
||||
import javax.transaction.TransactionManager;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.cfg.Mappings;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
|
@ -28,7 +25,6 @@ import org.hibernate.test.cache.jbc2.functional.util.DualNodeConnectionProviderI
|
|||
import org.hibernate.test.cache.jbc2.functional.util.DualNodeJtaTransactionManagerImpl;
|
||||
import org.hibernate.test.cache.jbc2.functional.util.DualNodeTestUtil;
|
||||
import org.hibernate.test.cache.jbc2.functional.util.DualNodeTransactionManagerLookup;
|
||||
import org.hibernate.test.cache.jbc2.functional.util.TestCacheInstanceManager;
|
||||
import org.hibernate.transaction.CMTTransactionFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
|
@ -212,6 +212,10 @@ public class ClassLoaderTestDAO
|
|||
try {
|
||||
Query query = sessionFactory.getCurrentSession().createQuery("select account.balance from Account as account where account.accountHolder = ?");
|
||||
query.setParameter(0, holder);
|
||||
if (useRegion)
|
||||
{
|
||||
query.setCacheRegion("AccountRegion");
|
||||
}
|
||||
query.setCacheable(true);
|
||||
results = query.list();
|
||||
tm.commit();
|
||||
|
|
|
@ -73,6 +73,12 @@ extends DualNodeTestCaseBase
|
|||
|
||||
static int test = 0;
|
||||
|
||||
private Cache localCache;
|
||||
private CacheAccessListener localListener;
|
||||
|
||||
private Cache remoteCache;
|
||||
private CacheAccessListener remoteListener;
|
||||
|
||||
public PessimisticIsolatedClassLoaderTest(String name)
|
||||
{
|
||||
super(name);
|
||||
|
@ -120,6 +126,22 @@ extends DualNodeTestCaseBase
|
|||
// Don't clean up the managers, just the transactions
|
||||
// Managers are still needed by the long-lived caches
|
||||
DualNodeJtaTransactionManagerImpl.cleanupTransactions();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cleanupTest() throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
if (localCache != null && localListener != null)
|
||||
localCache.removeCacheListener(localListener);
|
||||
if (remoteCache != null && remoteListener != null)
|
||||
remoteCache.removeCacheListener(remoteListener);
|
||||
}
|
||||
finally
|
||||
{
|
||||
super.cleanupTest();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -145,9 +167,11 @@ extends DualNodeTestCaseBase
|
|||
|
||||
org.jboss.cache.Fqn fqn = org.jboss.cache.Fqn.fromString("/isolated1");
|
||||
org.jboss.cache.Region r = localCache.getRegion(fqn, true);
|
||||
r.registerContextClassLoader(cl.getParent());
|
||||
r.activate();
|
||||
|
||||
r = remoteCache.getRegion(fqn, true);
|
||||
r.registerContextClassLoader(cl.getParent());
|
||||
r.activate();
|
||||
Thread.currentThread().setContextClassLoader(cl);
|
||||
Account acct = new Account();
|
||||
|
@ -182,16 +206,16 @@ extends DualNodeTestCaseBase
|
|||
// Bind a listener to the "local" cache
|
||||
// Our region factory makes its CacheManager available to us
|
||||
CacheManager localManager = TestCacheInstanceManager.getTestCacheManager(DualNodeTestUtil.LOCAL);
|
||||
Cache localCache = localManager.getCache(getEntityCacheConfigName(), true);
|
||||
CacheAccessListener localListener = new CacheAccessListener();
|
||||
this.localCache = localManager.getCache(getEntityCacheConfigName(), true);
|
||||
this.localListener = new CacheAccessListener();
|
||||
localCache.addCacheListener(localListener);
|
||||
|
||||
TransactionManager localTM = localCache.getConfiguration().getRuntimeConfig().getTransactionManager();
|
||||
|
||||
// Bind a listener to the "remote" cache
|
||||
CacheManager remoteManager = TestCacheInstanceManager.getTestCacheManager(DualNodeTestUtil.REMOTE);
|
||||
Cache remoteCache = remoteManager.getCache(getEntityCacheConfigName(), true);
|
||||
CacheAccessListener remoteListener = new CacheAccessListener();
|
||||
this.remoteCache = remoteManager.getCache(getEntityCacheConfigName(), true);
|
||||
this.remoteListener = new CacheAccessListener();
|
||||
remoteCache.addCacheListener(remoteListener);
|
||||
|
||||
TransactionManager remoteTM = remoteCache.getConfiguration().getRuntimeConfig().getTransactionManager();
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Red Hat Author(s): Brian Stansberry
|
||||
*/
|
||||
|
||||
package org.hibernate.test.cache.jbc2.functional.util;
|
||||
|
||||
import org.jboss.cache.Cache;
|
||||
import org.jboss.cache.CacheManagerImpl;
|
||||
import org.jboss.cache.DefaultCacheFactory;
|
||||
import org.jboss.cache.config.Configuration;
|
||||
import org.jgroups.ChannelFactory;
|
||||
|
||||
/**
|
||||
* CacheManager implementation that lets us set a default ClassLoader
|
||||
* on the created cache.
|
||||
*
|
||||
* @author <a href="brian.stansberry@jboss.com">Brian Stansberry</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class CustomClassLoaderCacheManager extends CacheManagerImpl
|
||||
{
|
||||
private final ClassLoader defaultClassLoader;
|
||||
|
||||
/**
|
||||
* Create a new CustomClassLoaderCacheManager.
|
||||
*
|
||||
* @param configFileName
|
||||
* @param factory
|
||||
*/
|
||||
public CustomClassLoaderCacheManager(String configFileName,
|
||||
ChannelFactory factory,
|
||||
ClassLoader defaultClassLoader)
|
||||
{
|
||||
super(configFileName, factory);
|
||||
this.defaultClassLoader = defaultClassLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Cache<Object, Object> createCache(Configuration config)
|
||||
{
|
||||
DefaultCacheFactory<Object, Object> factory = new DefaultCacheFactory<Object, Object>();
|
||||
factory.setDefaultClassLoader(defaultClassLoader);
|
||||
return factory.createCache(config, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -35,8 +35,6 @@ import javax.transaction.SystemException;
|
|||
import javax.transaction.Transaction;
|
||||
import javax.transaction.TransactionManager;
|
||||
|
||||
import org.hibernate.test.cache.jbc2.functional.classloader.ClassLoaderTestDAO;
|
||||
import org.hsqldb.lib.Iterator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -52,7 +50,7 @@ public class DualNodeJtaTransactionManagerImpl implements TransactionManager {
|
|||
|
||||
private static final Hashtable INSTANCES = new Hashtable();
|
||||
|
||||
private DualNodeJtaTransactionImpl currentTransaction;
|
||||
private ThreadLocal currentTransaction = new ThreadLocal();
|
||||
private String nodeId;
|
||||
|
||||
public synchronized static DualNodeJtaTransactionManagerImpl getInstance(String nodeId) {
|
||||
|
@ -87,62 +85,66 @@ public class DualNodeJtaTransactionManagerImpl implements TransactionManager {
|
|||
}
|
||||
|
||||
public int getStatus() throws SystemException {
|
||||
return currentTransaction == null ? Status.STATUS_NO_TRANSACTION : currentTransaction.getStatus();
|
||||
Transaction tx = getCurrentTransaction();
|
||||
return tx == null ? Status.STATUS_NO_TRANSACTION : tx.getStatus();
|
||||
}
|
||||
|
||||
public Transaction getTransaction() throws SystemException {
|
||||
return currentTransaction;
|
||||
return (Transaction) currentTransaction.get();
|
||||
}
|
||||
|
||||
public DualNodeJtaTransactionImpl getCurrentTransaction() {
|
||||
return currentTransaction;
|
||||
return (DualNodeJtaTransactionImpl) currentTransaction.get();
|
||||
}
|
||||
|
||||
public void begin() throws NotSupportedException, SystemException {
|
||||
currentTransaction = new DualNodeJtaTransactionImpl( this );
|
||||
currentTransaction.set(new DualNodeJtaTransactionImpl( this ));
|
||||
}
|
||||
|
||||
public Transaction suspend() throws SystemException {
|
||||
log.trace(nodeId + ": Suspending " + currentTransaction + " for thread " + Thread.currentThread().getName());
|
||||
DualNodeJtaTransactionImpl suspended = currentTransaction;
|
||||
currentTransaction = null;
|
||||
DualNodeJtaTransactionImpl suspended = getCurrentTransaction();
|
||||
log.trace(nodeId + ": Suspending " + suspended + " for thread " + Thread.currentThread().getName());
|
||||
currentTransaction.set(null);
|
||||
return suspended;
|
||||
}
|
||||
|
||||
public void resume(Transaction transaction)
|
||||
throws InvalidTransactionException, IllegalStateException, SystemException {
|
||||
currentTransaction = ( DualNodeJtaTransactionImpl ) transaction;
|
||||
log.trace(nodeId + ": Resumed " + currentTransaction + " for thread " + Thread.currentThread().getName());
|
||||
currentTransaction.set(( DualNodeJtaTransactionImpl ) transaction);
|
||||
log.trace(nodeId + ": Resumed " + transaction + " for thread " + Thread.currentThread().getName());
|
||||
}
|
||||
|
||||
public void commit()
|
||||
throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, IllegalStateException, SystemException {
|
||||
if ( currentTransaction == null ) {
|
||||
Transaction tx = getCurrentTransaction();
|
||||
if ( tx == null ) {
|
||||
throw new IllegalStateException( "no current transaction to commit" );
|
||||
}
|
||||
currentTransaction.commit();
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
public void rollback() throws IllegalStateException, SecurityException, SystemException {
|
||||
if ( currentTransaction == null ) {
|
||||
Transaction tx = getCurrentTransaction();
|
||||
if ( tx == null ) {
|
||||
throw new IllegalStateException( "no current transaction" );
|
||||
}
|
||||
currentTransaction.rollback();
|
||||
tx.rollback();
|
||||
}
|
||||
|
||||
public void setRollbackOnly() throws IllegalStateException, SystemException {
|
||||
if ( currentTransaction == null ) {
|
||||
Transaction tx = getCurrentTransaction();
|
||||
if ( tx == null ) {
|
||||
throw new IllegalStateException( "no current transaction" );
|
||||
}
|
||||
currentTransaction.setRollbackOnly();
|
||||
tx.setRollbackOnly();
|
||||
}
|
||||
|
||||
public void setTransactionTimeout(int i) throws SystemException {
|
||||
}
|
||||
|
||||
void endCurrent(DualNodeJtaTransactionImpl transaction) {
|
||||
if ( transaction == currentTransaction ) {
|
||||
currentTransaction = null;
|
||||
if ( transaction == currentTransaction.get() ) {
|
||||
currentTransaction.set(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,6 @@ import junit.framework.Test;
|
|||
|
||||
import org.hibernate.test.util.SelectedClassnameClassLoader;
|
||||
import org.hibernate.test.util.SelectedClassnameClassLoaderTestSetup;
|
||||
import org.jboss.cache.Cache;
|
||||
import org.jboss.cache.config.Configuration;
|
||||
|
||||
/**
|
||||
* A TestSetup that uses SelectedClassnameClassLoader to ensure that
|
||||
|
@ -55,36 +53,34 @@ public class IsolatedCacheTestSetup extends SelectedClassnameClassLoaderTestSetu
|
|||
protected void setUp() throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
|
||||
|
||||
// At this point the TCCL cannot see the isolatedClasses
|
||||
// We want the caches to use this CL as their default classloader
|
||||
|
||||
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
org.jgroups.ChannelFactory cf = new org.jgroups.JChannelFactory();
|
||||
cf.setMultiplexerConfig(DEF_JGROUPS_RESOURCE);
|
||||
|
||||
org.jboss.cache.CacheManagerImpl cm = new org.jboss.cache.CacheManagerImpl(DEF_CACHE_FACTORY_RESOURCE, cf);
|
||||
// Use a CacheManager that will inject the desired defaultClassLoader into our caches
|
||||
CustomClassLoaderCacheManager cm = new CustomClassLoaderCacheManager(DEF_CACHE_FACTORY_RESOURCE, cf, tccl);
|
||||
cm.start();
|
||||
TestCacheInstanceManager.addTestCacheManager(DualNodeTestUtil.LOCAL, cm);
|
||||
|
||||
// Inject the desired defaultClassLoader into our caches
|
||||
Configuration cfg = cm.getConfigurationRegistry().getConfiguration(cacheConfig);
|
||||
Cache cache = new CustomClassLoaderCacheFactory(tccl).createCache(cfg, false);
|
||||
cache.getConfiguration().getRuntimeConfig().setMuxChannelFactory(cm.getChannelFactory());
|
||||
cm.registerCache(cache, cacheConfig);
|
||||
cm.getCache(cacheConfig, true);
|
||||
|
||||
// Repeat for the "remote" cache
|
||||
|
||||
cf = new org.jgroups.JChannelFactory();
|
||||
cf.setMultiplexerConfig(DEF_JGROUPS_RESOURCE);
|
||||
|
||||
cm = new org.jboss.cache.CacheManagerImpl(DEF_CACHE_FACTORY_RESOURCE, cf);
|
||||
cm = new CustomClassLoaderCacheManager(DEF_CACHE_FACTORY_RESOURCE, cf, tccl);
|
||||
cm.start();
|
||||
TestCacheInstanceManager.addTestCacheManager(DualNodeTestUtil.REMOTE, cm);
|
||||
|
||||
cfg = cm.getConfigurationRegistry().getConfiguration(cacheConfig);
|
||||
cache = new CustomClassLoaderCacheFactory(tccl).createCache(cfg, false);
|
||||
cache.getConfiguration().getRuntimeConfig().setMuxChannelFactory(cm.getChannelFactory());
|
||||
cm.registerCache(cache, cacheConfig);
|
||||
cm.getCache(cacheConfig, true);
|
||||
|
||||
// Now make the isolatedClasses visible
|
||||
// Now make the isolatedClasses visible to the test driver itself
|
||||
SelectedClassnameClassLoader visible = new SelectedClassnameClassLoader(isolatedClasses, null, null, tccl);
|
||||
Thread.currentThread().setContextClassLoader(visible);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue