From a816a71d9e2587a83890f499dd2cabb7c6e02889 Mon Sep 17 00:00:00 2001 From: adammurdoch Date: Wed, 27 Mar 2002 07:04:17 +0000 Subject: [PATCH] * Added ClassLoaderManager.createClassLoader( File[] ), to create a ClassLoader from a class-path. * Moved responsibility for creation of ClassLoaders out of the tasks, and into the ClassLoaderManager, which caches them, and resolves extension dependencies. * Added PathUtil.createClassLoader() convenience method to create a ClassLoader from a Path. * Changed the PathUtil methods to use the more general FileList, rather than Path. * Added 'classpath' attribute to the <*-available> conditions. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272047 13f79535-47bb-0310-9956-ffa450edef68 --- .../core/AbstractAvailableCondition.java | 26 ++-- .../apache/antlib/xml/XMLValidateTask.java | 41 ++---- .../DefaultClassLoaderManager.java | 118 ++++++++++++------ .../classloader/Resources.properties | 2 +- .../myrmidon/framework/java/ExecuteJava.java | 20 +-- .../classloader/ClassLoaderException.java | 41 ++++++ .../classloader/ClassLoaderManager.java | 19 ++- .../components/AbstractComponentTest.java | 2 +- .../apache/tools/todo/taskdefs/Property.java | 27 +--- .../apache/tools/todo/taskdefs/SQLExec.java | 33 +---- .../tools/todo/taskdefs/junit/JUnitTask.java | 11 +- .../apache/tools/todo/taskdefs/rmic/Rmic.java | 7 +- .../org/apache/tools/todo/types/PathUtil.java | 75 +++++++++-- 13 files changed, 245 insertions(+), 177 deletions(-) create mode 100644 proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/classloader/ClassLoaderException.java diff --git a/proposal/myrmidon/src/java/org/apache/antlib/core/AbstractAvailableCondition.java b/proposal/myrmidon/src/java/org/apache/antlib/core/AbstractAvailableCondition.java index 96d61eaf9..e7b0fb860 100644 --- a/proposal/myrmidon/src/java/org/apache/antlib/core/AbstractAvailableCondition.java +++ b/proposal/myrmidon/src/java/org/apache/antlib/core/AbstractAvailableCondition.java @@ -7,8 +7,6 @@ */ package org.apache.antlib.core; -import java.net.URL; -import java.net.URLClassLoader; import org.apache.myrmidon.api.TaskContext; import org.apache.myrmidon.api.TaskException; import org.apache.myrmidon.framework.conditions.Condition; @@ -27,11 +25,18 @@ public abstract class AbstractAvailableCondition { private Path m_classpath = new Path(); + /** + * Adds a classpath element. + */ + public void setClasspath( final Path classpath ) + { + m_classpath.add( classpath ); + } + /** * Adds a classpath element. */ public void addClasspath( final Path classpath ) - throws TaskException { m_classpath.add( classpath ); } @@ -41,19 +46,6 @@ public abstract class AbstractAvailableCondition */ protected ClassLoader buildClassLoader( final TaskContext context ) throws TaskException { - final URL[] urls = PathUtil.toURLs( m_classpath, context ); - final ClassLoader classLoader; - if( urls.length > 0 ) - { - classLoader = new URLClassLoader( urls ); - } - else - { - // TODO - using system classloader is kinda useless now, because - // the system classpath contains almost nothing. Should be using - // the 'common' classloader instead - classLoader = ClassLoader.getSystemClassLoader(); - } - return classLoader; + return PathUtil.createClassLoader( m_classpath, context ); } } diff --git a/proposal/myrmidon/src/java/org/apache/antlib/xml/XMLValidateTask.java b/proposal/myrmidon/src/java/org/apache/antlib/xml/XMLValidateTask.java index 291ce3c33..fd7697928 100644 --- a/proposal/myrmidon/src/java/org/apache/antlib/xml/XMLValidateTask.java +++ b/proposal/myrmidon/src/java/org/apache/antlib/xml/XMLValidateTask.java @@ -10,16 +10,14 @@ package org.apache.antlib.xml; import java.io.File; import java.io.FileReader; import java.io.IOException; -import java.net.URL; -import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import org.apache.myrmidon.api.AbstractTask; import org.apache.myrmidon.api.TaskException; +import org.apache.myrmidon.framework.file.Path; import org.apache.tools.todo.types.DirectoryScanner; import org.apache.tools.todo.types.FileSet; -import org.apache.myrmidon.framework.file.Path; import org.apache.tools.todo.types.PathUtil; import org.apache.tools.todo.types.ScannerUtil; import org.xml.sax.EntityResolver; @@ -76,7 +74,7 @@ public class XMLValidateTask * The list of configured DTD locations */ private ArrayList m_dtdLocations = new ArrayList();// sets of file to be validated - private Path m_classpath; + private Path m_classpath = new Path(); /** * Specify the class name of the SAX parser to be used. (optional) @@ -100,17 +98,10 @@ public class XMLValidateTask /** * Specify the classpath to be searched to load the parser (optional) */ - public void setClasspath( final Path classpath ) + public void setClasspath( final String classpath ) throws TaskException { - if( m_classpath == null ) - { - m_classpath = classpath; - } - else - { - m_classpath.add( classpath ); - } + m_classpath.add( classpath ); } /** @@ -161,17 +152,10 @@ public class XMLValidateTask /** * @see #setClasspath */ - public Path createClasspath() + public void addClasspath( final Path path ) throws TaskException { - if( m_classpath == null ) - { - m_classpath = new Path(); - } - Path path1 = m_classpath; - final Path path = new Path(); - path1.add( path ); - return path; + m_classpath.add( path ); } /** @@ -327,17 +311,8 @@ public class XMLValidateTask { // load the parser class // with JAXP, we would use a SAXParser factory - Class readerClass = null; - if( m_classpath != null ) - { - final URL[] urls = PathUtil.toURLs( m_classpath, getContext() ); - final ClassLoader classLoader = new URLClassLoader( urls ); - readerClass = classLoader.loadClass( m_readerClassName ); - } - else - { - readerClass = Class.forName( m_readerClassName ); - } + final ClassLoader classLoader = PathUtil.createClassLoader( m_classpath, getContext() ); + final Class readerClass = classLoader.loadClass( m_readerClassName ); // then check it implements XMLReader if( XMLReader.class.isAssignableFrom( readerClass ) ) diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/classloader/DefaultClassLoaderManager.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/classloader/DefaultClassLoaderManager.java index c9307a6b7..d9587aaa9 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/classloader/DefaultClassLoaderManager.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/classloader/DefaultClassLoaderManager.java @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.List; import java.util.jar.Manifest; import org.apache.avalon.excalibur.extension.Extension; import org.apache.avalon.excalibur.extension.OptionalPackage; @@ -28,11 +29,13 @@ import org.apache.avalon.framework.service.ServiceException; import org.apache.avalon.framework.service.ServiceManager; import org.apache.avalon.framework.service.Serviceable; import org.apache.myrmidon.interfaces.classloader.ClassLoaderManager; +import org.apache.myrmidon.interfaces.classloader.ClassLoaderException; import org.apache.myrmidon.interfaces.deployer.DeploymentException; import org.apache.myrmidon.interfaces.extensions.ExtensionManager; +import org.apache.tools.todo.types.PathUtil; /** - * A default implementation of a classloader manager. + * A default implementation of a ClassLoader manager. * * @author Adam Murdoch */ @@ -49,79 +52,117 @@ public class DefaultClassLoaderManager private final Map m_fileDeployers = new HashMap(); private PackageManager m_packageManager; - private ClassLoader m_baseClassLoader; + private ClassLoader m_commonClassLoader; public void initialize() throws Exception { - if( null == m_baseClassLoader ) + if( null == m_commonClassLoader ) { - m_baseClassLoader = Thread.currentThread().getContextClassLoader(); + m_commonClassLoader = Thread.currentThread().getContextClassLoader(); } } + /** + * Retrieve relevent services needed to deploy. + */ + public void service( final ServiceManager serviceManager ) + throws ServiceException + { + final ExtensionManager extensionManager = + (ExtensionManager)serviceManager.lookup( ExtensionManager.ROLE ); + m_packageManager = new PackageManager( extensionManager ); + } + /** * Sets the ClassLoader to use as the parent for all classloaders * created by this ClassLoader manager. */ - public void setBaseClassLoader( final ClassLoader classLoader ) + public void setCommonClassLoader( final ClassLoader classLoader ) { - m_baseClassLoader = classLoader; + m_commonClassLoader = classLoader; } /** - * Retrieve relevent services needed to deploy. + * Returns the common ClassLoader. This is the parent of all classloaders + * built by this ClassLoaderManager. */ - public void service( final ServiceManager serviceManager ) - throws ServiceException + public ClassLoader getCommonClassLoader() { - final ExtensionManager extensionManager = - (ExtensionManager)serviceManager.lookup( ExtensionManager.ROLE ); - m_packageManager = new PackageManager( extensionManager ); + return m_commonClassLoader; } /** * Creates a class loader for a Jar file. */ - public ClassLoader createClassLoader( File file ) throws DeploymentException + public ClassLoader createClassLoader( final File file ) throws ClassLoaderException + { + return createClassLoader( new File[] { file } ); + } + + /** + * Creates a class loader for a set of Jar files. + */ + public ClassLoader createClassLoader( final File[] files ) throws ClassLoaderException { try { - final File canonFile = file.getCanonicalFile(); + // Build a list of canonical file names + final ArrayList canonFiles = new ArrayList( files.length ); + for( int i = 0; i < files.length; i++ ) + { + canonFiles.add( files[ i ].getCanonicalFile() ); + } // Locate cached classloader, creating it if necessary - URLClassLoader classLoader = (URLClassLoader)m_fileDeployers.get( canonFile ); + ClassLoader classLoader = (ClassLoader)m_fileDeployers.get( canonFiles ); if( classLoader == null ) { - checkFile( canonFile ); - final File[] extensions = getOptionalPackagesFor( canonFile ); - final URL[] urls = buildClasspath( canonFile, extensions ); - classLoader = new URLClassLoader( urls, m_baseClassLoader ); - m_fileDeployers.put( canonFile, classLoader ); + classLoader = buildClassLoader( canonFiles ); + m_fileDeployers.put( canonFiles, classLoader ); } return classLoader; } - catch( Exception e ) + catch( final Exception e ) { - final String message = REZ.getString( "create-classloader-for-file.error", file ); - throw new DeploymentException( message ); + final String fileNames = PathUtil.formatPath( files ); + final String message = REZ.getString( "create-classloader-for-file.error", fileNames ); + throw new ClassLoaderException( message, e ); } } + /** + * Builds the classloader for a set of files. + */ + private ClassLoader buildClassLoader( final ArrayList files ) + throws Exception + { + final ArrayList allFiles = new ArrayList( files ); + final int count = files.size(); + for( int i = 0; i < count; i++ ) + { + final File file = (File)files.get(i ); + checkFile( file ); + getOptionalPackagesFor( file, allFiles ); + } + + final URL[] urls = buildClasspath( allFiles ); + return new URLClassLoader( urls, m_commonClassLoader ); + } + /** * Assembles a set of files into a URL classpath. */ - private URL[] buildClasspath( final File file, final File[] dependencies ) + private URL[] buildClasspath( final ArrayList files ) throws MalformedURLException { - final URL[] urls = new URL[ dependencies.length + 1 ]; - - for( int i = 0; i < dependencies.length; i++ ) + final URL[] urls = new URL[ files.size() + 1 ]; + final int count = files.size(); + for( int i = 0; i < count; i++ ) { - urls[ i ] = dependencies[ i ].toURL(); + final File file = (File)files.get( i ); + urls[ i ] = file.toURL(); } - urls[ dependencies.length ] = file.toURL(); - return urls; } @@ -129,13 +170,13 @@ public class DefaultClassLoaderManager * Retrieve the files for the optional packages required by * the specified typeLibrary jar. * - * @param typeLibrary the typeLibrary - * @return the files that need to be added to ClassLoader + * @param jarFile the typeLibrary + * @param packages used to return the files that need to be added to ClassLoader. */ - private File[] getOptionalPackagesFor( final File typeLibrary ) + private void getOptionalPackagesFor( final File jarFile, final List packages ) throws Exception { - final URL url = new URL( "jar:" + typeLibrary.getCanonicalFile().toURL() + "!/" ); + final URL url = new URL( "jar:" + jarFile.getCanonicalFile().toURL() + "!/" ); final JarURLConnection connection = (JarURLConnection)url.openConnection(); final Manifest manifest = connection.getManifest(); final Extension[] available = Extension.getAvailable( manifest ); @@ -166,9 +207,12 @@ public class DefaultClassLoaderManager throw new Exception( message ); } - final OptionalPackage[] packages = - (OptionalPackage[])dependencies.toArray( new OptionalPackage[ 0 ] ); - return OptionalPackage.toFiles( packages ); + final int count = dependencies.size(); + for( int i = 0; i < count; i++ ) + { + final OptionalPackage optionalPackage = (OptionalPackage)dependencies.get(i ); + packages.add( optionalPackage.getFile() ); + } } /** diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/classloader/Resources.properties b/proposal/myrmidon/src/java/org/apache/myrmidon/components/classloader/Resources.properties index b425cbd5a..dfefa825e 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/classloader/Resources.properties +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/classloader/Resources.properties @@ -1,4 +1,4 @@ -create-classloader-for-file.error=Could not create ClassLoader for file {0}. +create-classloader-for-file.error=Could not create ClassLoader for files: {0}. available-extensions.notice=The list of available extensions for type library includes; {0} required-extensions.notice=The list of required extensions for type library includes; {0} unsatisfied.extensions.error=Missing {0} extensions for type library. diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/java/ExecuteJava.java b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/java/ExecuteJava.java index 047f7e25a..106dd1c11 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/java/ExecuteJava.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/java/ExecuteJava.java @@ -10,20 +10,18 @@ package org.apache.myrmidon.framework.java; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; import org.apache.aut.nativelib.Os; +import org.apache.avalon.excalibur.i18n.ResourceManager; +import org.apache.avalon.excalibur.i18n.Resources; import org.apache.myrmidon.api.TaskContext; import org.apache.myrmidon.api.TaskException; import org.apache.myrmidon.framework.Execute; +import org.apache.myrmidon.framework.file.Path; import org.apache.tools.todo.types.Commandline; import org.apache.tools.todo.types.EnvironmentData; -import org.apache.myrmidon.framework.file.Path; import org.apache.tools.todo.types.PathUtil; import org.apache.tools.todo.types.SysProperties; import org.apache.tools.todo.util.FileUtils; -import org.apache.avalon.excalibur.i18n.ResourceManager; -import org.apache.avalon.excalibur.i18n.Resources; /** * A utility class that takes care of executing a Java application. This @@ -236,16 +234,8 @@ public class ExecuteJava final Class target; try { - final URL[] urls = PathUtil.toURLs( m_classPath, context ); - if( urls.length == 0 ) - { - target = Class.forName( m_className ); - } - else - { - final URLClassLoader classLoader = new URLClassLoader( urls ); - target = classLoader.loadClass( m_className ); - } + final ClassLoader classLoader = PathUtil.createClassLoader( m_classPath, context ); + target = classLoader.loadClass( m_className ); } catch( final Exception e ) { diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/classloader/ClassLoaderException.java b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/classloader/ClassLoaderException.java new file mode 100644 index 000000000..8a5216944 --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/classloader/ClassLoaderException.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.myrmidon.interfaces.classloader; + +import org.apache.myrmidon.interfaces.ComponentException; + +/** + * An exception thrown by the ClassLoaderManager. + * + * @author Adam Murdoch + * @version $Revision$ $Date$ + */ +public class ClassLoaderException + extends ComponentException +{ + /** + * Constructs a non-cascaded exception. + * + * @param message The detail message for this exception. + */ + public ClassLoaderException( final String message ) + { + super( message ); + } + + /** + * Constructs a cascaded exception. + * + * @param message The detail message for this exception. + * @param throwable the root cause of the exception + */ + public ClassLoaderException( final String message, final Throwable throwable ) + { + super( message, throwable ); + } +} diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/classloader/ClassLoaderManager.java b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/classloader/ClassLoaderManager.java index fd5780d55..79a49ba23 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/classloader/ClassLoaderManager.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/classloader/ClassLoaderManager.java @@ -8,7 +8,6 @@ package org.apache.myrmidon.interfaces.classloader; import java.io.File; -import org.apache.myrmidon.interfaces.deployer.DeploymentException; /** * Manages a classloader hierarchy. @@ -20,7 +19,21 @@ public interface ClassLoaderManager String ROLE = ClassLoaderManager.class.getName(); /** - * Builds the ClassLoader for a Jar file. + * Builds the ClassLoader for a Jar file, resolving dependencies. */ - ClassLoader createClassLoader( File jar ) throws DeploymentException; + ClassLoader createClassLoader( File jar ) throws ClassLoaderException; + + /** + * Builds the ClassLoader for a set of files, resolving dependencies. + * + * @param jars The Jar/zip files to create the classloader for. Use null + * or an empty array to use the common classloader. + */ + ClassLoader createClassLoader( File[] jars ) throws ClassLoaderException; + + /** + * Returns the common ClassLoader. This is the parent of all classloaders + * built by this ClassLoaderManager. + */ + ClassLoader getCommonClassLoader(); } diff --git a/proposal/myrmidon/src/test/org/apache/myrmidon/components/AbstractComponentTest.java b/proposal/myrmidon/src/test/org/apache/myrmidon/components/AbstractComponentTest.java index b4d8bb89c..45ea88298 100644 --- a/proposal/myrmidon/src/test/org/apache/myrmidon/components/AbstractComponentTest.java +++ b/proposal/myrmidon/src/test/org/apache/myrmidon/components/AbstractComponentTest.java @@ -94,7 +94,7 @@ public abstract class AbstractComponentTest components.add( component ); final DefaultClassLoaderManager classLoaderMgr = new DefaultClassLoaderManager(); - classLoaderMgr.setBaseClassLoader( getClass().getClassLoader() ); + classLoaderMgr.setCommonClassLoader( getClass().getClassLoader() ); m_serviceManager.put( ClassLoaderManager.ROLE, classLoaderMgr ); components.add( classLoaderMgr ); diff --git a/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Property.java b/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Property.java index c022d83b9..07c847f81 100644 --- a/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Property.java +++ b/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Property.java @@ -10,8 +10,6 @@ package org.apache.tools.todo.taskdefs; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.net.URL; -import java.net.URLClassLoader; import java.util.Iterator; import java.util.Properties; import org.apache.myrmidon.api.AbstractTask; @@ -30,23 +28,16 @@ import org.apache.tools.todo.types.PathUtil; public class Property extends AbstractTask { - private Path m_classpath; + private Path m_classpath = new Path(); private String m_name; private String m_resource; private String m_value; - public void addClasspath( Path classpath ) + public void addClasspath( final Path classpath ) throws TaskException { - if( m_classpath == null ) - { - m_classpath = classpath; - } - else - { - m_classpath.add( classpath ); - } + m_classpath.add( classpath ); } public void setLocation( File location ) @@ -129,17 +120,7 @@ public class Property getContext().debug( "Resource Loading " + name ); try { - ClassLoader classLoader = null; - - if( m_classpath != null ) - { - final URL[] urls = PathUtil.toURLs( m_classpath, getContext() ); - classLoader = new URLClassLoader( urls ); - } - else - { - classLoader = ClassLoader.getSystemClassLoader(); - } + final ClassLoader classLoader = PathUtil.createClassLoader( m_classpath, getContext() ); final InputStream is = classLoader.getResourceAsStream( name ); if( is != null ) diff --git a/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/SQLExec.java b/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/SQLExec.java index c2c84a4d4..c992a676b 100644 --- a/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/SQLExec.java +++ b/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/SQLExec.java @@ -18,8 +18,6 @@ import java.io.InputStreamReader; import java.io.PrintStream; import java.io.Reader; import java.io.StringReader; -import java.net.URL; -import java.net.URLClassLoader; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.Driver; @@ -34,10 +32,10 @@ import java.util.Properties; import java.util.StringTokenizer; import org.apache.myrmidon.api.AbstractTask; import org.apache.myrmidon.api.TaskException; +import org.apache.myrmidon.framework.file.Path; import org.apache.tools.todo.types.DirectoryScanner; import org.apache.tools.todo.types.EnumeratedAttribute; import org.apache.tools.todo.types.FileSet; -import org.apache.myrmidon.framework.file.Path; import org.apache.tools.todo.types.PathUtil; import org.apache.tools.todo.types.ScannerUtil; @@ -152,7 +150,7 @@ public class SQLExec */ private String encoding; - private Path classpath; + private Path classpath = new Path(); /** * Set the autocommit flag for the DB connection. @@ -169,17 +167,10 @@ public class SQLExec * * @param classpath The new Classpath value */ - public void addClasspath( Path classpath ) + public void addClasspath( final Path classpath ) throws TaskException { - if( this.classpath == null ) - { - this.classpath = classpath; - } - else - { - this.classpath.add( classpath ); - } + this.classpath.add( classpath ); } /** @@ -426,20 +417,8 @@ public class SQLExec // Load the driver using the try { - Class dc; - if( classpath != null ) - { - getContext().debug( "Loading " + driver + " using AntClassLoader with classpath " + classpath ); - - final URL[] urls = PathUtil.toURLs( classpath, getContext() ); - final ClassLoader classLoader = new URLClassLoader( urls ); - dc = classLoader.loadClass( driver ); - } - else - { - getContext().debug( "Loading " + driver + " using system loader." ); - dc = Class.forName( driver ); - } + final ClassLoader classLoader = PathUtil.createClassLoader( classpath, getContext() ); + final Class dc = classLoader.loadClass( driver ); driverInstance = (Driver)dc.newInstance(); } catch( ClassNotFoundException e ) diff --git a/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/JUnitTask.java b/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/JUnitTask.java index 3d3306e70..63ee44ca3 100644 --- a/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/JUnitTask.java +++ b/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/JUnitTask.java @@ -11,7 +11,6 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.URL; -import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Iterator; import java.util.Properties; @@ -19,13 +18,13 @@ import java.util.Random; import org.apache.myrmidon.api.AbstractTask; import org.apache.myrmidon.api.TaskContext; import org.apache.myrmidon.api.TaskException; +import org.apache.myrmidon.framework.file.Path; import org.apache.myrmidon.framework.java.ExecuteJava; import org.apache.tools.todo.types.Argument; import org.apache.tools.todo.types.Commandline; import org.apache.tools.todo.types.EnumeratedAttribute; import org.apache.tools.todo.types.EnvironmentData; import org.apache.tools.todo.types.EnvironmentVariable; -import org.apache.myrmidon.framework.file.Path; import org.apache.tools.todo.types.PathUtil; import org.apache.tools.todo.types.SysProperties; @@ -641,12 +640,8 @@ public class JUnitTask extends AbstractTask try { getContext().debug( "Using System properties " + System.getProperties() ); - ClassLoader classLoader = null; - final URL[] urls = PathUtil.toURLs( classPath, getContext() ); - if( urls.length > 0 ) - { - classLoader = new URLClassLoader( urls ); - } + final ClassLoader classLoader = PathUtil.createClassLoader( classPath, getContext() ); + runner = new JUnitTestRunner( test, test.getHaltonerror(), test.getFiltertrace(), diff --git a/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/rmic/Rmic.java b/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/rmic/Rmic.java index b89e0c867..a4a700074 100644 --- a/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/rmic/Rmic.java +++ b/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/rmic/Rmic.java @@ -9,16 +9,14 @@ package org.apache.tools.todo.taskdefs.rmic; import java.io.File; import java.io.IOException; -import java.net.URL; -import java.net.URLClassLoader; import java.rmi.Remote; import java.util.ArrayList; import org.apache.avalon.excalibur.io.FileUtil; import org.apache.myrmidon.api.TaskException; import org.apache.myrmidon.framework.FileNameMapper; +import org.apache.myrmidon.framework.file.Path; import org.apache.tools.todo.taskdefs.MatchingTask; import org.apache.tools.todo.types.DirectoryScanner; -import org.apache.myrmidon.framework.file.Path; import org.apache.tools.todo.types.PathUtil; import org.apache.tools.todo.types.SourceFileScanner; @@ -485,8 +483,7 @@ public class Rmic extends MatchingTask adapter.setRmic( this ); Path classpath = adapter.getClasspath(); - final URL[] urls = PathUtil.toURLs( classpath, getContext() ); - loader = new URLClassLoader( urls ); + loader = PathUtil.createClassLoader( classpath, getContext() ); // scan base dirs to build up compile lists only if a // specific classname is not given diff --git a/proposal/myrmidon/src/todo/org/apache/tools/todo/types/PathUtil.java b/proposal/myrmidon/src/todo/org/apache/tools/todo/types/PathUtil.java index 637063e4f..7e4315821 100644 --- a/proposal/myrmidon/src/todo/org/apache/tools/todo/types/PathUtil.java +++ b/proposal/myrmidon/src/todo/org/apache/tools/todo/types/PathUtil.java @@ -14,6 +14,9 @@ import java.util.Locale; import org.apache.myrmidon.api.TaskContext; import org.apache.myrmidon.api.TaskException; import org.apache.myrmidon.framework.file.Path; +import org.apache.myrmidon.framework.file.FileList; +import org.apache.myrmidon.interfaces.classloader.ClassLoaderManager; +import org.apache.myrmidon.interfaces.classloader.ClassLoaderException; import org.apache.aut.nativelib.Os; /** @@ -25,7 +28,7 @@ import org.apache.aut.nativelib.Os; public class PathUtil { /** - * Formats a Path into its native representation. + * Formats a path into its native representation. */ public static String formatPath( final String[] path ) { @@ -47,9 +50,31 @@ public class PathUtil } /** - * Formats a Path into its native representation. + * Formats a path into its native representation. */ - public static String formatPath( final Path path, final TaskContext context ) + public static String formatPath( final File[] path ) + { + // empty path return empty string + if( path.length == 0 ) + { + return ""; + } + + // path containing one or more elements + final StringBuffer result = new StringBuffer( path[ 0 ].toString() ); + for( int i = 1; i < path.length; i++ ) + { + result.append( File.pathSeparatorChar ); + result.append( path[ i ].getAbsolutePath() ); + } + + return result.toString(); + } + + /** + * Formats a path into its native representation. + */ + public static String formatPath( final FileList path, final TaskContext context ) throws TaskException { final String[] list = path.listFiles( context ); @@ -57,9 +82,24 @@ public class PathUtil } /** - * Returns an array of URLs - useful for building a ClassLoader. + * Converts a path into an array of Files. */ - public static URL[] toURLs( final Path path, final TaskContext context ) + public static File[] toFiles( final FileList path, final TaskContext context ) + throws TaskException + { + final String[] list = path.listFiles( context ); + final File[] result = new File[ list.length ]; + for( int i = 0; i < list.length; i++ ) + { + result[ i ] = new File( list[ i ] ); + } + return result; + } + + /** + * Converts a path into an array of URLs - useful for building a ClassLoader. + */ + public static URL[] toURLs( final FileList path, final TaskContext context ) throws TaskException { try @@ -83,7 +123,26 @@ public class PathUtil } /** - * Adds the JVM's runtime to a path. + * Creates a ClassLoader from a class-path. + */ + public static ClassLoader createClassLoader( final FileList classpath, + final TaskContext context ) + throws TaskException + { + final File[] files = toFiles( classpath, context ); + final ClassLoaderManager manager = (ClassLoaderManager)context.getService( ClassLoaderManager.class ); + try + { + return manager.createClassLoader( files ); + } + catch( final ClassLoaderException e ) + { + throw new TaskException( e.getMessage(), e ); + } + } + + /** + * Adds this JVM's runtime to a path. */ public static void addJavaRuntime( final Path path ) throws TaskException @@ -129,7 +188,9 @@ public class PathUtil /** * Adds the contents of a set of directories to a path. */ - public static void addExtdirs( final Path toPath, final Path extDirs, TaskContext context ) + public static void addExtdirs( final Path toPath, + final Path extDirs, + final TaskContext context ) throws TaskException { final String[] dirs = extDirs.listFiles( context );