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; | package org.apache.antlib.core; | ||||
| import java.net.URL; | |||||
| import java.net.URLClassLoader; | |||||
| import org.apache.myrmidon.api.TaskContext; | import org.apache.myrmidon.api.TaskContext; | ||||
| import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
| import org.apache.myrmidon.framework.conditions.Condition; | import org.apache.myrmidon.framework.conditions.Condition; | ||||
| @@ -27,11 +25,18 @@ public abstract class AbstractAvailableCondition | |||||
| { | { | ||||
| private Path m_classpath = new Path(); | private Path m_classpath = new Path(); | ||||
| /** | |||||
| * Adds a classpath element. | |||||
| */ | |||||
| public void setClasspath( final Path classpath ) | |||||
| { | |||||
| m_classpath.add( classpath ); | |||||
| } | |||||
| /** | /** | ||||
| * Adds a classpath element. | * Adds a classpath element. | ||||
| */ | */ | ||||
| public void addClasspath( final Path classpath ) | public void addClasspath( final Path classpath ) | ||||
| throws TaskException | |||||
| { | { | ||||
| m_classpath.add( classpath ); | m_classpath.add( classpath ); | ||||
| } | } | ||||
| @@ -41,19 +46,6 @@ public abstract class AbstractAvailableCondition | |||||
| */ | */ | ||||
| protected ClassLoader buildClassLoader( final TaskContext context ) throws TaskException | 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.File; | ||||
| import java.io.FileReader; | import java.io.FileReader; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.net.URL; | |||||
| import java.net.URLClassLoader; | |||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||
| import java.util.Enumeration; | import java.util.Enumeration; | ||||
| import java.util.Hashtable; | import java.util.Hashtable; | ||||
| import org.apache.myrmidon.api.AbstractTask; | import org.apache.myrmidon.api.AbstractTask; | ||||
| import org.apache.myrmidon.api.TaskException; | 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.DirectoryScanner; | ||||
| import org.apache.tools.todo.types.FileSet; | 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.PathUtil; | ||||
| import org.apache.tools.todo.types.ScannerUtil; | import org.apache.tools.todo.types.ScannerUtil; | ||||
| import org.xml.sax.EntityResolver; | import org.xml.sax.EntityResolver; | ||||
| @@ -76,7 +74,7 @@ public class XMLValidateTask | |||||
| * The list of configured DTD locations | * The list of configured DTD locations | ||||
| */ | */ | ||||
| private ArrayList m_dtdLocations = new ArrayList();// sets of file to be validated | 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) | * 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) | * 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 | 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 | * @see #setClasspath | ||||
| */ | */ | ||||
| public Path createClasspath() | |||||
| public void addClasspath( final Path path ) | |||||
| throws TaskException | 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 | // load the parser class | ||||
| // with JAXP, we would use a SAXParser factory | // 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 | // then check it implements XMLReader | ||||
| if( XMLReader.class.isAssignableFrom( readerClass ) ) | if( XMLReader.class.isAssignableFrom( readerClass ) ) | ||||
| @@ -16,6 +16,7 @@ import java.util.ArrayList; | |||||
| import java.util.Arrays; | import java.util.Arrays; | ||||
| import java.util.HashMap; | import java.util.HashMap; | ||||
| import java.util.Map; | import java.util.Map; | ||||
| import java.util.List; | |||||
| import java.util.jar.Manifest; | import java.util.jar.Manifest; | ||||
| import org.apache.avalon.excalibur.extension.Extension; | import org.apache.avalon.excalibur.extension.Extension; | ||||
| import org.apache.avalon.excalibur.extension.OptionalPackage; | 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.ServiceManager; | ||||
| import org.apache.avalon.framework.service.Serviceable; | import org.apache.avalon.framework.service.Serviceable; | ||||
| import org.apache.myrmidon.interfaces.classloader.ClassLoaderManager; | 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.deployer.DeploymentException; | ||||
| import org.apache.myrmidon.interfaces.extensions.ExtensionManager; | 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> | * @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 final Map m_fileDeployers = new HashMap(); | ||||
| private PackageManager m_packageManager; | private PackageManager m_packageManager; | ||||
| private ClassLoader m_baseClassLoader; | |||||
| private ClassLoader m_commonClassLoader; | |||||
| public void initialize() throws Exception | 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 | * Sets the ClassLoader to use as the parent for all classloaders | ||||
| * created by this ClassLoader manager. | * 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. | * 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 | 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 | // Locate cached classloader, creating it if necessary | ||||
| URLClassLoader classLoader = (URLClassLoader)m_fileDeployers.get( canonFile ); | |||||
| ClassLoader classLoader = (ClassLoader)m_fileDeployers.get( canonFiles ); | |||||
| if( classLoader == null ) | 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; | 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. | * 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 | 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; | return urls; | ||||
| } | } | ||||
| @@ -129,13 +170,13 @@ public class DefaultClassLoaderManager | |||||
| * Retrieve the files for the optional packages required by | * Retrieve the files for the optional packages required by | ||||
| * the specified typeLibrary jar. | * 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 | 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 JarURLConnection connection = (JarURLConnection)url.openConnection(); | ||||
| final Manifest manifest = connection.getManifest(); | final Manifest manifest = connection.getManifest(); | ||||
| final Extension[] available = Extension.getAvailable( manifest ); | final Extension[] available = Extension.getAvailable( manifest ); | ||||
| @@ -166,9 +207,12 @@ public class DefaultClassLoaderManager | |||||
| throw new Exception( message ); | 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} | 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} | required-extensions.notice=The list of required extensions for type library includes; {0} | ||||
| unsatisfied.extensions.error=Missing {0} extensions for type library. | 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.io.File; | ||||
| import java.lang.reflect.InvocationTargetException; | import java.lang.reflect.InvocationTargetException; | ||||
| import java.lang.reflect.Method; | import java.lang.reflect.Method; | ||||
| import java.net.URL; | |||||
| import java.net.URLClassLoader; | |||||
| import org.apache.aut.nativelib.Os; | 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.TaskContext; | ||||
| import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
| import org.apache.myrmidon.framework.Execute; | 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.Commandline; | ||||
| import org.apache.tools.todo.types.EnvironmentData; | 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.PathUtil; | ||||
| import org.apache.tools.todo.types.SysProperties; | import org.apache.tools.todo.types.SysProperties; | ||||
| import org.apache.tools.todo.util.FileUtils; | 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 | * A utility class that takes care of executing a Java application. This | ||||
| @@ -236,16 +234,8 @@ public class ExecuteJava | |||||
| final Class target; | final Class target; | ||||
| try | 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 ) | 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; | package org.apache.myrmidon.interfaces.classloader; | ||||
| import java.io.File; | import java.io.File; | ||||
| import org.apache.myrmidon.interfaces.deployer.DeploymentException; | |||||
| /** | /** | ||||
| * Manages a classloader hierarchy. | * Manages a classloader hierarchy. | ||||
| @@ -20,7 +19,21 @@ public interface ClassLoaderManager | |||||
| String ROLE = ClassLoaderManager.class.getName(); | 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 ); | components.add( component ); | ||||
| final DefaultClassLoaderManager classLoaderMgr = new DefaultClassLoaderManager(); | final DefaultClassLoaderManager classLoaderMgr = new DefaultClassLoaderManager(); | ||||
| classLoaderMgr.setBaseClassLoader( getClass().getClassLoader() ); | |||||
| classLoaderMgr.setCommonClassLoader( getClass().getClassLoader() ); | |||||
| m_serviceManager.put( ClassLoaderManager.ROLE, classLoaderMgr ); | m_serviceManager.put( ClassLoaderManager.ROLE, classLoaderMgr ); | ||||
| components.add( classLoaderMgr ); | components.add( classLoaderMgr ); | ||||
| @@ -10,8 +10,6 @@ package org.apache.tools.todo.taskdefs; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.io.InputStream; | import java.io.InputStream; | ||||
| import java.net.URL; | |||||
| import java.net.URLClassLoader; | |||||
| import java.util.Iterator; | import java.util.Iterator; | ||||
| import java.util.Properties; | import java.util.Properties; | ||||
| import org.apache.myrmidon.api.AbstractTask; | import org.apache.myrmidon.api.AbstractTask; | ||||
| @@ -30,23 +28,16 @@ import org.apache.tools.todo.types.PathUtil; | |||||
| public class Property | public class Property | ||||
| extends AbstractTask | extends AbstractTask | ||||
| { | { | ||||
| private Path m_classpath; | |||||
| private Path m_classpath = new Path(); | |||||
| private String m_name; | private String m_name; | ||||
| private String m_resource; | private String m_resource; | ||||
| private String m_value; | private String m_value; | ||||
| public void addClasspath( Path classpath ) | |||||
| public void addClasspath( final Path classpath ) | |||||
| throws TaskException | throws TaskException | ||||
| { | { | ||||
| if( m_classpath == null ) | |||||
| { | |||||
| m_classpath = classpath; | |||||
| } | |||||
| else | |||||
| { | |||||
| m_classpath.add( classpath ); | |||||
| } | |||||
| m_classpath.add( classpath ); | |||||
| } | } | ||||
| public void setLocation( File location ) | public void setLocation( File location ) | ||||
| @@ -129,17 +120,7 @@ public class Property | |||||
| getContext().debug( "Resource Loading " + name ); | getContext().debug( "Resource Loading " + name ); | ||||
| try | 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 ); | final InputStream is = classLoader.getResourceAsStream( name ); | ||||
| if( is != null ) | if( is != null ) | ||||
| @@ -18,8 +18,6 @@ import java.io.InputStreamReader; | |||||
| import java.io.PrintStream; | import java.io.PrintStream; | ||||
| import java.io.Reader; | import java.io.Reader; | ||||
| import java.io.StringReader; | import java.io.StringReader; | ||||
| import java.net.URL; | |||||
| import java.net.URLClassLoader; | |||||
| import java.sql.Connection; | import java.sql.Connection; | ||||
| import java.sql.DatabaseMetaData; | import java.sql.DatabaseMetaData; | ||||
| import java.sql.Driver; | import java.sql.Driver; | ||||
| @@ -34,10 +32,10 @@ import java.util.Properties; | |||||
| import java.util.StringTokenizer; | import java.util.StringTokenizer; | ||||
| import org.apache.myrmidon.api.AbstractTask; | import org.apache.myrmidon.api.AbstractTask; | ||||
| import org.apache.myrmidon.api.TaskException; | 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.DirectoryScanner; | ||||
| import org.apache.tools.todo.types.EnumeratedAttribute; | import org.apache.tools.todo.types.EnumeratedAttribute; | ||||
| import org.apache.tools.todo.types.FileSet; | 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.PathUtil; | ||||
| import org.apache.tools.todo.types.ScannerUtil; | import org.apache.tools.todo.types.ScannerUtil; | ||||
| @@ -152,7 +150,7 @@ public class SQLExec | |||||
| */ | */ | ||||
| private String encoding; | private String encoding; | ||||
| private Path classpath; | |||||
| private Path classpath = new Path(); | |||||
| /** | /** | ||||
| * Set the autocommit flag for the DB connection. | * Set the autocommit flag for the DB connection. | ||||
| @@ -169,17 +167,10 @@ public class SQLExec | |||||
| * | * | ||||
| * @param classpath The new Classpath value | * @param classpath The new Classpath value | ||||
| */ | */ | ||||
| public void addClasspath( Path classpath ) | |||||
| public void addClasspath( final Path classpath ) | |||||
| throws TaskException | 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 | // Load the driver using the | ||||
| try | 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(); | driverInstance = (Driver)dc.newInstance(); | ||||
| } | } | ||||
| catch( ClassNotFoundException e ) | catch( ClassNotFoundException e ) | ||||
| @@ -11,7 +11,6 @@ import java.io.File; | |||||
| import java.io.FileOutputStream; | import java.io.FileOutputStream; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.net.URL; | import java.net.URL; | ||||
| import java.net.URLClassLoader; | |||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||
| import java.util.Iterator; | import java.util.Iterator; | ||||
| import java.util.Properties; | import java.util.Properties; | ||||
| @@ -19,13 +18,13 @@ import java.util.Random; | |||||
| import org.apache.myrmidon.api.AbstractTask; | import org.apache.myrmidon.api.AbstractTask; | ||||
| import org.apache.myrmidon.api.TaskContext; | import org.apache.myrmidon.api.TaskContext; | ||||
| import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
| import org.apache.myrmidon.framework.file.Path; | |||||
| import org.apache.myrmidon.framework.java.ExecuteJava; | import org.apache.myrmidon.framework.java.ExecuteJava; | ||||
| import org.apache.tools.todo.types.Argument; | import org.apache.tools.todo.types.Argument; | ||||
| import org.apache.tools.todo.types.Commandline; | import org.apache.tools.todo.types.Commandline; | ||||
| import org.apache.tools.todo.types.EnumeratedAttribute; | import org.apache.tools.todo.types.EnumeratedAttribute; | ||||
| import org.apache.tools.todo.types.EnvironmentData; | import org.apache.tools.todo.types.EnvironmentData; | ||||
| import org.apache.tools.todo.types.EnvironmentVariable; | 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.PathUtil; | ||||
| import org.apache.tools.todo.types.SysProperties; | import org.apache.tools.todo.types.SysProperties; | ||||
| @@ -641,12 +640,8 @@ public class JUnitTask extends AbstractTask | |||||
| try | try | ||||
| { | { | ||||
| getContext().debug( "Using System properties " + System.getProperties() ); | 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, | runner = new JUnitTestRunner( test, | ||||
| test.getHaltonerror(), | test.getHaltonerror(), | ||||
| test.getFiltertrace(), | test.getFiltertrace(), | ||||
| @@ -9,16 +9,14 @@ package org.apache.tools.todo.taskdefs.rmic; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.net.URL; | |||||
| import java.net.URLClassLoader; | |||||
| import java.rmi.Remote; | import java.rmi.Remote; | ||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||
| import org.apache.avalon.excalibur.io.FileUtil; | import org.apache.avalon.excalibur.io.FileUtil; | ||||
| import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
| import org.apache.myrmidon.framework.FileNameMapper; | 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.taskdefs.MatchingTask; | ||||
| import org.apache.tools.todo.types.DirectoryScanner; | 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.PathUtil; | ||||
| import org.apache.tools.todo.types.SourceFileScanner; | import org.apache.tools.todo.types.SourceFileScanner; | ||||
| @@ -485,8 +483,7 @@ public class Rmic extends MatchingTask | |||||
| adapter.setRmic( this ); | adapter.setRmic( this ); | ||||
| Path classpath = adapter.getClasspath(); | 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 | // scan base dirs to build up compile lists only if a | ||||
| // specific classname is not given | // specific classname is not given | ||||
| @@ -14,6 +14,9 @@ import java.util.Locale; | |||||
| import org.apache.myrmidon.api.TaskContext; | import org.apache.myrmidon.api.TaskContext; | ||||
| import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
| import org.apache.myrmidon.framework.file.Path; | 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; | import org.apache.aut.nativelib.Os; | ||||
| /** | /** | ||||
| @@ -25,7 +28,7 @@ import org.apache.aut.nativelib.Os; | |||||
| public class PathUtil | public class PathUtil | ||||
| { | { | ||||
| /** | /** | ||||
| * Formats a Path into its native representation. | |||||
| * Formats a path into its native representation. | |||||
| */ | */ | ||||
| public static String formatPath( final String[] path ) | 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 | throws TaskException | ||||
| { | { | ||||
| final String[] list = path.listFiles( context ); | 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 | throws TaskException | ||||
| { | { | ||||
| try | 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 ) | public static void addJavaRuntime( final Path path ) | ||||
| throws TaskException | throws TaskException | ||||
| @@ -129,7 +188,9 @@ public class PathUtil | |||||
| /** | /** | ||||
| * Adds the contents of a set of directories to a path. | * 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 | throws TaskException | ||||
| { | { | ||||
| final String[] dirs = extDirs.listFiles( context ); | final String[] dirs = extDirs.listFiles( context ); | ||||