adammurdoch 02/04/03 02:58:20
Modified: proposal/myrmidon build.xml
proposal/myrmidon/docs todo.html
proposal/myrmidon/src/java/org/apache/myrmidon/components/classloader
DefaultClassLoaderManager.java Resources.properties
proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer
DefaultDeployer.java
proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor
DefaultEmbeddor.java Resources.properties
proposal/myrmidon/src/java/org/apache/myrmidon/components/extensions
DefaultExtensionManager.java
proposal/myrmidon/src/java/org/apache/myrmidon/frontends
CLIMain.java EmbeddedAnt.java Resources.properties
proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/classloader
ClassLoaderManager.java
proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/extensions
ExtensionManager.java
proposal/myrmidon/src/test/org/apache/myrmidon
AbstractMyrmidonTest.java AbstractProjectTest.java
proposal/myrmidon/src/test/org/apache/myrmidon/components
AbstractComponentTest.java
proposal/myrmidon/src/test/org/apache/myrmidon/components/embeddor/test
DefaultEmbeddorTest.java
proposal/myrmidon/src/xdocs todo.xml
Added:
proposal/myrmidon/src/java/org/apache/myrmidon/components/classloader
MultiParentURLClassLoader.java
proposal/myrmidon/src/test/org/apache/myrmidon/components/classloader/test
DefaultClassLoaderManagerTestCase.java
proposal/myrmidon/src/test/org/apache/myrmidon/components/classloader/test/libs
cycle-extension-1.mf cycle-extension-2.mf
one-dependency.mf simple-extension.mf
proposal/myrmidon/src/test/org/apache/myrmidon/components/classloader/test/libs/extn
ExtnClass.java extn.txt
proposal/myrmidon/src/test/org/apache/myrmidon/components/classloader/test/libs/shared
SharedClass.java shared.txt
proposal/myrmidon/src/test/org/apache/myrmidon/components/classloader/test/libs/unshared
UnsharedClass.java unshared.txt
Log:
ClassLoader hierarchy changes:
* Use multi-parent ClassLoaders for antlibs and extensions, so that each
extension jar is loaded by a single ClassLoader in the hierarchy. Allows
classes from extensions to be shared across dependent antlibs and
extensions.
* Changed contract of ClassLoaderManager.createClassLoader( File[] ), so that
it creates a new ClassLoader each time it is called.
* Changed ExtensionManager, so that it no longer extends PackageRepository.
* Added a few test cases for DefaultClassLoaderManager.
* Moved responsibility for checking myrmidon.home and building the various
paths,
from DefaultEmbeddor and DefaultExtensionManager to EmbeddedAnt. Use the
platform path separator for the paths, rather than the | char.
* Use EmbeddedAnt in AbstractProjectTest, rather than using an Embeddor
directly.
* AbstractComponentTest was not parameterising or initialising the test
components.
Revision Changes Path
1.102 +56 -1 jakarta-ant/proposal/myrmidon/build.xml
Index: build.xml
===================================================================
RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/build.xml,v
retrieving revision 1.101
retrieving revision 1.102
diff -u -r1.101 -r1.102
--- build.xml 2 Apr 2002 12:06:37 -0000 1.101
+++ build.xml 3 Apr 2002 10:58:18 -0000 1.102
@@ -67,6 +67,7 @@
<property name="test.dir" value="${build.dir}/test"/>
<property name="test.working.dir" value="${test.dir}/test"/>
<property name="test.classes" value="${test.dir}/classes"/>
+ <property name="test.fork" value="true"/>
<property name="constants.file"
value="org/apache/myrmidon/Constants.java"/>
@@ -544,6 +545,9 @@
<!-- Compiles and runs the unit tests -->
<target name="run-tests" depends="dist-lite" if="junit.present">
+
+ <property name="test.classloader.pkg"
value="org/apache/myrmidon/components/classloader/test/libs"/>
+
<!-- Compile the unit tests -->
<mkdir dir="${test.classes}"/>
<javac srcdir="src/test"
@@ -558,6 +562,7 @@
<exclude name="**/SmbFileSystemTestCase.java"
unless="jcifs.present"/>
<exclude name="**/FtpFileSystemTestCase.java"
unless="netcomp.present"/>
+ <exclude name="${test.classloader.pkg}/**"/>
</javac>
<!-- Prepare test files -->
@@ -602,6 +607,56 @@
<fileset dir="${test.classes}"
includes="org/apache/myrmidon/interfaces/type/test/MyType1.class"/>
</jar>
+ <!-- Prepare the class loader manager tests -->
+ <property name="test.classloader.dir"
value="${test.working.dir}/${test.classloader.pkg}/.."/>
+ <property name="test.classloader.classes"
value="${test.dir}/classloader"/>
+ <mkdir dir="${test.classloader.dir}"/>
+ <mkdir dir="${test.classloader.dir}/ext"/>
+ <mkdir dir="${test.classloader.classes}"/>
+ <javac srcdir="src/test"
+ destdir="${test.classloader.classes}"
+ debug="${debug}"
+ deprecation="${deprecation}">
+ <include name="${test.classloader.pkg}/**"/>
+ </javac>
+ <copy todir="${test.classloader.classes}">
+ <fileset dir="src/test">
+ <include name="${test.classloader.pkg}/**"/>
+ <exclude name="**/*.java"/>
+ </fileset>
+ </copy>
+ <jar jarfile="${test.classloader.dir}/common.jar">
+ <fileset dir="${test.classloader.classes}">
+ <include name="**/shared/**"/>
+ </fileset>
+ </jar>
+ <jar jarfile="${test.classloader.dir}/no-dependencies.jar">
+ <fileset dir="${test.classloader.classes}">
+ <include name="**/shared/**"/>
+ <include name="**/unshared/**"/>
+ </fileset>
+ </jar>
+ <jar jarfile="${test.classloader.dir}/one-dependency.jar"
+ manifest="src/test/${test.classloader.pkg}/one-dependency.mf">
+ <fileset dir="${test.classloader.classes}">
+ <include name="**/shared/**"/>
+ <include name="**/unshared/**"/>
+ </fileset>
+ </jar>
+ <copy file="${test.classloader.dir}/one-dependency.jar"
+ tofile="${test.classloader.dir}/one-dependency-2.jar"/>
+ <jar jarfile="${test.classloader.dir}/ext/simple-extension.jar"
+ manifest="src/test/${test.classloader.pkg}/simple-extension.mf"
>
+ <fileset dir="${test.classloader.classes}">
+ <include name="**/shared/**"/>
+ <include name="**/extn/**"/>
+ </fileset>
+ </jar>
+ <jar jarfile="${test.classloader.dir}/ext/cycle-extension-1.jar"
+
manifest="src/test/${test.classloader.pkg}/cycle-extension-1.mf" />
+ <jar jarfile="${test.classloader.dir}/ext/cycle-extension-2.jar"
+
manifest="src/test/${test.classloader.pkg}/cycle-extension-2.mf" />
+
<!-- Prepare the project tests -->
<antlib-descriptor libName="unittests"
destdir="${gen.dir}"
@@ -616,7 +671,7 @@
<!-- Run all the tests -->
<junit printsummary="on"
- fork="true" failureProperty="test.failed">
+ fork="${test.fork}" failureProperty="test.failed">
<formatter type="brief" usefile="false"/>
<classpath>
<fileset dir="${test.working.dir}/dist/bin/lib"
includes="**/*.jar"/>
1.23 +13 -11 jakarta-ant/proposal/myrmidon/docs/todo.html
Index: todo.html
===================================================================
RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/docs/todo.html,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- todo.html 1 Apr 2002 00:46:26 -0000 1.22
+++ todo.html 3 Apr 2002 10:58:18 -0000 1.23
@@ -837,23 +837,12 @@
<code><socket></code>
conditions to an antlib. Need to resolve how these will
be passed a logger.
</li>
- <li>Make the
- <code><uptodate></code> task a condition, and
move to
- an antlib.
- </li>
- <li>Split up
- <code><is-set></code> condition into is-set
and is-true conditions.
- </li>
<li>Allow the
<code><if></code> task to take any condition
implementation.
</li>
<li>Add an else block to the
<code><if></code> task.
</li>
- <li>Split the
- <code><available></code> condition into
separate conditions
- that test for the availability of a class, or a resource.
- </li>
<li>Move
<code>crimson.jar</code> to
<code>bin/lib</code> in the distribution,
@@ -863,6 +852,19 @@
<li>Add a <code>--type</code> command-line option, to
allow
the project builder to be manually selected.
</li>
+ <li>Change <code>ProjectBuilder</code>
+ and <code>Embeddor</code> to throw something more
+ specialised than Exception.
+ </li>
+ <li>Change <code>DefaultClassLoaderManager</code> to
handle
+ directories as part of a library classpath.
+ </li>
+ <li><code><condition></code> should set the
property
+ value to <code>false</code> when the condition is
false.</li>
+ <li>Split the <code><uptodate></code> condition
into
+ a condition that checks against a single target file,
+ and one which checks using a destdir/mapper.</li>
+ <li>Add a task to unset a property.</li>
<li>Unit tests.</li>
</ul>
</blockquote>
1.5 +154 -87
jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/classloader/DefaultClassLoaderManager.java
Index: DefaultClassLoaderManager.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/classloader/DefaultClassLoaderManager.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- DefaultClassLoaderManager.java 29 Mar 2002 12:56:03 -0000 1.4
+++ DefaultClassLoaderManager.java 3 Apr 2002 10:58:19 -0000 1.5
@@ -8,19 +8,17 @@
package org.apache.myrmidon.components.classloader;
import java.io.File;
-import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
-import java.net.URLClassLoader;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
-import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
import java.util.jar.Manifest;
+import java.util.jar.JarFile;
import org.apache.avalon.excalibur.extension.Extension;
import org.apache.avalon.excalibur.extension.OptionalPackage;
-import org.apache.avalon.excalibur.extension.PackageManager;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.activity.Initializable;
@@ -28,8 +26,8 @@
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.classloader.ClassLoaderManager;
import org.apache.myrmidon.interfaces.deployer.DeploymentException;
import org.apache.myrmidon.interfaces.extensions.ExtensionManager;
import org.apache.tools.todo.types.PathUtil;
@@ -38,6 +36,7 @@
* A default implementation of a ClassLoader manager.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Adam Murdoch</a>
+ * @version $Revision: 1.5 $ $Date: 2002/04/03 10:58:19 $
*/
public class DefaultClassLoaderManager
extends AbstractLogEnabled
@@ -47,13 +46,22 @@
ResourceManager.getPackageResources( DefaultClassLoaderManager.class
);
/**
- * Map from File to the ClassLoader for that file.
+ * Map from File/ArrayList to the ClassLoader for that file/files.
*/
- private final Map m_fileDeployers = new HashMap();
+ private final Map m_classLoaders = new HashMap();
- private PackageManager m_packageManager;
+ private ExtensionManager m_extensionManager;
private ClassLoader m_commonClassLoader;
+ public DefaultClassLoaderManager()
+ {
+ }
+
+ public DefaultClassLoaderManager( final ClassLoader commonClassLoader )
+ {
+ m_commonClassLoader = commonClassLoader;
+ }
+
public void initialize() throws Exception
{
if( null == m_commonClassLoader )
@@ -68,18 +76,7 @@
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 setCommonClassLoader( final ClassLoader classLoader )
- {
- m_commonClassLoader = classLoader;
+ m_extensionManager = (ExtensionManager)serviceManager.lookup(
ExtensionManager.ROLE );
}
/**
@@ -94,9 +91,27 @@
/**
* Creates a class loader for a Jar file.
*/
- public ClassLoader createClassLoader( final File file ) throws
ClassLoaderException
+ public ClassLoader getClassLoader( final File file ) throws
ClassLoaderException
{
- return createClassLoader( new File[] { file } );
+ try
+ {
+ final File canonFile = file.getCanonicalFile();
+
+ // Check for cached classloader, creating it if required
+ ClassLoader loader = (ClassLoader)m_classLoaders.get( canonFile
);
+ if( loader == null )
+ {
+ checkFile( canonFile );
+ final OptionalPackage optionalPackage = toOptionalPackage(
canonFile );
+ loader = buildClassLoader( optionalPackage, new HashSet() );
+ }
+ return loader;
+ }
+ catch( final Exception e )
+ {
+ final String message = REZ.getString(
"create-classloader-for-file.error", file );
+ throw new ClassLoaderException( message, e );
+ }
}
/**
@@ -106,113 +121,165 @@
{
try
{
- // Build a list of canonical file names
- final ArrayList canonFiles = new ArrayList( files.length );
- for( int i = 0; i < files.length; i++ )
+ if( files == null || files.length == 0 )
{
- canonFiles.add( files[ i ].getCanonicalFile() );
+ return m_commonClassLoader;
}
- // Locate cached classloader, creating it if necessary
- ClassLoader classLoader = (ClassLoader)m_fileDeployers.get(
canonFiles );
- if( classLoader == null )
+ // Build a list of optional packages for the files
+ final OptionalPackage[] packages = new OptionalPackage[
files.length ];
+ for( int i = 0; i < files.length; i++ )
{
- classLoader = buildClassLoader( canonFiles );
- m_fileDeployers.put( canonFiles, classLoader );
+ final File canonFile = files[ i ].getCanonicalFile();
+ checkFile( canonFile );
+ packages[ i ] = toOptionalPackage( canonFile );
}
- return classLoader;
+
+ // Build the classloaders for the required extensions
+ final ClassLoader[] parentClassLoaders =
buildParentClassLoaders( packages, new HashSet() );
+
+ // Build the classloader
+ final URL[] urls = buildClasspath( files );
+ return new MultiParentURLClassLoader( urls, parentClassLoaders );
}
catch( final Exception e )
{
final String fileNames = PathUtil.formatPath( files );
- final String message = REZ.getString(
"create-classloader-for-file.error", fileNames );
+ final String message = REZ.getString(
"create-classloader-for-files.error", fileNames );
throw new ClassLoaderException( message, e );
}
}
/**
- * Builds the classloader for a set of files.
+ * Builds the classloader for an optional package.
+ */
+ private ClassLoader buildClassLoader( final OptionalPackage pkg,
+ final Set pending )
+ throws Exception
+ {
+ final File jarFile = pkg.getFile();
+
+ // Check for cached classloader
+ ClassLoader classLoader = (ClassLoader)m_classLoaders.get( jarFile );
+ if( classLoader != null )
+ {
+ return classLoader;
+ }
+
+ // Check for cyclic dependency
+ if( pending.contains( jarFile ) )
+ {
+ final String message = REZ.getString( "dependency-cycle.error",
jarFile );
+ throw new Exception( message );
+ }
+ pending.add( jarFile );
+
+ // Build the classloaders for the extensions required by this
optional
+ // package
+ final ClassLoader[] parentClassLoaders =
+ buildParentClassLoaders( new OptionalPackage[] { pkg }, pending
);
+
+ // Create and cache the classloader
+ final URL[] urls = { jarFile.toURL() };
+ classLoader = new MultiParentURLClassLoader( urls,
parentClassLoaders );
+ m_classLoaders.put( jarFile, classLoader );
+ pending.remove( jarFile );
+ return classLoader;
+ }
+
+ /**
+ * Builds the parent classloaders for a set of optional packages. That
is,
+ * the classloaders for all of the extensions required by the given set
+ * of optional packages.
*/
- private ClassLoader buildClassLoader( final ArrayList files )
+ private ClassLoader[] buildParentClassLoaders( final OptionalPackage[]
packages,
+ final Set pending )
throws Exception
{
- final ArrayList allFiles = new ArrayList( files );
- final int count = files.size();
- for( int i = 0; i < count; i++ )
+ final ArrayList classLoaders = new ArrayList();
+
+ // Include the common class loader
+ classLoaders.add( m_commonClassLoader );
+
+ // Build the classloader for each optional package, filtering out
duplicates
+ for( int i = 0; i < packages.length; i++ )
{
- final File file = (File)files.get(i );
- checkFile( file );
- getOptionalPackagesFor( file, allFiles );
+ final OptionalPackage optionalPackage = packages[ i ];
+
+ // Locate the dependencies for this jar file
+ final OptionalPackage[] requiredPackages =
getOptionalPackagesFor( optionalPackage );
+
+ // Build the classloader for the package
+ for( int j = 0; j < requiredPackages.length; j++ )
+ {
+ final OptionalPackage requiredPackage = requiredPackages[j ];
+ final ClassLoader classLoader = buildClassLoader(
requiredPackage, pending );
+ if( ! classLoaders.contains( classLoader ) )
+ {
+ classLoaders.add( classLoader );
+ }
+ }
}
- final URL[] urls = buildClasspath( allFiles );
- return new URLClassLoader( urls, m_commonClassLoader );
+ return (ClassLoader[])classLoaders.toArray( new
ClassLoader[classLoaders.size() ] );
}
/**
* Assembles a set of files into a URL classpath.
*/
- private URL[] buildClasspath( final ArrayList files )
+ private URL[] buildClasspath( final File[] files )
throws MalformedURLException
{
- final URL[] urls = new URL[ files.size() ];
- final int count = files.size();
- for( int i = 0; i < count; i++ )
+ final URL[] urls = new URL[ files.length ];
+ for( int i = 0; i < files.length; i++ )
{
- final File file = (File)files.get( i );
- urls[ i ] = file.toURL();
+ urls[ i ] = files[i ].toURL();
}
return urls;
}
/**
- * Retrieve the files for the optional packages required by
- * the specified typeLibrary jar.
+ * Builds an OptionalPackage for a Jar file.
*
- * @param jarFile the typeLibrary
- * @param packages used to return the files that need to be added to
ClassLoader.
+ * @param file the jar.
*/
- private void getOptionalPackagesFor( final File jarFile, final List
packages )
+ private OptionalPackage toOptionalPackage( final File file )
throws Exception
{
- 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 );
+ // Determine the extensions required by this file
+ final JarFile jarFile = new JarFile( file );
+ final Manifest manifest = jarFile.getManifest();
final Extension[] required = Extension.getRequired( manifest );
+ return new OptionalPackage( file, new Extension[0], required );
+ }
- if( getLogger().isDebugEnabled() )
- {
- final String message1 =
- REZ.getString( "available-extensions.notice", Arrays.asList(
available ) );
- getLogger().debug( message1 );
- final String message2 =
- REZ.getString( "required-extensions.notice", Arrays.asList(
required ) );
- getLogger().debug( message2 );
- }
-
- final ArrayList dependencies = new ArrayList();
- final ArrayList unsatisfied = new ArrayList();
-
- m_packageManager.scanDependencies( required,
- available,
- dependencies,
- unsatisfied );
-
- if( 0 != unsatisfied.size() )
+ /**
+ * Locates the optional packages required by an optional package.
+ */
+ private OptionalPackage[] getOptionalPackagesFor( final OptionalPackage
pkg )
+ throws Exception
+ {
+ // Locate the optional packages that provide the required extesions
+ final Extension[] required = pkg.getRequiredExtensions();
+ final ArrayList packages = new ArrayList();
+ for( int i = 0; i < required.length; i++ )
{
- final String message =
- REZ.getString( "unsatisfied.extensions.error", new Integer(
unsatisfied.size() ) );
- throw new Exception( message );
+ final Extension extension = required[i ];
+ final OptionalPackage optionalPackage =
m_extensionManager.getOptionalPackage( extension );
+ if( optionalPackage == null )
+ {
+ final String message =
+ REZ.getString( "unsatisfied.extension.error",
+ pkg.getFile(),
+ extension.getExtensionName(),
+ extension.getSpecificationVersion() );
+ throw new Exception( message );
+ }
+ packages.add( optionalPackage );
}
- final int count = dependencies.size();
- for( int i = 0; i < count; i++ )
- {
- final OptionalPackage optionalPackage =
(OptionalPackage)dependencies.get(i );
- packages.add( optionalPackage.getFile() );
- }
+ return (OptionalPackage[])packages.toArray( new
OptionalPackage[packages.size() ] );
}
/**
1.3 +5 -6
jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/classloader/Resources.properties
Index: Resources.properties
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/classloader/Resources.properties,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Resources.properties 27 Mar 2002 07:04:16 -0000 1.2
+++ Resources.properties 3 Apr 2002 10:58:19 -0000 1.3
@@ -1,6 +1,5 @@
-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.
-no-file.error=Could not find type library "{0}".
-file-is-dir.error=Type library "{0}" is a directory.
+create-classloader-for-file.error=Could not create a ClassLoader for "{0}".
+create-classloader-for-files.error=Could not create a ClassLoader for {0}.
+unsatisfied.extension.error=Library "{0}" requires unknown extension "{1}" (
version {2}).
+no-file.error=Could not find library "{0}".
+file-is-dir.error=Library "{0}" is a directory.
1.1
jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/classloader/MultiParentURLClassLoader.java
Index: MultiParentURLClassLoader.java
===================================================================
/*
* 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.components.classloader;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
/**
* A URLClassLoader with more than one parent.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Adam Murdoch</a>
* @version $Revision: 1.1 $ $Date: 2002/04/03 10:58:19 $
*/
public class MultiParentURLClassLoader
extends URLClassLoader
{
private final ClassLoader[] m_parents;
/**
* Constructs a new URLClassLoader for the given URLs.
*
* @param urls the URLs from which to load classes and resources
* @param parents the parent class loaderer for delegation
*/
public MultiParentURLClassLoader( final URL[] urls, final ClassLoader[]
parents )
{
super( urls );
m_parents = parents;
}
/**
* Finds a class.
*
* @param name the name of the class
* @return the resulting class
* @exception ClassNotFoundException if the class could not be found
*/
protected Class findClass( final String name )
throws ClassNotFoundException
{
// Try the parent classloaders first
for( int i = 0; i < m_parents.length; i++ )
{
try
{
final ClassLoader parent = m_parents[ i ];
return parent.loadClass( name );
}
catch( ClassNotFoundException e )
{
// Ignore - continue to the next ClassLoader
}
}
// Now this classloader
return super.findClass( name );
}
/**
* Finds a resource.
*
* @param name the name of the resource
* @return a <code>URL</code> for the resource, or <code>null</code>
* if the resource could not be found.
*/
public URL findResource( final String name )
{
// Try the parent classloaders first
for( int i = 0; i < m_parents.length; i++ )
{
final ClassLoader parent = m_parents[ i ];
final URL resource = parent.getResource( name );
if( resource != null )
{
return resource;
}
}
// Now this classloader
return super.findResource( name );
}
/**
* Returns an Enumeration of URLs representing all of the resources
* having the specified name.
*
* @param name the resource name
* @throws IOException if an I/O exception occurs
* @return an <code>Enumeration</code> of <code>URL</code>s
*/
public Enumeration findResources( final String name ) throws IOException
{
// Need to filter out duplicate resources
final ArrayList urls = new ArrayList();
final Set urlSet = new HashSet();
// Gather the resources from the parent classloaders
for( int i = 0; i < m_parents.length; i++ )
{
final ClassLoader parent = m_parents[ i ];
final Enumeration enum = parent.getResources( name );
addUrls( enum, urls, urlSet );
}
// Gather the resources from this classloader
addUrls( super.findResources( name ), urls, urlSet );
return Collections.enumeration( urls );
}
/**
* Adds those URLs not already present.
*/
private void addUrls( final Enumeration enum,
final List urls,
final Set urlSet )
{
while( enum.hasMoreElements() )
{
final URL url = (URL)enum.nextElement();
final String urlStr = url.toExternalForm();
if( !urlSet.contains( urlStr ) )
{
urls.add( url );
urlSet.add( urlStr );
}
}
}
}
1.36 +2 -2
jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/DefaultDeployer.java
Index: DefaultDeployer.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/deployer/DefaultDeployer.java,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- DefaultDeployer.java 29 Mar 2002 12:56:03 -0000 1.35
+++ DefaultDeployer.java 3 Apr 2002 10:58:19 -0000 1.36
@@ -36,7 +36,7 @@
*
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Adam Murdoch</a>
- * @version $Revision: 1.35 $ $Date: 2002/03/29 12:56:03 $
+ * @version $Revision: 1.36 $ $Date: 2002/04/03 10:58:19 $
*/
public class DefaultDeployer
extends AbstractLogEnabled
@@ -108,7 +108,7 @@
{
try
{
- final ClassLoader classLoader =
m_classLoaderManager.createClassLoader( file );
+ final ClassLoader classLoader =
m_classLoaderManager.getClassLoader( file );
return createDeployment( classLoader, file.toURL() );
}
catch( final Exception e )
1.41 +3 -105
jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java
Index: DefaultEmbeddor.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- DefaultEmbeddor.java 1 Apr 2002 09:56:26 -0000 1.40
+++ DefaultEmbeddor.java 3 Apr 2002 10:58:19 -0000 1.41
@@ -52,7 +52,7 @@
* Instantiate this to embed inside other applications.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
- * @version $Revision: 1.40 $ $Date: 2002/04/01 09:56:26 $
+ * @version $Revision: 1.41 $ $Date: 2002/04/03 10:58:19 $
*/
public class DefaultEmbeddor
extends AbstractLogEnabled
@@ -71,10 +71,7 @@
private List m_components = new ArrayList();
private DefaultServiceManager m_serviceManager = new
DefaultServiceManager();
private Parameters m_parameters;
- private Parameters m_defaults;
- private File m_homeDir;
- private File m_taskLibDir;
private static final String MYRMIDON_HOME = "myrmidon.home";
/**
@@ -163,9 +160,6 @@
public void initialize()
throws Exception
{
- // setup default properties
- m_defaults = createDefaultParameters();
-
// setup the root components
setupComponents();
@@ -183,9 +177,6 @@
m_workspaceServiceManager = new MultiSourceServiceManager();
m_workspaceServiceManager.add( projServiceManager );
m_workspaceServiceManager.add( m_serviceManager );
-
- // setup
- setupFiles();
}
public void start()
@@ -198,7 +189,8 @@
// Deploy all type libraries in the lib directory
final ExtensionFileFilter filter = new ExtensionFileFilter( ".atl" );
- deployFromDirectory( m_deployer, m_taskLibDir, filter );
+ final File taskLibDir = new File( m_parameters.getParameter(
"myrmidon.lib.path" ) );
+ deployFromDirectory( m_deployer, taskLibDir, filter );
}
/**
@@ -230,26 +222,6 @@
m_deployer = null;
m_serviceManager = null;
m_parameters = null;
- m_defaults = null;
- m_homeDir = null;
- m_taskLibDir = null;
- }
-
- /**
- * Create default properties which includes default names of all
components.
- * Overide this in sub-classes to change values.
- *
- * @return the Parameters
- */
- private Parameters createDefaultParameters()
- {
- final Parameters defaults = new Parameters();
-
- //create all the default properties for files/directories
- defaults.setParameter( "myrmidon.bin.path", "bin" );
- defaults.setParameter( "myrmidon.lib.path", "lib" );
-
- return defaults;
}
/**
@@ -294,80 +266,6 @@
m_serviceManager.put( roleType.getName(), component );
m_components.add( component );
return component;
- }
-
- /**
- * Setup all the files attributes.
- */
- private void setupFiles()
- throws Exception
- {
- String filepath = null;
-
- filepath = getParameter( MYRMIDON_HOME );
- m_homeDir = ( new File( filepath ) ).getAbsoluteFile();
- checkDirectory( m_homeDir, "home-dir.name" );
-
- filepath = getParameter( "myrmidon.lib.path" );
- m_taskLibDir = resolveDirectory( filepath, "task-lib-dir.name" );
- }
-
- /**
- * Retrieve value of named property.
- * First access passed in properties and then the default properties.
- *
- * @param name the name of property
- * @return the value of property or null
- */
- private String getParameter( final String name )
- {
- String value = m_parameters.getParameter( name, null );
-
- if( null == value )
- {
- value = m_defaults.getParameter( name, null );
- }
-
- return value;
- }
-
- /**
- * Resolve a directory relative to another base directory.
- *
- * @param dir the base directory
- * @param name the relative directory
- * @return the created File
- * @exception Exception if an error occurs
- */
- private File resolveDirectory( final String dir, final String name )
- throws Exception
- {
- final File file = FileUtil.resolveFile( m_homeDir, dir );
- checkDirectory( file, name );
- return file;
- }
-
- /**
- * Verify file is a directory else throw an exception.
- *
- * @param file the File
- * @param name the name of file type (used in error messages)
- */
- private void checkDirectory( final File file, final String name )
- throws Exception
- {
- if( !file.exists() )
- {
- final String nameStr = REZ.getString( name );
- final String message = REZ.getString( "file-no-exist.error",
nameStr, file );
- throw new Exception( message );
- }
- else if( !file.isDirectory() )
- {
- final String nameStr = REZ.getString( name );
- final String message = REZ.getString( "file-not-dir.error",
nameStr, file );
- throw new Exception( message );
- }
}
/**
1.5 +0 -4
jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/Resources.properties
Index: Resources.properties
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/Resources.properties,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Resources.properties 11 Mar 2002 06:02:22 -0000 1.4
+++ Resources.properties 3 Apr 2002 10:58:19 -0000 1.5
@@ -1,10 +1,6 @@
-file-no-exist.error={0} ({1}) does not exist.
-file-not-dir.error={0} ({1}) is not a directory.
bad-type.error=Object {0} is not an instance of {1}.
bad-ctor.error=Non-public constructor for {0} {1}.
no-instantiate.error=Error instantiating class for {0} {1}.
no-class.error=Could not find the class for {0} ({1}).
bad-filename.error=Unable to retrieve filename for file {0}.
-home-dir.name=Myrmidon home directory
-task-lib-dir.name=Task library directory
create-project.error=Could not load the project definition from {0}.
1.8 +26 -7
jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/extensions/DefaultExtensionManager.java
Index: DefaultExtensionManager.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/extensions/DefaultExtensionManager.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- DefaultExtensionManager.java 29 Mar 2002 12:55:04 -0000 1.7
+++ DefaultExtensionManager.java 3 Apr 2002 10:58:19 -0000 1.8
@@ -27,7 +27,7 @@
* PhoenixPackageRepository
*
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
- * @version $Revision: 1.7 $ $Date: 2002/03/29 12:55:04 $
+ * @version $Revision: 1.8 $ $Date: 2002/04/03 10:58:19 $
*/
public class DefaultExtensionManager
extends DefaultPackageRepository
@@ -50,7 +50,6 @@
File.separator + "lib" + File.separator + "tools.jar";
private Logger m_logger;
-
private String m_path;
public DefaultExtensionManager()
@@ -58,6 +57,11 @@
super( new File[ 0 ] );
}
+ public DefaultExtensionManager( final File[] path )
+ {
+ super( path );
+ }
+
public void enableLogging( final Logger logger )
{
m_logger = logger;
@@ -66,16 +70,13 @@
public void parameterize( final Parameters parameters )
throws ParameterException
{
- final String phoenixHome = parameters.getParameter( "myrmidon.home"
);
- final String defaultExtPath = phoenixHome + File.separator + "ext";
- m_path = parameters.getParameter( "myrmidon.ext.path",
defaultExtPath );
+ m_path = parameters.getParameter( "myrmidon.ext.path" );
}
public void initialize()
throws Exception
{
- final String[] pathElements = StringUtil.split( m_path, "|" );
-
+ final String[] pathElements = StringUtil.split( m_path,
File.pathSeparator );
final File[] dirs = new File[ pathElements.length ];
for( int i = 0; i < dirs.length; i++ )
{
@@ -86,6 +87,7 @@
scanPath();
+ // Add the JVM's tools.jar as an extension
final Extension extension = createToolsExtension();
final File jar = getToolsJar();
final Extension[] available = new Extension[]{extension};
@@ -97,6 +99,23 @@
public void dispose()
{
clearCache();
+ }
+
+ /**
+ * Locates the optional package which best matches a required extension.
+ *
+ * @param extension the extension to locate an optional package
+ * @return the optional package, or null if not found.
+ */
+ public OptionalPackage getOptionalPackage( final Extension extension )
+ {
+ final OptionalPackage[] packages = getOptionalPackages( extension );
+
+ if( null == packages || 0 == packages.length ) return null;
+
+ //TODO: Use heurisitic to find which is best package
+
+ return packages[ 0 ];
}
protected void debug( final String message )
1.37 +4 -4
jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/CLIMain.java
Index: CLIMain.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/CLIMain.java,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- CLIMain.java 29 Mar 2002 12:56:03 -0000 1.36
+++ CLIMain.java 3 Apr 2002 10:58:19 -0000 1.37
@@ -32,7 +32,7 @@
* to run project.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
- * @version $Revision: 1.36 $ $Date: 2002/03/29 12:56:03 $
+ * @version $Revision: 1.37 $ $Date: 2002/04/03 10:58:19 $
*/
public class CLIMain
{
@@ -277,10 +277,10 @@
break;
case LISTENER_OPT:
- m_embedded.setListener( option.getArgument() );
+ m_embedded.setProjectListener( option.getArgument() );
break;
case NO_PREFIX_OPT:
- m_embedded.setListener( "noprefix" );
+ m_embedded.setProjectListener( "noprefix" );
break;
case DEFINE_OPT:
@@ -310,7 +310,7 @@
try
{
// Set system properties set up by launcher
- m_embedded.setEmbeddorProperty( "myrmidon.home", properties.get(
"myrmidon.home" ) );
+ m_embedded.setHomeDirectory( (File)properties.get(
"myrmidon.home" ) );
// Command line
if( !parseCommandLineOptions( args ) )
1.6 +84 -25
jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/EmbeddedAnt.java
Index: EmbeddedAnt.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/EmbeddedAnt.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- EmbeddedAnt.java 29 Mar 2002 12:56:03 -0000 1.5
+++ EmbeddedAnt.java 3 Apr 2002 10:58:19 -0000 1.6
@@ -8,8 +8,10 @@
package org.apache.myrmidon.frontends;
import java.io.File;
+import java.util.ArrayList;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
+import org.apache.avalon.excalibur.io.FileUtil;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Startable;
@@ -33,7 +35,7 @@
*
* @author <a href="mailto:[EMAIL PROTECTED]">Adam Murdoch</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
- * @version $Revision: 1.5 $ $Date: 2002/03/29 12:56:03 $
+ * @version $Revision: 1.6 $ $Date: 2002/04/03 10:58:19 $
*/
public class EmbeddedAnt
extends AbstractLogEnabled
@@ -47,12 +49,25 @@
private String m_projectFile = "build.ant";
private Project m_project;
private String m_listenerName = "default";
- private ProjectListener m_listener;
+ private ArrayList m_listeners = new ArrayList();
private Parameters m_workspaceProps = new Parameters();
private Parameters m_builderProps = new Parameters();
private Parameters m_embeddorParameters = new Parameters();
private ClassLoader m_sharedClassLoader;
private Embeddor m_embeddor;
+ private File m_homeDir;
+
+ /**
+ * Sets the Myrmidon home directory. Default is to use the current
+ * directory.
+ *
+ * @todo Autodetect myrmidon home, rather than using current directory
+ * as the default (which is a dud default).
+ */
+ public void setHomeDirectory( final File homeDir )
+ {
+ m_homeDir = homeDir.getAbsoluteFile();
+ }
/**
* Sets the project file to execute. Default is 'build.ant'.
@@ -75,21 +90,20 @@
}
/**
- * Sets the name of the project listener to use.
+ * Sets the name of the project listener to use. Set to null to disable
+ * the project listener.
*/
- public void setListener( final String listener )
+ public void setProjectListener( final String listener )
{
m_listenerName = listener;
- m_listener = null;
}
/**
- * Sets the project listener to use.
+ * Adds a project listener.
*/
- public void setListener( final ProjectListener listener )
+ public void addProjectListener( final ProjectListener listener )
{
- m_listenerName = null;
- m_listener = listener;
+ m_listeners.add( listener );
}
/**
@@ -99,7 +113,7 @@
public void setWorkspaceProperty( final String name, final Object value )
{
// TODO - Make properties Objects, not Strings
- m_workspaceProps.setParameter( name, (String)value );
+ m_workspaceProps.setParameter( name, value.toString() );
}
/**
@@ -109,7 +123,7 @@
public void setBuilderProperty( final String name, final Object value )
{
// TODO - Make properties Objects, not Strings
- m_builderProps.setParameter( name, (String)value );
+ m_builderProps.setParameter( name, value.toString() );
}
/**
@@ -145,14 +159,13 @@
checkHomeDir();
- // Prepare the embeddor, project listener and project model
+ // Prepare the embeddor, and project model
final Embeddor embeddor = prepareEmbeddor();
- final ProjectListener listener = prepareListener( embeddor );
final Project project = prepareProjectModel( embeddor );
// Create a new workspace
final Workspace workspace = embeddor.createWorkspace(
m_workspaceProps );
- workspace.addProjectListener( listener );
+ prepareListeners( embeddor, workspace );
//execute the project
executeTargets( workspace, project, targets );
@@ -181,7 +194,7 @@
{
m_embeddor = null;
m_project = null;
- m_listener = null;
+ m_listeners.clear();
}
}
@@ -213,19 +226,26 @@
*/
private void checkHomeDir() throws Exception
{
- final String home = m_embeddorParameters.getParameter(
"myrmidon.home" );
- final File homeDir = ( new File( home ) ).getAbsoluteFile();
- if( !homeDir.isDirectory() )
+ if( m_homeDir == null )
{
- final String message = REZ.getString( "home-not-dir.error",
homeDir );
- throw new Exception( message );
+ m_homeDir = new File( "." ).getAbsoluteFile();
}
+ checkDirectory( m_homeDir, "home-dir.name" );
+ m_embeddorParameters.setParameter( "myrmidon.home",
m_homeDir.getAbsolutePath() );
if( getLogger().isInfoEnabled() )
{
- final String message = REZ.getString( "homedir.notice", homeDir
);
+ final String message = REZ.getString( "homedir.notice",
m_homeDir );
getLogger().info( message );
}
+
+ String path = m_embeddorParameters.getParameter(
"myrmidon.lib.path", "lib" );
+ File dir = resolveDirectory( m_homeDir, path, "task-lib-dir.name" );
+ m_embeddorParameters.setParameter( "myrmidon.lib.path",
dir.getAbsolutePath() );
+
+ path = m_embeddorParameters.getParameter( "myrmidon.ext.path", "ext"
);
+ dir = resolveDirectory( m_homeDir, path, "ext-dir.name" );
+ m_embeddorParameters.setParameter( "myrmidon.ext.path",
dir.getAbsolutePath() );
}
/**
@@ -267,14 +287,21 @@
/**
* Prepares and returns the project listener to use.
*/
- private ProjectListener prepareListener( final Embeddor embeddor )
+ private void prepareListeners( final Embeddor embeddor,
+ final Workspace workspace )
throws Exception
{
- if( m_listener == null )
+ if( m_listenerName != null )
{
- m_listener = embeddor.createListener( m_listenerName );
+ final ProjectListener listener = embeddor.createListener(
m_listenerName );
+ workspace.addProjectListener( listener );
+ }
+ final int count = m_listeners.size();
+ for( int i = 0; i < count; i++ )
+ {
+ final ProjectListener listener =
(ProjectListener)m_listeners.get(i );
+ workspace.addProjectListener( listener );
}
- return m_listener;
}
/**
@@ -310,4 +337,36 @@
return projectFile;
}
+
+ /**
+ * Resolve a directory relative to another base directory.
+ */
+ private File resolveDirectory( final File baseDir, final String dir,
final String name )
+ throws Exception
+ {
+ final File file = FileUtil.resolveFile( baseDir, dir );
+ checkDirectory( file, name );
+ return file;
+ }
+
+ /**
+ * Verify file is a directory else throw an exception.
+ */
+ private void checkDirectory( final File file, final String name )
+ throws Exception
+ {
+ if( !file.exists() )
+ {
+ final String nameStr = REZ.getString( name );
+ final String message = REZ.getString( "file-no-exist.error",
nameStr, file );
+ throw new Exception( message );
+ }
+ else if( !file.isDirectory() )
+ {
+ final String nameStr = REZ.getString( name );
+ final String message = REZ.getString( "file-not-dir.error",
nameStr, file );
+ throw new Exception( message );
+ }
+ }
+
}
1.8 +5 -1
jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/Resources.properties
Index: Resources.properties
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/Resources.properties,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Resources.properties 26 Mar 2002 02:14:02 -0000 1.7
+++ Resources.properties 3 Apr 2002 10:58:19 -0000 1.8
@@ -16,7 +16,8 @@
build.opt=Define a builder parameter (ie -Bfoo=var).
dry-run.opt=Do not execute tasks - just print them out.
-home-not-dir.error=myrmidon-home ({0}) is not a directory.
+file-no-exist.error={0} {1} does not exist.
+file-not-dir.error={0} {1} is not a directory.
bad-file.error=File {0} is not a file or doesn't exist.
bad-loglevel.error=Unknown log level - {0}.
build-failed.error=BUILD FAILED.
@@ -26,3 +27,6 @@
homedir.notice=Ant Home Directory: {0}
buildfile.notice=Ant Build File: {0}
+home-dir.name=Ant home directory
+task-lib-dir.name=Task library directory
+ext-dir.name=Extension library directory
1.4 +15 -6
jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/classloader/ClassLoaderManager.java
Index: ClassLoaderManager.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/classloader/ClassLoaderManager.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ClassLoaderManager.java 1 Apr 2002 09:56:26 -0000 1.3
+++ ClassLoaderManager.java 3 Apr 2002 10:58:19 -0000 1.4
@@ -13,6 +13,7 @@
* Manages a classloader hierarchy.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Adam Murdoch</a>
+ * @version $Revision: 1.4 $ $Date: 2002/04/03 10:58:19 $
*/
public interface ClassLoaderManager
{
@@ -20,15 +21,22 @@
String ROLE = ClassLoaderManager.class.getName();
/**
- * Builds the ClassLoader for a Jar file, resolving dependencies.
+ * Returns the ClassLoader for a Jar file. The ClassLoader is created,
+ * if necessary. The ClassLoader's parent will include the common
+ * ClassLoader, along with any extensions required by the Jar file.
+ * It is guaranteed that each extension will appear at most once in the
+ * ClassLoader hierarchy, so that classes from the extension can be
+ * shared across the ClassLoaders returned by this method.
+ *
* @param jar the jar file containing the classes to load
- * @return the created classloader
+ * @return the classloader
* @throws ClassLoaderException on error
*/
- ClassLoader createClassLoader( File jar ) throws ClassLoaderException;
+ ClassLoader getClassLoader( File jar ) throws ClassLoaderException;
/**
- * Builds the ClassLoader for a set of files, resolving dependencies.
+ * Creates a ClassLoader for a set of files. See [EMAIL PROTECTED]
#getClassLoader}
+ * for details.
*
* @param jars The Jar/zip files to create the classloader for. Use null
* or an empty array to use the common classloader.
@@ -38,9 +46,10 @@
ClassLoader createClassLoader( File[] jars ) throws ClassLoaderException;
/**
- * Provides the common ClassLoader, which is the parent of all
classloaders
+ * Returns the common ClassLoader, which is the parent of all
classloaders
* built by this ClassLoaderManager.
- * @return the common ClassLoader
+ *
+ * @return the common ClassLoader.
*/
ClassLoader getCommonClassLoader();
}
1.7 +12 -4
jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/extensions/ExtensionManager.java
Index: ExtensionManager.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/extensions/ExtensionManager.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- ExtensionManager.java 1 Apr 2002 09:56:27 -0000 1.6
+++ ExtensionManager.java 3 Apr 2002 10:58:19 -0000 1.7
@@ -7,17 +7,25 @@
*/
package org.apache.myrmidon.interfaces.extensions;
-import org.apache.avalon.excalibur.extension.PackageRepository;
+import org.apache.avalon.excalibur.extension.Extension;
+import org.apache.avalon.excalibur.extension.OptionalPackage;
/**
- * PackageRepository
+ * Maintains a set of optional packages.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
- * @version $Revision: 1.6 $ $Date: 2002/04/01 09:56:27 $
+ * @version $Revision: 1.7 $ $Date: 2002/04/03 10:58:19 $
*/
public interface ExtensionManager
- extends PackageRepository
{
/** Role name for this interface. */
String ROLE = ExtensionManager.class.getName();
+
+ /**
+ * Locates the optional package which best matches a required extension.
+ *
+ * @param extension the extension to locate an optional package
+ * @return the optional package, or null if not found.
+ */
+ public OptionalPackage getOptionalPackage( Extension extension );
}
1.12 +35 -29
jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/AbstractMyrmidonTest.java
Index: AbstractMyrmidonTest.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/AbstractMyrmidonTest.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- AbstractMyrmidonTest.java 28 Mar 2002 06:35:21 -0000 1.11
+++ AbstractMyrmidonTest.java 3 Apr 2002 10:58:20 -0000 1.12
@@ -29,28 +29,21 @@
private final File m_baseDir;
private Logger m_logger;
- protected static final Resources getResourcesForTested( final Class
clazz )
+ public AbstractMyrmidonTest( final String name )
{
- final Package pkg = clazz.getPackage();
-
- String baseName;
- if( null == pkg )
- {
- final String name = clazz.getName();
- if( -1 == name.lastIndexOf( "." ) )
- {
- baseName = "";
- }
- else
- {
- baseName = name.substring( 0, name.lastIndexOf( "." ) );
- }
- }
- else
- {
- baseName = pkg.getName();
- }
+ super( name );
+ final String baseDirProp = System.getProperty( "test.basedir" );
+ m_baseDir = getCanonicalFile( new File( baseDirProp ) );
+ final String packagePath = getPackageName( getClass() ).replace(
'.', File.separatorChar );
+ m_testBaseDir = getCanonicalFile( new File( m_baseDir, packagePath )
);
+ }
+ /**
+ * Locates the error message resources for a class.
+ */
+ protected static final Resources getResourcesForTested( final Class
clazz )
+ {
+ String baseName = getPackageName( clazz );
if( baseName.endsWith( ".test" ) )
{
baseName = baseName.substring( 0, baseName.length() - 5 );
@@ -59,16 +52,29 @@
return ResourceManager.getBaseResources( baseName + ".Resources",
AbstractMyrmidonTest.class.getClassLoader() );
}
- public AbstractMyrmidonTest( String name )
+ /**
+ * Returns the name of the package containing a class.
+ *
+ * @return The . delimited package name, or an empty string if the class
+ * is in the default package.
+ */
+ protected static String getPackageName( final Class clazz )
{
- super( name );
- final String baseDirProp = System.getProperty( "test.basedir" );
- m_baseDir = getCanonicalFile( new File( baseDirProp ) );
- String packagePath = getClass().getName();
- int idx = packagePath.lastIndexOf( '.' );
- packagePath = packagePath.substring( 0, idx );
- packagePath = packagePath.replace( '.', File.separatorChar );
- m_testBaseDir = getCanonicalFile( new File( m_baseDir, packagePath )
);
+ final Package pkg = clazz.getPackage();
+ if( null != pkg )
+ {
+ return pkg.getName();
+ }
+
+ final String name = clazz.getName();
+ if( -1 == name.lastIndexOf( "." ) )
+ {
+ return "";
+ }
+ else
+ {
+ return name.substring( 0, name.lastIndexOf( "." ) );
+ }
}
/**
1.7 +13 -52
jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/AbstractProjectTest.java
Index: AbstractProjectTest.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/AbstractProjectTest.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- AbstractProjectTest.java 28 Mar 2002 06:35:21 -0000 1.6
+++ AbstractProjectTest.java 3 Apr 2002 10:58:20 -0000 1.7
@@ -8,68 +8,24 @@
package org.apache.myrmidon;
import java.io.File;
-import org.apache.avalon.framework.logger.Logger;
-import org.apache.avalon.framework.parameters.Parameters;
-import org.apache.myrmidon.components.embeddor.DefaultEmbeddor;
-import org.apache.myrmidon.interfaces.embeddor.Embeddor;
-import org.apache.myrmidon.interfaces.model.Project;
-import org.apache.myrmidon.interfaces.workspace.Workspace;
+import org.apache.myrmidon.frontends.EmbeddedAnt;
import org.apache.myrmidon.listeners.ProjectListener;
/**
* A base class for test cases which need to execute projects.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Adam Murdoch</a>
- * @version $Revision: 1.6 $ $Date: 2002/03/28 06:35:21 $
+ * @version $Revision: 1.7 $ $Date: 2002/04/03 10:58:20 $
*/
public class AbstractProjectTest
extends AbstractMyrmidonTest
{
- private DefaultEmbeddor m_embeddor;
-
public AbstractProjectTest( final String name )
{
super( name );
}
/**
- * Tear-down the test.
- */
- protected void tearDown() throws Exception
- {
- if( m_embeddor != null )
- {
- m_embeddor.dispose();
- m_embeddor = null;
- }
- }
-
- /**
- * Returns an embeddor which can be used to build and execute projects.
- */
- protected Embeddor getEmbeddor() throws Exception
- {
- if( m_embeddor == null )
- {
- // Need to set the context classloader - The default embeddor
uses it
- Thread.currentThread().setContextClassLoader(
getClass().getClassLoader() );
-
- final Logger logger = getLogger();
- m_embeddor = new DefaultEmbeddor();
- m_embeddor.enableLogging( logger );
-
- final Parameters params = new Parameters();
- final File instDir = getInstallDirectory();
- params.setParameter( "myrmidon.home", instDir.getAbsolutePath()
);
- m_embeddor.parameterize( params );
- m_embeddor.initialize();
- m_embeddor.start();
- }
-
- return m_embeddor;
- }
-
- /**
* Executes a target in a project, and asserts that it fails with the
* given error message.
*/
@@ -117,22 +73,27 @@
throws Exception
{
// Create the project and workspace
- final Embeddor embeddor = getEmbeddor();
- final Project project = embeddor.createProject(
projectFile.getAbsolutePath(), null, null );
- final Workspace workspace = embeddor.createWorkspace( new
Parameters() );
+ final EmbeddedAnt embeddor = new EmbeddedAnt();
+ embeddor.setHomeDirectory( getInstallDirectory() );
+ embeddor.enableLogging( getLogger() );
+ embeddor.setSharedClassLoader( getClass().getClassLoader() );
+ embeddor.setProjectFile( projectFile.getAbsolutePath() );
+ embeddor.setProjectListener( null );
// Add a listener to make sure all is good
final TrackingProjectListener tracker = new
TrackingProjectListener();
- workspace.addProjectListener( tracker );
+ embeddor.addProjectListener( tracker );
// Add supplied listener
if( listener != null )
{
- workspace.addProjectListener( listener );
+ embeddor.addProjectListener( listener );
}
// Now execute the target
- workspace.executeProject( project, targetName );
+ embeddor.executeTargets( new String[] { targetName } );
+
+ embeddor.stop();
// Make sure all expected events were delivered
tracker.assertComplete();
1.21 +48 -5
jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/components/AbstractComponentTest.java
Index: AbstractComponentTest.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/components/AbstractComponentTest.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- AbstractComponentTest.java 27 Mar 2002 07:04:17 -0000 1.20
+++ AbstractComponentTest.java 3 Apr 2002 10:58:20 -0000 1.21
@@ -10,12 +10,16 @@
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.io.File;
import org.apache.aut.converter.Converter;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.service.DefaultServiceManager;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.activity.Initializable;
import org.apache.myrmidon.AbstractMyrmidonTest;
import org.apache.myrmidon.components.classloader.DefaultClassLoaderManager;
import org.apache.myrmidon.components.configurer.DefaultConfigurer;
@@ -93,10 +97,9 @@
m_serviceManager.put( Executor.ROLE, component );
components.add( component );
- final DefaultClassLoaderManager classLoaderMgr = new
DefaultClassLoaderManager();
- classLoaderMgr.setCommonClassLoader( getClass().getClassLoader()
);
- m_serviceManager.put( ClassLoaderManager.ROLE, classLoaderMgr );
- components.add( classLoaderMgr );
+ component = createComponent( ClassLoaderManager.ROLE,
DefaultClassLoaderManager.class );
+ m_serviceManager.put( ClassLoaderManager.ROLE, component );
+ components.add( component );
component = createComponent( ExtensionManager.ROLE,
DefaultExtensionManager.class );
m_serviceManager.put( ExtensionManager.ROLE, component );
@@ -132,6 +135,29 @@
}
}
+ // Parameterise the components
+ final Parameters parameters = getParameters();
+ for( Iterator iterator = components.iterator();
iterator.hasNext(); )
+ {
+ Object obj = iterator.next();
+ if( obj instanceof Parameterizable )
+ {
+ final Parameterizable parameterizable =
(Parameterizable)obj;
+ parameterizable.parameterize( parameters );
+ }
+ }
+
+ // Initialise the components
+ for( Iterator iterator = components.iterator();
iterator.hasNext(); )
+ {
+ Object obj = iterator.next();
+ if( obj instanceof Initializable )
+ {
+ final Initializable initializable = (Initializable)obj;
+ initializable.initialize();
+ }
+ }
+
// Register some standard roles
// Add some core roles
final RoleManager roleManager =
(RoleManager)getServiceManager().lookup( RoleManager.ROLE );
@@ -144,12 +170,29 @@
}
/**
- * Creates an instance of a component. Sub-classes can override this
+ * Creates the parameters for the test. Sub-classes can override this
+ * method to set-up the parameters.
+ */
+ protected Parameters getParameters()
+ {
+ final Parameters parameters = new Parameters();
+ final String homeDir = getInstallDirectory().getAbsolutePath();
+ parameters.setParameter( "myrmidon.home", homeDir );
+ parameters.setParameter( "myrmidon.ext.path", homeDir +
File.separatorChar + "ext" );
+ return parameters;
+ }
+
+ /**
+ * Creates an instance of a test component. Sub-classes can override
this
* method to add a particular implementation to the set of test
components.
*/
protected Object createComponent( final String role, final Class
defaultImpl )
throws Exception
{
+ if( role.equals( ClassLoaderManager.ROLE ) )
+ {
+ return new DefaultClassLoaderManager(
getClass().getClassLoader() );
+ }
return defaultImpl.newInstance();
}
1.1
jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/components/classloader/test/DefaultClassLoaderManagerTestCase.java
Index: DefaultClassLoaderManagerTestCase.java
===================================================================
/*
* 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.components.classloader.test;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import org.apache.myrmidon.components.AbstractComponentTest;
import org.apache.myrmidon.components.classloader.DefaultClassLoaderManager;
import org.apache.myrmidon.interfaces.classloader.ClassLoaderManager;
import org.apache.myrmidon.interfaces.classloader.ClassLoaderException;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.excalibur.i18n.Resources;
/**
* Test cases for the DefaultClassLoaderManager.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Adam Murdoch</a>
* @version $Revision: 1.1 $ $Date: 2002/04/03 10:58:20 $
*/
public class DefaultClassLoaderManagerTestCase
extends AbstractComponentTest
{
private static final String UNSHARED_PKG_NAME =
getPackageName( DefaultClassLoaderManagerTestCase.class ) +
".libs.unshared";
private static final String UNSHARED_RES_NAME = getResourceName(
UNSHARED_PKG_NAME, "unshared.txt" );
private static final String UNSHARED_CLASS_NAME = UNSHARED_PKG_NAME +
".UnsharedClass";
private static final String SHARED_PKG_NAME =
getPackageName( DefaultClassLoaderManagerTestCase.class ) +
".libs.shared";
private static final String SHARED_RES_NAME = getResourceName(
SHARED_PKG_NAME, "shared.txt" );
private static final String SHARED_CLASS_NAME = SHARED_PKG_NAME +
".SharedClass";
private static final String EXTN_PKG_NAME =
getPackageName( DefaultClassLoaderManagerTestCase.class ) +
".libs.extn";
private static final String EXTN_RES_NAME = getResourceName(
EXTN_PKG_NAME, "extn.txt" );
private static final String EXTN_CLASS_NAME = EXTN_PKG_NAME +
".ExtnClass";
private File m_commonJar;
private ClassLoader m_commonClassLoader;
private ClassLoaderManager m_loaderManager;
public DefaultClassLoaderManagerTestCase( final String name )
{
super( name );
}
/**
* Sets up the test.
*/
protected void setUp() throws Exception
{
m_commonJar = getTestResource( "common.jar" );
final URL commonJarUrl = m_commonJar.toURL();
m_commonClassLoader = new URLClassLoader( new URL[]{commonJarUrl} );
assertClassFound( m_commonClassLoader, SHARED_CLASS_NAME );
assertResourcesFound( m_commonClassLoader, SHARED_RES_NAME,
m_commonJar );
// Create the classloader mgr
m_loaderManager = (ClassLoaderManager)getServiceManager().lookup(
ClassLoaderManager.ROLE );
}
/**
* Creates an instance of a test component.
*/
protected Object createComponent( final String role, final Class
defaultImpl )
throws Exception
{
if( role.equals( ClassLoaderManager.ROLE ) )
{
return new DefaultClassLoaderManager( m_commonClassLoader );
}
else
{
return super.createComponent( role, defaultImpl );
}
}
/**
* Creates the parameters for the test. Sub-classes can override this
* method to set-up the parameters.
*/
protected Parameters getParameters()
{
final Parameters parameters = super.getParameters();
parameters.setParameter( "myrmidon.ext.path", getTestDirectory( "ext"
).getAbsolutePath() );
return parameters;
}
/**
* Returns the name of a resource in a package.
*/
private static String getResourceName( final String pkgName,
final String resname )
{
return pkgName.replace( '.', '/' ) + '/' + resname;
}
/**
* Asserts that a class is not available in a classloader.
*/
private void assertClassNotFound( final ClassLoader classLoader,
final String className )
{
try
{
classLoader.loadClass( className );
fail( "Class " + className + " should not be available." );
}
catch( ClassNotFoundException e )
{
}
}
/**
* Asserts that a class is available in a classloader.
*/
private void assertClassFound( final ClassLoader classLoader,
final String className )
throws Exception
{
assertClassFound( classLoader, className, classLoader );
}
/**
* Asserts that a class is available in a classloader.
*/
private void assertClassFound( final ClassLoader classLoader,
final String className,
final ClassLoader expectedClassLoader )
throws Exception
{
try
{
final Class cls = classLoader.loadClass( className );
assertSame( expectedClassLoader, cls.getClassLoader() );
if( classLoader != expectedClassLoader )
{
final Class expectedCls = expectedClassLoader.loadClass(
className );
assertSame( expectedCls, cls );
}
}
catch( ClassNotFoundException e )
{
fail( "Class " + className + " not found." );
}
}
/**
* Asserts that a resouce is not available in a classloader.
*/
private void assertResourceNotFound( final ClassLoader classLoader,
final String resName )
throws Exception
{
assertNull( classLoader.getResource( resName ) );
assertNull( classLoader.getResourceAsStream( resName ) );
final Enumeration enum = classLoader.getResources( resName );
assertTrue( !enum.hasMoreElements() );
}
/**
* Asserts that a resource is available in a classloader.
*/
private void assertResourcesFound( final ClassLoader classLoader,
final String resName,
final File expectedJar )
throws Exception
{
assertResourcesFound( classLoader, resName, new File[]{expectedJar} );
}
/**
* Asserts that a resource is available in a classloader.
*/
private void assertResourcesFound( final ClassLoader classLoader,
final String resName,
final File[] expectedJars )
throws Exception
{
final String[] expectedLocations = new String[ expectedJars.length ];
for( int i = 0; i < expectedJars.length; i++ )
{
final File jar = expectedJars[ i ];
expectedLocations[ i ] = "jar:" + jar.toURL() + "!/" + resName;
}
assertResourcesFound( classLoader, resName, expectedLocations );
}
/**
* Asserts that a resource is available in a classloader.
*/
private void assertResourcesFound( final ClassLoader classLoader,
final String resName,
final String[] expectedLocations )
throws Exception
{
// Use the first in the list of expected locations as the location
// of the resource returned by getResource()
final URL resUrl = classLoader.getResource( resName );
assertNotNull( resUrl );
assertEquals( expectedLocations[ 0 ], resUrl.toString() );
// Now check all of the resources returned by getResources()
final Enumeration resources = classLoader.getResources( resName );
for( int i = 0; i < expectedLocations.length; i++ )
{
final String expectedLocation = expectedLocations[ i ];
assertTrue( resources.hasMoreElements() );
final URL location = (URL)resources.nextElement();
assertEquals( expectedLocation, location.toString() );
}
assertTrue( !resources.hasMoreElements() );
}
/**
* Tests for a Jar with no required extensions.
*/
public void testNoDependencies() throws Exception
{
// Make some assumptions about the common classloader
assertClassNotFound( m_commonClassLoader, UNSHARED_CLASS_NAME );
assertResourceNotFound( m_commonClassLoader, UNSHARED_RES_NAME );
// Build the classloader
final File jarFile = getTestResource( "no-dependencies.jar" );
final ClassLoader classLoader = m_loaderManager.getClassLoader(
jarFile );
// Check shared classes/resources
assertClassFound( classLoader, SHARED_CLASS_NAME, m_commonClassLoader
);
assertResourcesFound( classLoader, SHARED_RES_NAME, new
File[]{m_commonJar, jarFile} );
// Check unshared classes/resources
assertClassFound( classLoader, UNSHARED_CLASS_NAME );
assertResourcesFound( classLoader, UNSHARED_RES_NAME, jarFile );
}
/**
* Tests ClassLoader caching.
*/
public void testClassLoaderReuse() throws Exception
{
final File jarFile = getTestResource( "no-dependencies.jar" );
final ClassLoader classLoader1 = m_loaderManager.getClassLoader(
jarFile );
final ClassLoader classLoader2 = m_loaderManager.getClassLoader(
jarFile );
assertSame( classLoader1, classLoader2 );
}
/**
* Tests for a Jar with a single required extension.
*/
public void testOneDependency() throws Exception
{
// Make some assumptions about the common classloader
assertClassNotFound( m_commonClassLoader, UNSHARED_CLASS_NAME );
assertResourceNotFound( m_commonClassLoader, UNSHARED_RES_NAME );
assertClassNotFound( m_commonClassLoader, EXTN_CLASS_NAME );
assertResourceNotFound( m_commonClassLoader, EXTN_RES_NAME );
// Build the extension classloader
final File extnJarFile = getTestResource( "ext/simple-extension.jar"
);
final ClassLoader extnClassLoader = m_loaderManager.getClassLoader(
extnJarFile );
// Build the Jar classloader
final File jarFile = getTestResource( "one-dependency.jar" );
final ClassLoader classLoader = m_loaderManager.getClassLoader(
jarFile );
// Check shared classes/resources
assertClassFound( classLoader, SHARED_CLASS_NAME, m_commonClassLoader
);
assertResourcesFound( classLoader, SHARED_RES_NAME, new
File[]{m_commonJar, extnJarFile, jarFile} );
// Check extension classes/resources
assertClassFound( classLoader, EXTN_CLASS_NAME, extnClassLoader );
assertResourcesFound( classLoader, EXTN_RES_NAME, extnJarFile );
// Check unshared classes/resources
assertClassFound( classLoader, UNSHARED_CLASS_NAME );
assertResourcesFound( classLoader, UNSHARED_RES_NAME, jarFile );
}
/**
* Tests that classes from extensions can be shared across classloaders.
*/
public void testShareClasses() throws Exception
{
// Build the extension classloader
final File extnJarFile = getTestResource( "ext/simple-extension.jar"
);
final ClassLoader extnClassLoader = m_loaderManager.getClassLoader(
extnJarFile );
// Build the Jar classloaders
final File jarFile1 = getTestResource( "one-dependency.jar" );
final ClassLoader classLoader1 = m_loaderManager.getClassLoader(
jarFile1 );
final File jarFile2 = getTestResource( "one-dependency-2.jar" );
final ClassLoader classLoader2 = m_loaderManager.getClassLoader(
jarFile2 );
// Check extension classes/resources
assertClassFound( classLoader1, EXTN_CLASS_NAME, extnClassLoader );
assertResourcesFound( classLoader1, EXTN_RES_NAME, extnJarFile );
assertClassFound( classLoader2, EXTN_CLASS_NAME, extnClassLoader );
assertResourcesFound( classLoader2, EXTN_RES_NAME, extnJarFile );
}
/**
* Tests detection of dependency cycles in extensions.
*/
public void testCycle() throws Exception
{
final File jarFile = getTestResource( "ext/cycle-extension-1.jar" );
try
{
m_loaderManager.getClassLoader( jarFile );
fail();
}
catch( final ClassLoaderException e )
{
final Resources rez = getResourcesForTested(
DefaultClassLoaderManager.class );
final String[] messages = {
rez.getString( "create-classloader-for-file.error", jarFile ),
rez.getString( "dependency-cycle.error", jarFile )
};
assertSameMessage( messages, e );
}
}
/**
* add some classes to common loader only.
*
* unknown extension
* multiple versions of extensions
* extn with requirement on itself
*
* jar with 1 and 2 extns:
* class/resources in parent
* class/resources in jar
* class/resources in extn
* class/resources in all
*
* jar with transitive extn
* class/resources in 2nd extn
*
* jar with transitive extn + explicit extn on same jar
* class/resources in 2nd extn
*
* Same classes:
* get extn explicitly and implicitly, and check classes are the same
* extn shared by 2 jars, using same extn and different extns
* classes in common classloader, shared by 2 jars
*
* multiple files:
* fetch classloader twice
* different path ordering
*
* tools.jar
*/
}
1.1
jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/components/classloader/test/libs/cycle-extension-1.mf
Index: cycle-extension-1.mf
===================================================================
Extension-Name: test.cycle1
Specification-Title: Test Extension
Specification-Version: 1.0.0
Specification-Vendor: Jakarta Apache
Implementation-Vendor-Id: org.apache.myrmidon
Implementation-Vendor: Apache Myrmidon Project
Implementation-Version: 3.0
Extension-List: cycle2
cycle2-Extension-Name: test.cycle2
cycle2-Specification-Version: 1.0
1.1
jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/components/classloader/test/libs/cycle-extension-2.mf
Index: cycle-extension-2.mf
===================================================================
Extension-Name: test.cycle2
Specification-Title: Test Extension
Specification-Version: 1.0.0
Specification-Vendor: Jakarta Apache
Implementation-Vendor-Id: org.apache.myrmidon
Implementation-Vendor: Apache Myrmidon Project
Implementation-Version: 1.709.2
Extension-List: cycle1
cycle1-Extension-Name: test.cycle1
cycle1-Specification-Version: 1.0
1.1
jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/components/classloader/test/libs/one-dependency.mf
Index: one-dependency.mf
===================================================================
Extension-List: extension1
extension1-Extension-Name: test.simple
extension1-Specification-Version: 1.0
1.1
jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/components/classloader/test/libs/simple-extension.mf
Index: simple-extension.mf
===================================================================
Extension-Name: test.simple
Specification-Title: Test Simple Extension
Specification-Version: 1.0.0
Specification-Vendor: Jakarta Apache
Implementation-Vendor-Id: org.apache.myrmidon
Implementation-Vendor: Apache Myrmidon Project
Implementation-Version: 1.0.2
1.1
jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/components/classloader/test/libs/extn/ExtnClass.java
Index: ExtnClass.java
===================================================================
/*
* 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.components.classloader.test.libs.extn;
import
org.apache.myrmidon.components.classloader.test.libs.shared.SharedClass;
/**
* A test class loaded from an extension.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Adam Murdoch</a>
* @version $Revision: 1.1 $ $Date: 2002/04/03 10:58:20 $
*/
public class ExtnClass
{
public SharedClass m_test = new SharedClass();
}
1.1
jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/components/classloader/test/libs/extn/extn.txt
Index: extn.txt
===================================================================
A test resource loaded from an extension.
1.1
jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/components/classloader/test/libs/shared/SharedClass.java
Index: SharedClass.java
===================================================================
/*
* 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.components.classloader.test.libs.shared;
/**
* A test class.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Adam Murdoch</a>
* @version $Revision: 1.1 $ $Date: 2002/04/03 10:58:20 $
*/
public class SharedClass
{
}
1.1
jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/components/classloader/test/libs/shared/shared.txt
Index: shared.txt
===================================================================
A shared resource.
1.1
jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/components/classloader/test/libs/unshared/UnsharedClass.java
Index: UnsharedClass.java
===================================================================
/*
* 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.components.classloader.test.libs.unshared;
import
org.apache.myrmidon.components.classloader.test.libs.shared.SharedClass;
/**
* A test class.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Adam Murdoch</a>
* @version $Revision: 1.1 $ $Date: 2002/04/03 10:58:20 $
*/
public class UnsharedClass
{
public SharedClass m_test = new SharedClass();
}
1.1
jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/components/classloader/test/libs/unshared/unshared.txt
Index: unshared.txt
===================================================================
An unshared resource.
1.2 +43 -1
jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/components/embeddor/test/DefaultEmbeddorTest.java
Index: DefaultEmbeddorTest.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/myrmidon/src/test/org/apache/myrmidon/components/embeddor/test/DefaultEmbeddorTest.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DefaultEmbeddorTest.java 17 Mar 2002 08:07:09 -0000 1.1
+++ DefaultEmbeddorTest.java 3 Apr 2002 10:58:20 -0000 1.2
@@ -9,8 +9,10 @@
import java.io.File;
import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.logger.Logger;
import org.apache.myrmidon.AbstractProjectTest;
import org.apache.myrmidon.LogMessageTracker;
+import org.apache.myrmidon.components.embeddor.DefaultEmbeddor;
import org.apache.myrmidon.interfaces.embeddor.Embeddor;
import org.apache.myrmidon.interfaces.model.Project;
import org.apache.myrmidon.interfaces.model.Target;
@@ -21,17 +23,56 @@
* Test cases for the default embeddor.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Adam Murdoch</a>
- * @version $Revision: 1.1 $ $Date: 2002/03/17 08:07:09 $
+ * @version $Revision: 1.2 $ $Date: 2002/04/03 10:58:20 $
*/
public class DefaultEmbeddorTest
extends AbstractProjectTest
{
+ private DefaultEmbeddor m_embeddor;
+
public DefaultEmbeddorTest( String name )
{
super( name );
}
/**
+ * Tear-down the test.
+ */
+ protected void tearDown() throws Exception
+ {
+ if( m_embeddor != null )
+ {
+ m_embeddor.dispose();
+ m_embeddor = null;
+ }
+ }
+
+ /**
+ * Returns an embeddor which can be used to build and execute projects.
+ */
+ protected Embeddor getEmbeddor() throws Exception
+ {
+ if( m_embeddor == null )
+ {
+ // Need to set the context classloader - The default embeddor
uses it
+ Thread.currentThread().setContextClassLoader(
getClass().getClassLoader() );
+
+ final Logger logger = getLogger();
+ m_embeddor = new DefaultEmbeddor();
+ m_embeddor.enableLogging( logger );
+
+ final Parameters params = new Parameters();
+ final File instDir = getInstallDirectory();
+ params.setParameter( "myrmidon.home", instDir.getAbsolutePath()
);
+ m_embeddor.parameterize( params );
+ m_embeddor.initialize();
+ m_embeddor.start();
+ }
+
+ return m_embeddor;
+ }
+
+ /**
* Tests that a project is successfully built from a file.
*/
public void testProjectBuilder() throws Exception
@@ -63,6 +104,7 @@
public void testCreateListener() throws Exception
{
final ProjectListener listener = getEmbeddor().createListener(
"default" );
+ assertNotNull( listener );
}
/**
1.26 +15 -11 jakarta-ant/proposal/myrmidon/src/xdocs/todo.xml
Index: todo.xml
===================================================================
RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/xdocs/todo.xml,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- todo.xml 1 Apr 2002 00:46:26 -0000 1.25
+++ todo.xml 3 Apr 2002 10:58:20 -0000 1.26
@@ -524,23 +524,12 @@
<code><socket></code>
conditions to an antlib. Need to resolve how these will
be passed a logger.
</li>
- <li>Make the
- <code><uptodate></code> task a condition, and
move to
- an antlib.
- </li>
- <li>Split up
- <code><is-set></code> condition into is-set
and is-true conditions.
- </li>
<li>Allow the
<code><if></code> task to take any condition
implementation.
</li>
<li>Add an else block to the
<code><if></code> task.
</li>
- <li>Split the
- <code><available></code> condition into
separate conditions
- that test for the availability of a class, or a resource.
- </li>
<li>Move
<code>crimson.jar</code> to
<code>bin/lib</code> in the distribution,
@@ -550,6 +539,21 @@
<li>Add a <code>--type</code> command-line option, to
allow
the project builder to be manually selected.
</li>
+ <li>Change <code>ProjectBuilder</code>
+ and <code>Embeddor</code> to throw something more
+ specialised than Exception.
+ </li>
+ <li>Change <code>DefaultClassLoaderManager</code> to
handle
+ directories as part of a library classpath.
+ </li>
+ <li><code><condition></code> should set the
property
+ value to <code>false</code> when the condition is
false.</li>
+ <li>Split the <code><uptodate></code> condition
into
+ a condition that checks against a single target file,
+ and one which checks using a destdir/mapper.</li>
+ <li>Add a task to unset a property.</li>
+ <li>Change the various def and import task to allow a
classpath
+ to be provided.</li>
<li>Unit tests.</li>
</ul>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>