[jboss-svn-commits] JBoss Common SVN: r2761 - in common-core/trunk/src: main/java/org/jboss/util/threadpool and 3 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Mar 27 15:59:15 EDT 2008
Author: bstansberry at jboss.com
Date: 2008-03-27 15:59:14 -0400 (Thu, 27 Mar 2008)
New Revision: 2761
Added:
common-core/trunk/src/main/java/org/jboss/util/loading/ClassLoaderSource.java
common-core/trunk/src/main/java/org/jboss/util/loading/ConstructorTCCLClassLoaderSource.java
common-core/trunk/src/main/java/org/jboss/util/loading/MyClassLoaderClassLoaderSource.java
common-core/trunk/src/test/java/org/jboss/test/util/test/loading/
common-core/trunk/src/test/java/org/jboss/test/util/test/loading/ClassLoaderSourceTestBase.java
common-core/trunk/src/test/java/org/jboss/test/util/test/loading/ConstructorTCCLClassLoaderSourceUnitTestCase.java
common-core/trunk/src/test/java/org/jboss/test/util/test/loading/MyClassLoaderClassLoaderSourceUnitTestCase.java
common-core/trunk/src/test/java/org/jboss/test/util/test/threadpool/
common-core/trunk/src/test/java/org/jboss/test/util/test/threadpool/BasicThreadPoolTCCLTestCase.java
Modified:
common-core/trunk/src/main/java/org/jboss/util/threadpool/BasicThreadPool.java
common-core/trunk/src/main/java/org/jboss/util/threadpool/BasicThreadPoolMBean.java
Log:
[JBCOMMON-41] BasicThreadPool can manage thread context classloader
Added: common-core/trunk/src/main/java/org/jboss/util/loading/ClassLoaderSource.java
===================================================================
--- common-core/trunk/src/main/java/org/jboss/util/loading/ClassLoaderSource.java (rev 0)
+++ common-core/trunk/src/main/java/org/jboss/util/loading/ClassLoaderSource.java 2008-03-27 19:59:14 UTC (rev 2761)
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, 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.
+ */
+
+package org.jboss.util.loading;
+
+/**
+ * Interface for objects that provide a reference to a classloader.
+ *
+ * @see org.jboss.util.threadpool.BasicThreadPool#setClassLoaderSource(ClassLoaderSource)
+ *
+ * @author Brian Stansberry
+ */
+public interface ClassLoaderSource
+{
+ /**
+ * Gets the classloader provided by this object.
+ *
+ * @return the classloader, or <code>null</code> if none is available
+ */
+ ClassLoader getClassLoader();
+}
Added: common-core/trunk/src/main/java/org/jboss/util/loading/ConstructorTCCLClassLoaderSource.java
===================================================================
--- common-core/trunk/src/main/java/org/jboss/util/loading/ConstructorTCCLClassLoaderSource.java (rev 0)
+++ common-core/trunk/src/main/java/org/jboss/util/loading/ConstructorTCCLClassLoaderSource.java 2008-03-27 19:59:14 UTC (rev 2761)
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, 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.
+ */
+
+package org.jboss.util.loading;
+
+import java.lang.ref.WeakReference;
+import java.security.AccessController;
+
+/**
+ * {@link ClassLoaderSource} implementation that returns the
+ * {@link Thread#getContextClassLoader() thread context classloader (TCCL)}
+ * in effect when this class' constructor is invoked.
+ *
+ * @author Brian Stansberry
+ */
+public class ConstructorTCCLClassLoaderSource implements ClassLoaderSource
+{
+ private final WeakReference classLoaderRef;
+
+ public ConstructorTCCLClassLoaderSource()
+ {
+ ContextClassLoader ccl = (ContextClassLoader) AccessController.doPrivileged(ContextClassLoader.INSTANTIATOR);
+ ClassLoader cl = ccl.getContextClassLoader();
+
+ if (cl != null)
+ classLoaderRef = new WeakReference(cl);
+ else
+ classLoaderRef = null;
+ }
+
+ public ClassLoader getClassLoader()
+ {
+ return classLoaderRef == null ? null : (ClassLoader) classLoaderRef.get();
+ }
+
+}
Added: common-core/trunk/src/main/java/org/jboss/util/loading/MyClassLoaderClassLoaderSource.java
===================================================================
--- common-core/trunk/src/main/java/org/jboss/util/loading/MyClassLoaderClassLoaderSource.java (rev 0)
+++ common-core/trunk/src/main/java/org/jboss/util/loading/MyClassLoaderClassLoaderSource.java 2008-03-27 19:59:14 UTC (rev 2761)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, 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.
+ */
+
+package org.jboss.util.loading;
+
+/**
+ * {@link ClassLoaderSource} implementation that returns the ClassLoader
+ * that loaded this class.
+ *
+ * @author Brian Stansberry
+ */
+public class MyClassLoaderClassLoaderSource implements ClassLoaderSource
+{
+
+ public ClassLoader getClassLoader()
+ {
+ return getClass().getClassLoader();
+ }
+
+}
Modified: common-core/trunk/src/main/java/org/jboss/util/threadpool/BasicThreadPool.java
===================================================================
--- common-core/trunk/src/main/java/org/jboss/util/threadpool/BasicThreadPool.java 2008-03-27 16:24:00 UTC (rev 2760)
+++ common-core/trunk/src/main/java/org/jboss/util/threadpool/BasicThreadPool.java 2008-03-27 19:59:14 UTC (rev 2761)
@@ -21,10 +21,12 @@
*/
package org.jboss.util.threadpool;
+import java.security.AccessController;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.PriorityQueue;
+import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
@@ -35,6 +37,8 @@
import org.jboss.logging.Logger;
import org.jboss.util.collection.WeakValueHashMap;
+import org.jboss.util.loading.ClassLoaderSource;
+import org.jboss.util.loading.ContextClassLoaderSwitcher;
/**
@@ -79,7 +83,12 @@
/** The thread group */
private ThreadGroup threadGroup;
+
+ /** Source for the thread contrext classloader to assign to threads */
+ private ClassLoaderSource classLoaderSource;
+ private ContextClassLoaderSwitcher classLoaderSwitcher;
+
/** The last thread number */
private AtomicInteger lastThreadNumber = new AtomicInteger(0);
@@ -130,10 +139,10 @@
queue = new LinkedBlockingQueue(1024);
- executor = new ThreadPoolExecutor(4, 4, 60, TimeUnit.SECONDS, queue);
+ executor = new RestoreTCCLThreadPoolExecutor(4, 4, 60, TimeUnit.SECONDS, queue);
executor.setThreadFactory(factory);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
-
+
poolNumber = lastPoolNumber.incrementAndGet();
setName(name);
this.threadGroup = threadGroup;
@@ -400,6 +409,37 @@
blockingMode = BlockingMode.ABORT;
}
+ public ClassLoaderSource getClassLoaderSource()
+ {
+ return classLoaderSource;
+ }
+
+ public void setClassLoaderSource(ClassLoaderSource classLoaderSource)
+ {
+ if (classLoaderSource == null)
+ {
+ this.classLoaderSource = null;
+ this.classLoaderSwitcher = null;
+ }
+ else if (classLoaderSwitcher == null)
+ {
+ try
+ {
+ this.classLoaderSwitcher = (ContextClassLoaderSwitcher) AccessController.doPrivileged(ContextClassLoaderSwitcher.INSTANTIATOR);
+ this.classLoaderSource = classLoaderSource;
+ }
+ catch (SecurityException e)
+ {
+ log.error("Cannot manage context classloader for pool threads; " +
+ "Do not have setContextClassLoader permission");
+ }
+ }
+ else
+ {
+ this.classLoaderSource = classLoaderSource;
+ }
+ }
+
public ThreadPool getInstance()
{
return this;
@@ -479,6 +519,15 @@
}
return info;
}
+
+ protected void setDefaultThreadContextClassLoader(Thread thread)
+ {
+ if (classLoaderSwitcher != null)
+ {
+ ClassLoader cl = classLoaderSource == null ? null : classLoaderSource.getClassLoader();
+ classLoaderSwitcher.setContextClassLoader(thread, cl);
+ }
+ }
// Private -------------------------------------------------------
@@ -494,10 +543,38 @@
String threadName = BasicThreadPool.this.toString() + "-" + lastThreadNumber.incrementAndGet();
Thread thread = new Thread(threadGroup, runnable, threadName);
thread.setDaemon(true);
+ BasicThreadPool.this.setDefaultThreadContextClassLoader(thread);
return thread;
}
}
+
+ private class RestoreTCCLThreadPoolExecutor extends ThreadPoolExecutor
+ {
+ public RestoreTCCLThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
+ long keepAliveTime, TimeUnit unit,
+ BlockingQueue<Runnable> workQueue)
+ {
+ super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
+ }
+ @Override
+ protected void afterExecute(Runnable r, Throwable t)
+ {
+ try
+ {
+ super.afterExecute(r, t);
+ }
+ finally
+ {
+
+ BasicThreadPool.this.setDefaultThreadContextClassLoader(Thread.currentThread());
+ }
+ }
+
+
+
+ }
+
/** An encapsulation of a task and its completion timeout
*/
private static class TimeoutInfo implements Comparable
Modified: common-core/trunk/src/main/java/org/jboss/util/threadpool/BasicThreadPoolMBean.java
===================================================================
--- common-core/trunk/src/main/java/org/jboss/util/threadpool/BasicThreadPoolMBean.java 2008-03-27 16:24:00 UTC (rev 2760)
+++ common-core/trunk/src/main/java/org/jboss/util/threadpool/BasicThreadPoolMBean.java 2008-03-27 19:59:14 UTC (rev 2761)
@@ -21,6 +21,8 @@
*/
package org.jboss.util.threadpool;
+import org.jboss.util.loading.ClassLoaderSource;
+
/**
* Management interface for the thread pool.
*
@@ -101,5 +103,33 @@
*/
void setKeepAliveTime(long time);
+ /**
+ * Gets the source of the classloader that will be set as the
+ * {@link Thread#getContextClassLoader() thread context classloader}
+ * for pool threads.
+ *
+ * @return the {@link ClassLoaderSource}. May return <code>null</code>.
+ */
+ ClassLoaderSource getClassLoaderSource();
+
+ /**
+ * Sets the source of the classloader that will be set as the
+ * {@link Thread#getContextClassLoader() thread context classloader}
+ * for pool threads. If set, whenever any new pool thread is created, it's
+ * context classloader will be set to the loader provided by this source.
+ * Further, when any thread is returned to the pool, its context classloader
+ * will be reset to the loader provided by this source.
+ * <p>
+ * If set to <code>null</code> (the default), the pool will not attempt to
+ * manage the context classloader for pool threads; instead a newly created
+ * pool thread will inherit its context classloader from whatever thread
+ * triggered the addition to the pool. A thread returned to the pool will
+ * not have its context classloader changed from whatever it was.
+ * </p>
+ *
+ * @param classLoaderSource the {@link ClassLoaderSource}. May be <code>null</code>.
+ */
+ void setClassLoaderSource(ClassLoaderSource classLoaderSource);
+
// Inner classes -------------------------------------------------
}
Added: common-core/trunk/src/test/java/org/jboss/test/util/test/loading/ClassLoaderSourceTestBase.java
===================================================================
--- common-core/trunk/src/test/java/org/jboss/test/util/test/loading/ClassLoaderSourceTestBase.java (rev 0)
+++ common-core/trunk/src/test/java/org/jboss/test/util/test/loading/ClassLoaderSourceTestBase.java 2008-03-27 19:59:14 UTC (rev 2761)
@@ -0,0 +1,125 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, 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.
+ */
+
+package org.jboss.test.util.test.loading;
+
+import org.jboss.test.BaseTestCase;
+import org.jboss.util.loading.ClassLoaderSource;
+
+/**
+ * Base class for testing {@link ClassLoaderSource} implementations.
+ *
+ * @author Brian Stansberry
+ */
+public abstract class ClassLoaderSourceTestBase extends BaseTestCase
+{
+ protected ClassLoader origCl;
+
+ /**
+ * @param name
+ */
+ public ClassLoaderSourceTestBase(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ origCl = Thread.currentThread().getContextClassLoader();
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ try
+ {
+ super.tearDown();
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader(origCl);
+ }
+ }
+
+ protected abstract ClassLoaderSource createClassLoaderSource();
+ protected abstract ClassLoader getExpectedClassLoader(ClassLoader tccl);
+
+ /**
+ * Tests that the ClassLoaderSource returns the expected classloader
+ * when the TCCL is null.
+ */
+ public void testNullTCCL()
+ {
+ checkCorrectClassLoaderSource(null);
+ }
+
+ /**
+ * Tests that the ClassLoaderSource returns the expected classloader
+ * when the TCCL is the basic one in place when this test is executed.
+ */
+ public void testOriginalTCCL()
+ {
+ checkCorrectClassLoaderSource(origCl);
+ }
+
+ /**
+ * Tests that the ClassLoaderSource returns the expected classloader
+ * when the TCCL is the CLS impl's own classloader.
+ */
+ public void testImplClassLoader()
+ {
+ checkCorrectClassLoaderSource(createClassLoaderSource().getClass().getClassLoader());
+ }
+
+ /**
+ * Tests that the ClassLoaderSource returns the expected classloader
+ * when the TCCL is a child classloader.
+ */
+ public void testDifferentTCCL()
+ {
+ checkCorrectClassLoaderSource(getExtendedClassLoader());
+ }
+
+ protected void checkCorrectClassLoaderSource(ClassLoader tccl)
+ {
+ Thread.currentThread().setContextClassLoader(tccl);
+ ClassLoaderSource cls = createClassLoaderSource();
+ assertSame("ClassLoaderSource returned expected cl", getExpectedClassLoader(tccl), cls.getClassLoader());
+ }
+
+ protected ClassLoader getExtendedClassLoader()
+ {
+ return new ExtendedClassLoader(origCl);
+ }
+
+ private class ExtendedClassLoader extends ClassLoader
+ {
+ ExtendedClassLoader(ClassLoader parent)
+ {
+ super(parent);
+ }
+ }
+
+}
Added: common-core/trunk/src/test/java/org/jboss/test/util/test/loading/ConstructorTCCLClassLoaderSourceUnitTestCase.java
===================================================================
--- common-core/trunk/src/test/java/org/jboss/test/util/test/loading/ConstructorTCCLClassLoaderSourceUnitTestCase.java (rev 0)
+++ common-core/trunk/src/test/java/org/jboss/test/util/test/loading/ConstructorTCCLClassLoaderSourceUnitTestCase.java 2008-03-27 19:59:14 UTC (rev 2761)
@@ -0,0 +1,71 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, 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.
+ */
+
+package org.jboss.test.util.test.loading;
+
+import org.jboss.util.loading.ClassLoaderSource;
+import org.jboss.util.loading.ConstructorTCCLClassLoaderSource;
+import org.jboss.util.loading.MyClassLoaderClassLoaderSource;
+
+/**
+ * Unit tests of {@link ConstructorTCCLClassLoaderSource}.
+ *
+ * @author Brian Stansberry
+ */
+public class ConstructorTCCLClassLoaderSourceUnitTestCase extends ClassLoaderSourceTestBase
+{
+
+ public ConstructorTCCLClassLoaderSourceUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ protected ClassLoaderSource createClassLoaderSource()
+ {
+ return new ConstructorTCCLClassLoaderSource();
+ }
+
+ @Override
+ protected ClassLoader getExpectedClassLoader(ClassLoader tccl)
+ {
+ return tccl;
+ }
+
+ /**
+ * Tests that the ClassLoaderSource does not prevent garbage collection of
+ * the classloader.
+ */
+ public void testGarbageCollectedClassLoader()
+ {
+ ClassLoader cl = getExtendedClassLoader();
+ Thread.currentThread().setContextClassLoader(cl);
+ ClassLoaderSource cls = createClassLoaderSource();
+ Thread.currentThread().setContextClassLoader(origCl);
+ cl = null;
+
+ System.gc();
+
+ assertNull("ClassLoader garbage collected", cls.getClassLoader());
+ }
+
+}
Added: common-core/trunk/src/test/java/org/jboss/test/util/test/loading/MyClassLoaderClassLoaderSourceUnitTestCase.java
===================================================================
--- common-core/trunk/src/test/java/org/jboss/test/util/test/loading/MyClassLoaderClassLoaderSourceUnitTestCase.java (rev 0)
+++ common-core/trunk/src/test/java/org/jboss/test/util/test/loading/MyClassLoaderClassLoaderSourceUnitTestCase.java 2008-03-27 19:59:14 UTC (rev 2761)
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, 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.
+ */
+
+package org.jboss.test.util.test.loading;
+
+import org.jboss.util.loading.ClassLoaderSource;
+import org.jboss.util.loading.MyClassLoaderClassLoaderSource;
+
+/**
+ * Unit tests of {@link MyClassLoaderClassLoaderSource}.
+ *
+ * @author Brian Stansberry
+ */
+public class MyClassLoaderClassLoaderSourceUnitTestCase extends ClassLoaderSourceTestBase
+{
+
+ public MyClassLoaderClassLoaderSourceUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ protected ClassLoaderSource createClassLoaderSource()
+ {
+ return new MyClassLoaderClassLoaderSource();
+ }
+
+ @Override
+ protected ClassLoader getExpectedClassLoader(ClassLoader tccl)
+ {
+ return MyClassLoaderClassLoaderSource.class.getClassLoader();
+ }
+
+}
Added: common-core/trunk/src/test/java/org/jboss/test/util/test/threadpool/BasicThreadPoolTCCLTestCase.java
===================================================================
--- common-core/trunk/src/test/java/org/jboss/test/util/test/threadpool/BasicThreadPoolTCCLTestCase.java (rev 0)
+++ common-core/trunk/src/test/java/org/jboss/test/util/test/threadpool/BasicThreadPoolTCCLTestCase.java 2008-03-27 19:59:14 UTC (rev 2761)
@@ -0,0 +1,174 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, 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.
+ */
+
+package org.jboss.test.util.test.threadpool;
+
+import org.jboss.test.BaseTestCase;
+import org.jboss.util.loading.ClassLoaderSource;
+import org.jboss.util.threadpool.BasicThreadPool;
+
+/**
+ * Tests thread context classloader management by BasicThreadPool.
+ *
+ * @author Brian Stansberry
+ */
+public class BasicThreadPoolTCCLTestCase extends BaseTestCase
+{
+ protected ClassLoader origCl;
+
+ /**
+ * @param name
+ */
+ public BasicThreadPoolTCCLTestCase(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ origCl = Thread.currentThread().getContextClassLoader();
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ try
+ {
+ super.tearDown();
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader(origCl);
+ }
+ }
+
+ public void testNullClassLoaderSource() throws Exception
+ {
+ ClassLoader existing = origCl == null ? getExtendedClassLoader() : origCl;
+ Thread.currentThread().setContextClassLoader(existing);
+ runClassLoaderSourceTest(null, existing);
+
+ Thread.currentThread().setContextClassLoader(null);
+ runClassLoaderSourceTest(null, null);
+ }
+
+ public void testConfiguredClassLoaderSource() throws Exception
+ {
+ ClassLoaderSource source = new TestClassLoaderSource();
+ runClassLoaderSourceTest(source, source.getClassLoader());
+ }
+
+ private void runClassLoaderSourceTest(ClassLoaderSource source, ClassLoader expected) throws Exception
+ {
+ ThreadGroup group = new ThreadGroup("Test");
+ BasicThreadPool pool = new BasicThreadPool("Test", group);
+ // Only one thread so we can use it twice to confirm
+ // it gets cleaned after the first task
+ pool.setMaximumPoolSize(1);
+ pool.setClassLoaderSource(source);
+
+ Task task = new Task();
+ pool.run(task);
+
+ // Wait for task completion
+ synchronized (task)
+ {
+ if (!task.done)
+ {
+ task.wait();
+ }
+ }
+
+// ClassLoader expected = source == null ? null : source.getClassLoader();
+ assertEquals(expected, task.incomingCl);
+
+ Task task2 = new Task();
+ pool.run(task2);
+
+ // Wait for task completion
+ synchronized (task2)
+ {
+ if (!task2.done)
+ {
+ task2.wait();
+ }
+ }
+
+ assertSame(expected, task.incomingCl);
+
+ assertEquals("Pool size limited", 1, pool.getPoolSize());
+ }
+
+ private ClassLoader getExtendedClassLoader()
+ {
+ return new ExtendedClassLoader(origCl);
+ }
+
+ private class ExtendedClassLoader extends ClassLoader
+ {
+ ExtendedClassLoader(ClassLoader parent)
+ {
+ super(parent);
+ }
+ }
+
+ private class Task implements Runnable
+ {
+ private ClassLoader incomingCl;
+ private boolean done;
+
+ public void run()
+ {
+ incomingCl = Thread.currentThread().getContextClassLoader();
+
+ // Deliberately pollute the TCCL
+ ClassLoader leakedCl = BasicThreadPoolTCCLTestCase.this.getExtendedClassLoader();
+ Thread.currentThread().setContextClassLoader(leakedCl);
+
+ // Wake up the test thread
+ synchronized (this)
+ {
+ done = true;
+ notifyAll();
+ }
+ }
+ }
+
+ private class TestClassLoaderSource implements ClassLoaderSource
+ {
+ private ClassLoader cl;
+
+ TestClassLoaderSource()
+ {
+ cl = BasicThreadPoolTCCLTestCase.this.getExtendedClassLoader();
+ }
+
+ public ClassLoader getClassLoader()
+ {
+ return cl;
+ }
+ }
+
+}
More information about the jboss-svn-commits
mailing list