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-ffa450edef68master
@@ -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 ); | |||
} | |||
} |
@@ -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 ) ) | |||
@@ -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 <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | |||
*/ | |||
@@ -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() ); | |||
} | |||
} | |||
/** | |||
@@ -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. | |||
@@ -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 ) | |||
{ | |||
@@ -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 <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | |||
* @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 ); | |||
} | |||
} |
@@ -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(); | |||
} |
@@ -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 ); | |||
@@ -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 ) | |||
@@ -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 ) | |||
@@ -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(), | |||
@@ -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 | |||
@@ -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 ); | |||