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 ); | |||