diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java index 236e01045..d392b945e 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java @@ -74,6 +74,7 @@ public class DefaultEmbeddor private File m_homeDir; private File m_taskLibDir; + private static final String MYRMIDON_HOME = "myrmidon.home"; /** * Setup basic properties of engine. @@ -133,6 +134,9 @@ public class DefaultEmbeddor { final Workspace workspace = (Workspace)createService( Workspace.class, PREFIX + "workspace.DefaultWorkspace" ); + // TODO - don't do this; need some way to pass separate sets of defines and config + // to the workspace + parameters.setParameter( MYRMIDON_HOME, m_parameters.getParameter( MYRMIDON_HOME ) ); setupObject( workspace, m_workspaceServiceManager, parameters ); return workspace; } @@ -186,7 +190,7 @@ public class DefaultEmbeddor throws Exception { // Deploy all type libraries found in the classpath - final ClassLoader libClassloader = Thread.currentThread().getContextClassLoader(); + final ClassLoader libClassloader = getClass().getClassLoader(); final TypeDeployer typeDeployer = m_deployer.createDeployer( libClassloader ); typeDeployer.deployAll(); @@ -297,7 +301,7 @@ public class DefaultEmbeddor { String filepath = null; - filepath = getParameter( "myrmidon.home" ); + filepath = getParameter( MYRMIDON_HOME ); m_homeDir = ( new File( filepath ) ).getAbsoluteFile(); checkDirectory( m_homeDir, "home-dir.name" ); diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java index 5f238c387..81dff63c7 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java @@ -147,7 +147,7 @@ public class DefaultWorkspace } private File findTypeLib( final String libraryName ) - throws TaskException + throws Exception { //TODO: In future this will be expanded to allow //users to specify search path or automagically @@ -155,7 +155,7 @@ public class DefaultWorkspace //workspace specific) final String name = libraryName.replace( '/', File.separatorChar ) + ".atl"; - final String home = System.getProperty( "myrmidon.home" ); + final String home = m_parameters.getParameter( "myrmidon.home" ); final File homeDir = new File( home + File.separatorChar + "ext" ); final File library = new File( homeDir, name ); @@ -178,7 +178,7 @@ public class DefaultWorkspace } private void deployTypeLib( final Deployer deployer, final Project project ) - throws TaskException + throws Exception { final TypeLib[] typeLibs = project.getTypeLibs(); @@ -213,7 +213,7 @@ public class DefaultWorkspace * Creates an execution frame for a project. */ private ExecutionFrame createExecutionFrame( final Project project ) - throws TaskException, ServiceException + throws Exception { //Create per frame ComponentManager final DefaultServiceManager serviceManager = diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/ExecManagerFactory.java b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/ExecManagerFactory.java index 7c3cedef2..ac91c15bc 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/ExecManagerFactory.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/ExecManagerFactory.java @@ -12,6 +12,9 @@ import org.apache.aut.nativelib.ExecException; import org.apache.aut.nativelib.impl.DefaultExecManager; import org.apache.avalon.excalibur.i18n.ResourceManager; import org.apache.avalon.excalibur.i18n.Resources; +import org.apache.avalon.framework.parameters.Parameterizable; +import org.apache.avalon.framework.parameters.Parameters; +import org.apache.avalon.framework.parameters.ParameterException; import org.apache.myrmidon.interfaces.service.AntServiceException; import org.apache.myrmidon.interfaces.service.ServiceFactory; @@ -22,23 +25,31 @@ import org.apache.myrmidon.interfaces.service.ServiceFactory; * @version $Revision$ $Date$ */ public class ExecManagerFactory - implements ServiceFactory + implements ServiceFactory, Parameterizable { private final static Resources REZ = ResourceManager.getPackageResources( ExecManagerFactory.class ); + private Parameters m_parameters; + + public void parameterize( final Parameters parameters ) + throws ParameterException + { + m_parameters = parameters; + } + /** * Create the ExecManager Service. */ public Object createService() throws AntServiceException { - final File home = getHomeDirectory(); try { + final File home = getHomeDirectory(); return new DefaultExecManager( home ); } - catch( final ExecException ee ) + catch( final Exception ee ) { throw new AntServiceException( ee.getMessage(), ee ); } @@ -47,10 +58,10 @@ public class ExecManagerFactory /** * Utility method to retrieve home directory. */ - private static File getHomeDirectory() - throws AntServiceException + private File getHomeDirectory() + throws Exception { - final String home = System.getProperty( "myrmidon.home" ); + final String home = m_parameters.getParameter( "myrmidon.home" ); if( null == home ) { final String message = REZ.getString( "missing-home-dir.error" ); diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/CLIMain.java b/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/CLIMain.java index 751a19a45..a90a0d5ec 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/CLIMain.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/CLIMain.java @@ -8,10 +8,12 @@ package org.apache.myrmidon.frontends; import java.io.BufferedReader; -import java.io.File; import java.io.InputStreamReader; +import java.io.File; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.HashMap; import org.apache.avalon.excalibur.cli.CLArgsParser; import org.apache.avalon.excalibur.cli.CLOption; import org.apache.avalon.excalibur.cli.CLOptionDescriptor; @@ -20,15 +22,9 @@ import org.apache.avalon.excalibur.i18n.ResourceManager; import org.apache.avalon.excalibur.i18n.Resources; import org.apache.avalon.framework.CascadingException; import org.apache.avalon.framework.ExceptionUtil; -import org.apache.avalon.framework.logger.AbstractLogEnabled; -import org.apache.avalon.framework.parameters.Parameters; import org.apache.myrmidon.Constants; import org.apache.myrmidon.api.TaskException; -import org.apache.myrmidon.interfaces.embeddor.Embeddor; import org.apache.myrmidon.interfaces.executor.Executor; -import org.apache.myrmidon.interfaces.model.Project; -import org.apache.myrmidon.interfaces.workspace.Workspace; -import org.apache.myrmidon.listeners.ProjectListener; /** * The class to kick the tires and light the fires. @@ -39,14 +35,10 @@ import org.apache.myrmidon.listeners.ProjectListener; * @version $Revision$ $Date$ */ public class CLIMain - extends AbstractLogEnabled { private final static Resources REZ = ResourceManager.getPackageResources( CLIMain.class ); - private static final String DEFAULT_EMBEDDOR_CLASS = - "org.apache.myrmidon.components.embeddor.DefaultEmbeddor"; - //defines for the Command Line options private final static int HELP_OPT = 'h'; private final static int QUIET_OPT = 'q'; @@ -84,23 +76,19 @@ public class CLIMain LISTENER_OPT, NO_PREFIX_OPT }; - ///Parameters for run of myrmidon - private Parameters m_parameters = new Parameters(); - ///List of targets supplied on command line to execute private ArrayList m_targets = new ArrayList(); - ///List of user supplied defines - private Parameters m_defines = new Parameters(); - - ///List of user supplied parameters for builder - private Parameters m_builderParameters = new Parameters(); - ///Determine whether tasks are actually executed private boolean m_dryRun = false; + ///Enables incremental mode + private boolean m_incremental; + + ///The launcher + private EmbeddedAnt m_embedded = new EmbeddedAnt(); + ///Log level to use - //private static Priority m_priority = Priority.WARN; private static int m_priority = BasicLogger.LEVEL_WARN; /** @@ -109,12 +97,24 @@ public class CLIMain * @param args the args */ public static void main( final String[] args ) + { + final Map properties = new HashMap(); + properties.put( "myrmidon.home", new File( "." ) ); + main( properties, args ); + } + + /** + * Main entry point called to run standard Myrmidon. + * + * @param args the args + */ + public static void main( final Map properties, final String[] args ) { int exitCode = 0; final CLIMain main = new CLIMain(); try { - main.execute( args ); + main.execute( properties, args ); } catch( final Throwable throwable ) { @@ -243,10 +243,10 @@ public class CLIMain return false; case HOME_DIR_OPT: - m_parameters.setParameter( "myrmidon.home", option.getArgument() ); + m_embedded.setEmbeddorProperty( "myrmidon.home", option.getArgument() ); break; case TASKLIB_DIR_OPT: - m_parameters.setParameter( "myrmidon.lib.path", option.getArgument() ); + m_embedded.setEmbeddorProperty( "myrmidon.lib.path", option.getArgument() ); break; case LOG_LEVEL_OPT: @@ -260,26 +260,26 @@ public class CLIMain break; case INCREMENTAL_OPT: - m_parameters.setParameter( "incremental", "true" ); + m_incremental = true; break; case FILE_OPT: - m_parameters.setParameter( "filename", option.getArgument() ); + m_embedded.setProjectFile( option.getArgument() ); break; case LISTENER_OPT: - m_parameters.setParameter( "listener", option.getArgument() ); + m_embedded.setListener( option.getArgument() ); break; case NO_PREFIX_OPT: - m_parameters.setParameter( "listener", "noprefix" ); + m_embedded.setListener( "noprefix" ); break; case DEFINE_OPT: - m_defines.setParameter( option.getArgument( 0 ), option.getArgument( 1 ) ); + m_embedded.setWorkspaceProperty( option.getArgument( 0 ), option.getArgument( 1 ) ); break; case BUILDER_PARAM_OPT: - m_builderParameters.setParameter( option.getArgument( 0 ), option.getArgument( 1 ) ); + m_embedded.setBuilderProperty( option.getArgument( 0 ), option.getArgument( 1 ) ); break; case DRY_RUN_OPT: @@ -295,61 +295,42 @@ public class CLIMain return true; } - private void setupDefaultParameters() - { - //System property set up by launcher - m_parameters.setParameter( "myrmidon.home", System.getProperty( "myrmidon.home", "." ) ); - - m_parameters.setParameter( "filename", "build.ant" ); - m_parameters.setParameter( "log.level", "WARN" ); - m_parameters.setParameter( "listener", "default" ); - m_parameters.setParameter( "incremental", "false" ); - } - - private void execute( final String[] args ) + private void execute( final Map properties, final String[] args ) throws Exception { - setupDefaultParameters(); - - if( !parseCommandLineOptions( args ) ) + try { - return; - } - - prepareLogging(); - - checkHomeDir(); - final File buildFile = getBuildFile(); - - //getLogger().debug( "Ant Bin Directory: " + m_binDir ); - //getLogger().debug( "Ant Lib Directory: " + m_libDir ); - //getLogger().debug( "Ant Task Lib Directory: " + m_taskLibDir ); + // Set system properties set up by launcher + m_embedded.setEmbeddorProperty( "myrmidon.home", properties.get( "myrmidon.home" ) ); - if( m_dryRun ) - { - m_parameters.setParameter( Executor.ROLE, - "org.apache.myrmidon.components.executor.PrintingExecutor" ); - } + // Command line + if( !parseCommandLineOptions( args ) ) + { + return; + } - final Embeddor embeddor = prepareEmbeddor(); + // Setup logging + final BasicLogger logger = new BasicLogger( "[myrmidon] ", m_priority ); + m_embedded.setLogger( logger ); - try - { - final ProjectListener listener = prepareListener( embeddor ); + if( m_dryRun ) + { + m_embedded.setEmbeddorProperty( Executor.ROLE, + "org.apache.myrmidon.components.executor.PrintingExecutor" ); + } - //create the project - final Project project = - embeddor.createProject( buildFile.toString(), null, m_builderParameters ); + // Set the common classloader + final ClassLoader sharedClassLoader = (ClassLoader)properties.get( "myrmidon.shared.classloader" ); + m_embedded.setSharedClassLoader( sharedClassLoader ); //loop over build if we are in incremental mode.. - final boolean incremental = m_parameters.getParameterAsBoolean( "incremental", false ); - if( !incremental ) + if( !m_incremental ) { - executeBuild( embeddor, project, listener ); + executeBuild(); } else { - executeIncrementalBuild( embeddor, project, listener ); + executeIncrementalBuild(); } } catch( final Exception e ) @@ -359,13 +340,11 @@ public class CLIMain } finally { - shutdownEmbeddor( embeddor ); + m_embedded.stop(); } } - private void executeIncrementalBuild( final Embeddor embeddor, - final Project project, - final ProjectListener listener ) + private void executeIncrementalBuild() throws Exception { BufferedReader reader = null; @@ -374,7 +353,7 @@ public class CLIMain { try { - executeBuild( embeddor, project, listener ); + executeBuild(); } catch( final TaskException te ) { @@ -398,6 +377,13 @@ public class CLIMain } } + private void executeBuild() throws Exception + { + //actually do the build ... + final String[] targets = (String[])m_targets.toArray( new String[m_targets.size() ] ); + m_embedded.executeTargets( targets ); + } + /** * Builds the error message for an exception */ @@ -426,131 +412,7 @@ public class CLIMain } // Write the message out - if( getLogger() == null ) - { - System.err.println( message ); - } - else - { - getLogger().error( message ); - } - } - - private void executeBuild( final Embeddor embeddor, - final Project project, - final ProjectListener listener ) - throws Exception - { - //actually do the build ... - final Workspace workspace = embeddor.createWorkspace( m_defines ); - workspace.addProjectListener( listener ); - - doBuild( workspace, project, m_targets ); - } - - private File getBuildFile() throws Exception - { - final String filename = m_parameters.getParameter( "filename", null ); - final File buildFile = ( new File( filename ) ).getCanonicalFile(); - if( !buildFile.isFile() ) - { - final String message = REZ.getString( "bad-file.error", buildFile ); - throw new Exception( message ); - } - - if( getLogger().isInfoEnabled() ) - { - final String message = REZ.getString( "buildfile.notice", buildFile ); - getLogger().info( message ); - } - - return buildFile; - } - - private void checkHomeDir() throws Exception - { - final String home = m_parameters.getParameter( "myrmidon.home" ); - final File homeDir = ( new File( home ) ).getAbsoluteFile(); - if( !homeDir.isDirectory() ) - { - final String message = REZ.getString( "home-not-dir.error", homeDir ); - throw new Exception( message ); - } - - if( getLogger().isInfoEnabled() ) - { - final String message = REZ.getString( "homedir.notice", homeDir ); - getLogger().info( message ); - } - } - - private void prepareLogging() throws Exception - { - //handle logging... - final BasicLogger logger = new BasicLogger( "[myrmidon] ", m_priority ); - enableLogging( logger ); - } - - private void shutdownEmbeddor( final Embeddor embeddor ) - throws Exception - { - embeddor.stop(); - embeddor.dispose(); - } - - private ProjectListener prepareListener( final Embeddor embeddor ) - throws Exception - { - //create the listener - final String listenerName = m_parameters.getParameter( "listener", null ); - final ProjectListener listener = embeddor.createListener( listenerName ); - return listener; - } - - private Embeddor prepareEmbeddor() - throws Exception - { - final Embeddor embeddor = createEmbeddor(); - setupLogger( embeddor ); - embeddor.parameterize( m_parameters ); - embeddor.initialize(); - embeddor.start(); - return embeddor; - } - - private Embeddor createEmbeddor() - throws Exception - { - final Class clazz = Class.forName( DEFAULT_EMBEDDOR_CLASS ); - return (Embeddor)clazz.newInstance(); - } - - /** - * Actually do the build. - * - * @param workspace the workspace - * @param project the project - * @param targets the targets to build as passed by CLI - */ - private void doBuild( final Workspace workspace, - final Project project, - final ArrayList targets ) - throws TaskException - { - final int targetCount = targets.size(); - - //if we didn't specify a target on CLI then choose default - if( 0 == targetCount ) - { - workspace.executeProject( project, project.getDefaultTargetName() ); - } - else - { - for( int i = 0; i < targetCount; i++ ) - { - workspace.executeProject( project, (String)targets.get( i ) ); - } - } + System.err.println( message ); } /** diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/EmbeddedAnt.java b/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/EmbeddedAnt.java new file mode 100644 index 000000000..d4ffefaad --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/frontends/EmbeddedAnt.java @@ -0,0 +1,295 @@ +/* + * 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.frontends; + +import java.io.File; +import org.apache.avalon.excalibur.i18n.ResourceManager; +import org.apache.avalon.excalibur.i18n.Resources; +import org.apache.avalon.framework.logger.AbstractLogEnabled; +import org.apache.avalon.framework.logger.Logger; +import org.apache.avalon.framework.parameters.Parameters; +import org.apache.myrmidon.api.TaskException; +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.listeners.ProjectListener; + +/** + * A utility class, that takes care of launching Myrmidon, and building and + * executing a project. + * + * @author Adam Murdoch + * @version $Revision$ $Date$ + */ +public class EmbeddedAnt + extends AbstractLogEnabled +{ + private final static Resources REZ + = ResourceManager.getPackageResources( EmbeddedAnt.class ); + + private static final String DEFAULT_EMBEDDOR_CLASS = + "org.apache.myrmidon.components.embeddor.DefaultEmbeddor"; + + private String m_projectFile = "build.ant"; + private Project m_project; + private String m_listenerName = "default"; + private ProjectListener m_listener; + private Parameters m_workspaceProps = new Parameters(); + private Parameters m_builderProps = new Parameters(); + private Parameters m_embeddorProps = new Parameters(); + private ClassLoader m_sharedClassLoader; + private Embeddor m_embeddor; + + /** + * Sets the logger to use. + */ + public void setLogger( final Logger logger ) + { + enableLogging( logger ); + } + + /** + * Sets the project file to execute. Default is 'build.ant'. + */ + public void setProjectFile( final String projectFile ) + { + m_projectFile = projectFile; + m_project = null; + } + + /** + * Sets the project to execute. This method can be used instead of + * {@link #setProjectFile}, for projects models that are built + * programmatically. + */ + public void setProject( final Project project ) + { + m_projectFile = null; + m_project = project; + } + + /** + * Sets the name of the project listener to use. + */ + public void setListener( final String listener ) + { + m_listenerName = listener; + m_listener = null; + } + + /** + * Sets the project listener to use. + */ + public void setListener( final ProjectListener listener ) + { + m_listenerName = null; + m_listener = listener; + } + + /** + * Sets a workspace property. These are inherited by all projects executed + * by this embeddor. + */ + public void setWorkspaceProperty( final String name, final Object value ) + { + // TODO - Make properties Objects, not Strings + m_workspaceProps.setParameter( name, (String)value ); + } + + /** + * Sets a project builder property. These are used by the project builder + * when it is parsing the project file. + */ + public void setBuilderProperty( final String name, final Object value ) + { + // TODO - Make properties Objects, not Strings + m_builderProps.setParameter( name, (String)value ); + } + + /** + * Sets a task engine property. These are used to configure the task engine. + */ + public void setEmbeddorProperty( final String name, final Object value ) + { + // TODO - Make properties Objects, not Strings + m_embeddorProps.setParameter( name, (String)value ); + } + + /** + * Sets the shared classloader, which is used as the parent classloader + * for all antlibs. Default is to use the context classloader. + */ + public void setSharedClassLoader( final ClassLoader classLoader ) + { + m_sharedClassLoader = classLoader; + } + + /** + * Executes a set of targets in the project. This method may be called + * multiple times. + */ + public void executeTargets( final String[] targets ) throws Exception + { + if( m_sharedClassLoader != null ) + { + Thread.currentThread().setContextClassLoader( m_sharedClassLoader ); + } + + checkHomeDir(); + + // Prepare the embeddor, project listener 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 ); + + //execute the project + executeTargets( workspace, project, targets ); + } + + /** + * Shuts down the task engine, after the project has been executed. + */ + public void stop() throws Exception + { + try + { + if( m_embeddor != null ) + { + m_embeddor.stop(); + m_embeddor.dispose(); + } + } + finally + { + m_embeddor = null; + m_project = null; + m_listener = null; + } + } + + /** + * Actually do the build. + */ + private void executeTargets( final Workspace workspace, + final Project project, + final String[] targets ) + throws TaskException + { + //if we didn't specify a target, then choose default + if( targets == null || targets.length == 0 ) + { + workspace.executeProject( project, project.getDefaultTargetName() ); + } + else + { + for( int i = 0; i < targets.length; i++ ) + { + workspace.executeProject( project, targets[ i ] ); + } + } + } + + /** + * Make sure myrmidon home directory has been specified, and is a + * directory. + */ + private void checkHomeDir() throws Exception + { + final String home = m_embeddorProps.getParameter( "myrmidon.home" ); + final File homeDir = ( new File( home ) ).getAbsoluteFile(); + if( !homeDir.isDirectory() ) + { + final String message = REZ.getString( "home-not-dir.error", homeDir ); + throw new Exception( message ); + } + + if( getLogger().isInfoEnabled() ) + { + final String message = REZ.getString( "homedir.notice", homeDir ); + getLogger().info( message ); + } + } + + /** + * Prepares and returns the embeddor to use. + */ + private Embeddor prepareEmbeddor() + throws Exception + { + if( m_embeddor == null ) + { + m_embeddor = createEmbeddor(); + setupLogger( m_embeddor ); + m_embeddor.parameterize( m_embeddorProps ); + m_embeddor.initialize(); + m_embeddor.start(); + } + return m_embeddor; + } + + /** + * Creates the embeddor. + */ + private Embeddor createEmbeddor() + throws Exception + { + final Class clazz = Class.forName( DEFAULT_EMBEDDOR_CLASS ); + return (Embeddor)clazz.newInstance(); + } + + /** + * Prepares and returns the project listener to use. + */ + private ProjectListener prepareListener( final Embeddor embeddor ) + throws Exception + { + if( m_listener == null ) + { + m_listener = embeddor.createListener( m_listenerName ); + } + return m_listener; + } + + /** + * Prepares and returns the project model. + */ + private Project prepareProjectModel( final Embeddor embeddor ) throws Exception + { + if( m_project == null ) + { + final File buildFile = getProjectFile(); + m_project = embeddor.createProject( buildFile.toString(), null, m_builderProps ); + } + return m_project; + } + + /** + * Locates the project file + */ + private File getProjectFile() throws Exception + { + final File projectFile = ( new File( m_projectFile ) ).getCanonicalFile(); + if( !projectFile.isFile() ) + { + final String message = REZ.getString( "bad-file.error", projectFile ); + throw new Exception( message ); + } + + if( getLogger().isInfoEnabled() ) + { + final String message = REZ.getString( "buildfile.notice", projectFile ); + getLogger().info( message ); + } + + return projectFile; + } +} diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/launcher/Main.java b/proposal/myrmidon/src/java/org/apache/myrmidon/launcher/Main.java index f9b58303f..32572dcd3 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/launcher/Main.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/launcher/Main.java @@ -14,6 +14,8 @@ import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.StringTokenizer; +import java.util.Map; +import java.util.HashMap; /** * Basic Loader that is responsible for all the hackery to get classloader to work. @@ -34,16 +36,26 @@ public final class Main { try { - //actually try to discover the install directory based on where - // the myrmidon.jar is + final Map properties = new HashMap(); + + // Try to discover the install directory based on where the + // launcher Jar is final File installDirectory = findInstallDir(); - System.setProperty( "myrmidon.home", installDirectory.toString() ); + properties.put( "myrmidon.home", installDirectory ); + + // Build the shared classloader + final URL[] sharedClassPath = getSharedClassPath( installDirectory ); + properties.put( "myrmidon.shared.classpath", sharedClassPath ); + final URLClassLoader sharedClassLoader = new URLClassLoader( sharedClassPath ); + properties.put( "myrmidon.shared.classloader", sharedClassLoader ); - final URLClassLoader sharedClassLoader = createSharedClassLoader( installDirectory ); - final URLClassLoader classLoader = - createContainerClassLoader( installDirectory, sharedClassLoader ); + // Build the container classloader + final URL[] containerClassPath = getContainerClassPath( installDirectory ); + properties.put( "myrmidon.container.classpath", containerClassPath ); + final URLClassLoader containerClassLoader = new URLClassLoader( containerClassPath, sharedClassLoader ); + properties.put( "myrmidon.container.classloader", containerClassLoader ); - execMainClass( classLoader, args ); + execMainClass( containerClassLoader, properties, args ); } catch( final InvocationTargetException ite ) { @@ -57,38 +69,42 @@ public final class Main } } - private static void execMainClass( final URLClassLoader classLoader, final String[] args ) + /** + * Executes the main class. + */ + private static void execMainClass( final ClassLoader classLoader, + final Map properties, + final String[] args ) throws Exception { //load class and retrieve appropriate main method. final Class clazz = classLoader.loadClass( "org.apache.myrmidon.frontends.CLIMain" ); - final Method method = clazz.getMethod( "main", new Class[]{args.getClass()} ); - - Thread.currentThread().setContextClassLoader( classLoader ); + final Method method = clazz.getMethod( "main", new Class[]{Map.class, args.getClass()} ); //kick the tires and light the fires.... - method.invoke( null, new Object[]{args} ); + method.invoke( null, new Object[]{properties, args} ); } - private static URLClassLoader createContainerClassLoader( final File installDirectory, - final URLClassLoader sharedClassLoader ) + /** + * Builds the classpath for the container classloader. + */ + private static URL[] getContainerClassPath( final File installDirectory ) throws Exception { + // Include everything from the bin/lib/ directory final File containerLibDir = new File( installDirectory, "bin" + File.separator + "lib" ); - final URL[] containerLibUrls = buildURLList( containerLibDir ); - final URLClassLoader classLoader = - new URLClassLoader( containerLibUrls, sharedClassLoader ); - return classLoader; + return buildURLList( containerLibDir ); } - private static URLClassLoader createSharedClassLoader( final File installDirectory ) + /** + * Builds the classpath for the shared classloader. + */ + private static URL[] getSharedClassPath( final File installDirectory ) throws Exception { - //setup classloader appropriately for myrmidon jar + // Include everything from the lib/ directory final File libDir = new File( installDirectory, "lib" ); - final URL[] libUrls = buildURLList( libDir ); - final URLClassLoader libClassLoader = new URLClassLoader( libUrls ); - return libClassLoader; + return buildURLList( libDir ); } private static final URL[] buildURLList( final File dir ) @@ -137,25 +153,23 @@ public final class Main final String classpath = System.getProperty( "java.class.path" ); final String pathSeparator = System.getProperty( "path.separator" ); final StringTokenizer tokenizer = new StringTokenizer( classpath, pathSeparator ); + final String jarName = "myrmidon-launcher.jar"; while( tokenizer.hasMoreTokens() ) { final String element = tokenizer.nextToken(); - - if( element.endsWith( "myrmidon-launcher.jar" ) ) + File file = ( new File( element ) ).getAbsoluteFile(); + if( file.isFile() && file.getName().equals( jarName ) ) { - File file = ( new File( element ) ).getAbsoluteFile(); file = file.getParentFile(); - if( null != file ) { file = file.getParentFile(); } - return file; } } - throw new Exception( "Unable to locate ant.jar in classpath" ); + throw new Exception( "Unable to locate " + jarName + " in classpath." ); } }