[jboss-svn-commits] JBoss Common SVN: r4708 - in shrinkwrap/trunk/extension-classloader/src: test/java/org/jboss/shrinkwrap/classloader and 1 other directory.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Fri Jul 9 01:02:22 EDT 2010
Author: ALRubinger
Date: 2010-07-09 01:02:21 -0400 (Fri, 09 Jul 2010)
New Revision: 4708
Modified:
shrinkwrap/trunk/extension-classloader/src/main/java/org/jboss/shrinkwrap/classloader/ShrinkWrapClassLoader.java
shrinkwrap/trunk/extension-classloader/src/test/java/org/jboss/shrinkwrap/classloader/ShrinkWrapClassLoaderTestCase.java
Log:
[SHRINKWRAP-161] Bug fixes, test fixes, documentation for ShrinkWrapClassLoader. Still has pending TODOs before resolution.
Modified: shrinkwrap/trunk/extension-classloader/src/main/java/org/jboss/shrinkwrap/classloader/ShrinkWrapClassLoader.java
===================================================================
--- shrinkwrap/trunk/extension-classloader/src/main/java/org/jboss/shrinkwrap/classloader/ShrinkWrapClassLoader.java 2010-07-08 22:35:20 UTC (rev 4707)
+++ shrinkwrap/trunk/extension-classloader/src/main/java/org/jboss/shrinkwrap/classloader/ShrinkWrapClassLoader.java 2010-07-09 05:02:21 UTC (rev 4708)
@@ -26,6 +26,7 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
+import java.util.logging.Logger;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.vfs3.ArchiveFileSystem;
@@ -38,15 +39,40 @@
* Extension that will create a ClassLoader based on a Array of Archives
*
* @author <a href="mailto:aslak at redhat.com">Aslak Knutsen</a>
- * @version $Revision: $
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
*/
public class ShrinkWrapClassLoader extends URLClassLoader implements Closeable
{
- private Set<Closeable> vfsHandlers = new HashSet<Closeable>();
-
- private Set<ExecutorService> executorServices = new HashSet<ExecutorService>();
-
+ //-------------------------------------------------------------------------------------||
+ // Class Members ----------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
/**
+ * Logger
+ */
+ private static final Logger log = Logger.getLogger(ShrinkWrapClassLoader.class.getName());
+
+ //-------------------------------------------------------------------------------------||
+ // Instance Members -------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * All open VFS handles to close when {@link ShrinkWrapClassLoader#close()}
+ * is invoked
+ */
+ private Set<Closeable> vfsHandlesToClose = new HashSet<Closeable>();
+
+ /**
+ * {@link ExecutorService}s to shutdown when {@link ShrinkWrapClassLoader#close()}
+ * is invoked
+ */
+ private Set<ExecutorService> executorServicesToShutdown = new HashSet<ExecutorService>();
+
+ //-------------------------------------------------------------------------------------||
+ // Constructors -----------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
* Constructs a new ShrinkWrapClassLoader for the specified {@link Archive}s using the
* default delegation parent <code>ClassLoader</code>. The {@link Archive}s will
* be searched in the order specified for classes and resources after
@@ -56,15 +82,16 @@
*/
public ShrinkWrapClassLoader(final Archive<?>... archives)
{
- super(new URL[]{});
-
- if(archives == null)
+ super(new URL[]
+ {});
+
+ if (archives == null)
{
- throw new IllegalArgumentException("Archives must be specified");
+ throw new IllegalArgumentException("Archives must be specified");
}
addArchives(archives);
}
-
+
/**
* Constructs a new ShrinkWrapClassLoader for the given {@link Archive}s. The {@link Archive}s will be
* searched in the order specified for classes and resources after first
@@ -73,81 +100,83 @@
* @param parent the parent class loader for delegation
* @param archives the {@link Archive}s from which to load classes and resources
*/
- public ShrinkWrapClassLoader(ClassLoader parent, final Archive<?>... archives)
+ public ShrinkWrapClassLoader(final ClassLoader parent, final Archive<?>... archives)
{
- super(new URL[]{}, parent);
-
- if(archives == null)
+ super(new URL[]
+ {}, parent);
+
+ if (archives == null)
{
- throw new IllegalArgumentException("Archives must be specified");
+ throw new IllegalArgumentException("Archives must be specified");
}
addArchives(archives);
}
-
- protected void addArchives(Archive<?>[] archives)
+
+ private void addArchives(final Archive<?>[] archives)
{
- for(Archive<?> archive : archives)
+ for (final Archive<?> archive : archives)
{
addArchive(archive);
}
}
-
- protected void addArchive(Archive<?> archive)
+
+ private void addArchive(final Archive<?> archive)
{
// TODO: Wrap a ExecutorService in a ScheduledExecutorService
//Configuration configuration = archive.as(Configurable.class).getConfiguration();
ScheduledExecutorService executorService = null; //configuration.getExecutorService();
- if(executorService == null)
+ if (executorService == null)
{
executorService = Executors.newScheduledThreadPool(2);
// TODO: only add to 'managed' executor services if it was created here..
-
+
// add to list of resources to cleanup during close()
- executorServices.add(executorService);
+ executorServicesToShutdown.add(executorService);
}
-
+
try
{
- TempFileProvider tempFileProvider = TempFileProvider.create("shrinkwrap-classloader", executorService);
-
+ final TempFileProvider tempFileProvider = TempFileProvider.create("shrinkwrap-classloader", executorService);
+
final TempDir tempDir = tempFileProvider.createTempDir(archive.getName());
final VirtualFile virtualFile = VFS.getChild(UUID.randomUUID().toString()).getChild(archive.getName());
-
- Closeable handle = VFS.mount(virtualFile, new ArchiveFileSystem(archive, tempDir));
-
+
+ final Closeable handle = VFS.mount(virtualFile, new ArchiveFileSystem(archive, tempDir));
+
// add to list of resources to cleanup during close()
- vfsHandlers.add(handle);
-
+ vfsHandlesToClose.add(handle);
+
addURL(virtualFile.toURL());
-
+
}
- catch (Exception e)
+ catch (final IOException e)
{
throw new RuntimeException("Could not create ClassLoader from archive: " + archive.getName(), e);
}
}
- /* (non-Javadoc)
+ /**
+ * {@inheritDoc}
* @see java.io.Closeable#close()
*/
public void close() throws IOException
{
// Unmount all VFS3 mount points
- for(Closeable handle : vfsHandlers)
+ for (final Closeable handle : vfsHandlesToClose)
{
try
{
handle.close();
- }
- catch (Exception e)
+ }
+ catch (final IOException e)
{
- e.printStackTrace(); // TODO: handle exception
+ log.warning("Could not close VFS handle: " + e);
}
}
-
+
// Shutdown all created Executor Services.
- for(ExecutorService executorService : executorServices)
+ for (final ExecutorService executorService : executorServicesToShutdown)
{
executorService.shutdownNow();
}
Modified: shrinkwrap/trunk/extension-classloader/src/test/java/org/jboss/shrinkwrap/classloader/ShrinkWrapClassLoaderTestCase.java
===================================================================
--- shrinkwrap/trunk/extension-classloader/src/test/java/org/jboss/shrinkwrap/classloader/ShrinkWrapClassLoaderTestCase.java 2010-07-08 22:35:20 UTC (rev 4707)
+++ shrinkwrap/trunk/extension-classloader/src/test/java/org/jboss/shrinkwrap/classloader/ShrinkWrapClassLoaderTestCase.java 2010-07-09 05:02:21 UTC (rev 4708)
@@ -1,6 +1,6 @@
/*
* JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * Copyright 2010, 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.
*
@@ -16,67 +16,149 @@
*/
package org.jboss.shrinkwrap.classloader;
+import java.io.Closeable;
+import java.io.IOException;
import java.net.URL;
+import java.util.logging.Logger;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
-import org.jboss.shrinkwrap.api.importer.ExplodedImporter;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.junit.After;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
/**
- * ShrinkWrapClassLoaderTestCase
+ * Ensures the {@link ShrinkWrapClassLoader}
+ * is working as contracted
*
* @author <a href="mailto:aslak at redhat.com">Aslak Knutsen</a>
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
* @version $Revision: $
*/
public class ShrinkWrapClassLoaderTestCase
{
- private Archive<?> createArchive()
+ //-------------------------------------------------------------------------------------||
+ // Class Members ----------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Logger
+ */
+ private static final Logger log = Logger.getLogger(ShrinkWrapClassLoaderTestCase.class.getName());
+
+ /**
+ * Class to be accessed via a ShrinkWrap ClassLoader
+ */
+ private static final Class<?> applicationClassLoaderClass = LoadedTestClass.class;
+
+ /**
+ * Archive to be read via a {@link ShrinkWrapClassLoaderTestCase#shrinkWrapClassLoader}
+ */
+ private static final JavaArchive archive = ShrinkWrap.create(JavaArchive.class)
+ .addClass(applicationClassLoaderClass);
+
+ //-------------------------------------------------------------------------------------||
+ // Instance Members -------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * ClassLoader used to load {@link ShrinkWrapClassLoaderTestCase#applicationClassLoaderClass}
+ */
+ private ClassLoader shrinkWrapClassLoader;
+
+ //-------------------------------------------------------------------------------------||
+ // Lifecycle --------------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Creates the {@link ShrinkWrapClassLoaderTestCase#shrinkWrapClassLoader}
+ * used to load classes from an {@link Archive}. The {@link ClassLoader}
+ * will be isolated from the application classpath by specifying a
+ * null parent explicitly.
+ */
+ @Before
+ public void createClassLoader()
{
- return ShrinkWrap.create(JavaArchive.class)
- .as(ExplodedImporter.class)
- .importDirectory("target/test-classes")
- .as(JavaArchive.class);
+ shrinkWrapClassLoader = new ShrinkWrapClassLoader((ClassLoader) null, archive);
}
-
- @Test
- public void shouldBeAbleToLoadClassFromArchive() throws Exception
+
+ /**
+ * Closes resources associated with the
+ * {@link ShrinkWrapClassLoaderTestCase#shrinkWrapClassLoader}
+ */
+ @After
+ public void closeClassLoader()
{
- ShrinkWrapClassLoader archiveClassLoader = new ShrinkWrapClassLoader((ClassLoader)null, createArchive());
-
- try
+ if (shrinkWrapClassLoader instanceof Closeable)
{
- Class<?> loadedTestClass = archiveClassLoader.loadClass(
- "org.jboss.shrinkwrap.classloader.LoadedTestClass");
-
- Assert.assertNotNull(loadedTestClass);
-
- Assert.assertFalse(LoadedTestClass.class == loadedTestClass.newInstance());
- }
- finally
- {
- archiveClassLoader.close();
+ try
+ {
+ ((Closeable) shrinkWrapClassLoader).close();
+ }
+ catch (final IOException e)
+ {
+ log.warning("Could not close the " + shrinkWrapClassLoader + ": " + e);
+ }
}
}
+ //-------------------------------------------------------------------------------------||
+ // Tests ------------------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Ensures we can load a Class instance from the {@link ShrinkWrapClassLoader}
+ */
@Test
- public void shouldBeAbleToLoadResourceFromArchive() throws Exception
+ public void shouldBeAbleToLoadClassFromArchive() throws ClassNotFoundException
{
- ShrinkWrapClassLoader archiveClassLoader = new ShrinkWrapClassLoader((ClassLoader)null, createArchive());
-
- try
- {
- URL resource = archiveClassLoader.getResource(
- "org/jboss/shrinkwrap/classloader/LoadedTestClass.class");
+ // Load the test class from the CL
+ final Class<?> loadedTestClass = Class.forName(applicationClassLoaderClass.getName(), false,
+ shrinkWrapClassLoader);
+ final ClassLoader loadedTestClassClassLoader = loadedTestClass.getClassLoader();
+ log.info("Got " + loadedTestClass + " from " + loadedTestClassClassLoader);
- Assert.assertNotNull(resource);
- }
- finally
- {
- archiveClassLoader.close();
- }
+ // Assertions
+ Assert.assertNotNull("Test class could not be found via the ClassLoader", loadedTestClass);
+ Assert.assertSame("Test class should have been loaded via the archive ClassLoader", shrinkWrapClassLoader,
+ loadedTestClassClassLoader);
+ Assert.assertNotSame("Class Loaded from the CL should not be the same as the one on the appCL", loadedTestClass,
+ applicationClassLoaderClass);
+
}
+
+ /**
+ * Ensures we can load a resource by name from the {@link ShrinkWrapClassLoader}
+ */
+ @Test
+ public void shouldBeAbleToLoadResourceFromArchive()
+ {
+
+ // Load the class as a resource
+ final URL resource = shrinkWrapClassLoader.getResource(getResourceNameOfClass(applicationClassLoaderClass));
+
+ // Assertions
+ Assert.assertNotNull(resource);
+
+ }
+
+ //-------------------------------------------------------------------------------------||
+ // Internal Helper Methods ------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Obtains the resource name for a given class
+ */
+ private static String getResourceNameOfClass(final Class<?> clazz)
+ {
+ assert clazz != null : "clazz must be specified";
+ final StringBuilder sb = new StringBuilder();
+ final String className = clazz.getName().replace('.', '/');
+ sb.append(className);
+ sb.append(".class");
+ return sb.toString();
+ }
}
\ No newline at end of file
More information about the jboss-svn-commits
mailing list