diff --git a/proposal/myrmidon/build.xml b/proposal/myrmidon/build.xml index 94932a015..403340475 100644 --- a/proposal/myrmidon/build.xml +++ b/proposal/myrmidon/build.xml @@ -235,7 +235,7 @@ Legal: - + @@ -281,7 +281,7 @@ Legal: - + @@ -450,10 +450,11 @@ Legal: - - - + + + - - - - - + + + + + + \ No newline at end of file diff --git a/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/ExecuteJava.java b/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/ExecuteJava.java index 3db6a880e..4b864b610 100644 --- a/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/ExecuteJava.java +++ b/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/ExecuteJava.java @@ -7,99 +7,282 @@ */ package org.apache.tools.todo.taskdefs; +import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; +import org.apache.myrmidon.api.TaskContext; import org.apache.myrmidon.api.TaskException; +import org.apache.myrmidon.framework.Execute; import org.apache.tools.todo.types.Commandline; import org.apache.tools.todo.types.Path; import org.apache.tools.todo.types.PathUtil; import org.apache.tools.todo.types.SysProperties; +import org.apache.tools.todo.util.FileUtils; +import org.apache.aut.nativelib.Os; -/* +/** + * A utility class that executes a Java app, either in this JVM, or a forked + * JVM. + * * @author thomas.haas@softwired-inc.com * @author Stefan Bodewig */ public class ExecuteJava { - private Commandline m_javaCommand; - private Path m_classpath; - private SysProperties m_sysProperties; + private final Path m_classPath = new Path(); + private final SysProperties m_sysProperties = new SysProperties(); + private final Commandline m_args = new Commandline(); + private final Commandline m_vmArgs = new Commandline(); + private boolean m_fork; + private File m_workingDirectory; + private File m_jar; + private String m_jvm; + private String m_className; + private String m_maxMemory; - public void setClasspath( final Path classpath ) + public void setClassName( final String className ) { - m_classpath = classpath; + m_className = className; } - public void setJavaCommand( final Commandline javaCommand ) + public void setJar( final File jar ) { - m_javaCommand = javaCommand; + m_jar = jar; } - public void setSystemProperties( final SysProperties sysProperties ) + public void setFork( final boolean fork ) { - m_sysProperties = sysProperties; + m_fork = fork; } - public void execute() - throws TaskException + public void setMaxMemory( final String maxMemory ) { - final String classname = m_javaCommand.getExecutable(); - final Object[] argument = new Object[]{m_javaCommand.getArguments()}; + m_maxMemory = maxMemory; + } - try + public void setWorkingDirectory( final File workingDirectory ) + { + m_workingDirectory = workingDirectory; + } + + public void setJvm( final String jvm ) + { + m_jvm = jvm; + } + + public Path getClassPath() + { + return m_classPath; + } + + public SysProperties getSysProperties() + { + return m_sysProperties; + } + + public Commandline getArguments() + { + return m_args; + } + + public Commandline getVmArguments() + { + return m_vmArgs; + } + + public void execute( final TaskContext context ) + throws TaskException + { + // Validate + if( m_className != null && m_jar != null ) + { + throw new TaskException( "Only one of Classname and Jar can be set." ); + } + else if( m_className == null && m_jar == null ) + { + throw new TaskException( "Classname must not be null." ); + } + if( ! m_fork ) { - if( m_sysProperties != null ) + if( m_jar != null ) { - m_sysProperties.setSystem(); + throw new TaskException( "Cannot execute a jar in non-forked mode." ); } - - final Class[] param = {Class.forName( "[Ljava.lang.String;" )}; - Class target = null; - if( m_classpath == null ) + if( m_vmArgs.size() > 0 ) { - target = Class.forName( classname ); + context.warn( "JVM args ignored when same JVM is used." ); } - else + if( m_workingDirectory != null ) { - final URL[] urls = PathUtil.toURLs( m_classpath ); - final URLClassLoader classLoader = new URLClassLoader( urls ); - target = classLoader.loadClass( classname ); + context.warn( "Working directory ignored when same JVM is used." ); + } + if( m_sysProperties.size() > 0 ) + { + context.warn( "System properties ignored when same JVM is used." ); } - final Method main = target.getMethod( "main", param ); - main.invoke( null, argument ); } - catch( NullPointerException e ) + + if( m_fork ) { - throw new TaskException( "Could not find main() method in " + classname ); + execForked( context ); } - catch( ClassNotFoundException e ) + else { - throw new TaskException( "Could not find " + classname + ". Make sure you have it in your classpath" ); + execNonForked( context ); } - catch( InvocationTargetException e ) + } + + /** + * Executes the app in this JVM. + */ + private void execNonForked( final TaskContext context ) + throws TaskException + { + final String[] args = m_args.getArguments(); + context.debug( "Running in same VM: " + m_className + " " + FileUtils.formatCommandLine( args ) ); + + // Locate the class + final Class target; + try { - Throwable t = e.getTargetException(); - if( !( t instanceof SecurityException ) ) + final URL[] urls = PathUtil.toURLs( m_classPath ); + if( urls.length == 0 ) { - throw new TaskException( "Error", t ); + target = Class.forName( m_className ); } else { - throw (SecurityException)t; + final URLClassLoader classLoader = new URLClassLoader( urls ); + target = classLoader.loadClass( m_className ); } } - catch( Exception e ) + catch( final Exception e ) { - throw new TaskException( "Error", e ); + throw new TaskException( "Could not find class \"" + m_className + "\".", e ); } - finally + + // Call the main method + try { - if( m_sysProperties != null ) - { - m_sysProperties.restoreSystem(); - } + final Class[] params = { args.getClass() }; + final Method main = target.getMethod( "main", params ); + main.invoke( null, new Object[] { args } ); + } + catch( final InvocationTargetException e ) + { + final Throwable t = e.getTargetException(); + throw new TaskException( "Could not execute class \"" + m_className + "\".", t ); + } + catch( final Exception e ) + { + throw new TaskException( "Could not execute class \"" + m_className + "\".", e ); + } + } + + /** + * Executes the given classname with the given arguments in a separate VM. + */ + private void execForked( final TaskContext context ) + throws TaskException + { + final Execute exe = new Execute(); + exe.setWorkingDirectory( m_workingDirectory ); + + // Setup the command line + final Commandline command = exe.getCommandline(); + + // Executable name + if( m_jvm != null ) + { + command.setExecutable( m_jvm ); + } + else + { + command.setExecutable( getJavaExecutableName() ); + } + + // JVM arguments + final String[] vmArgs = m_vmArgs.getArguments(); + command.addArguments( vmArgs ); + + // Max memory size + if( m_maxMemory != null ) + { + command.addArgument( "-Xmx" + m_maxMemory ); + } + + // System properties + final String[] props = m_sysProperties.getJavaVariables(); + command.addArguments( props ); + + // Classpath + if( ! m_classPath.isEmpty() ) + { + command.addArgument( "-classpath" ); + command.addArgument( PathUtil.formatPath( m_classPath ) ); + } + + // What to execute + if( m_jar != null ) + { + command.addArgument( "-jar" ); + command.addArgument( m_jar ); + } + else + { + command.addArgument( m_className ); + } + + // Java app arguments + final String[] args = m_args.getArguments(); + command.addArguments( args ); + + // Execute + exe.execute( context ); + } + + /** + * Determines the executable name for the java command for this JVM. + * + * @todo Move this to somewhere in AUT. + */ + public static String getJavaExecutableName() + { + if( Os.isFamily( Os.OS_FAMILY_NETWARE ) ) + { + // NetWare may have a "java" in the JRE directory, but 99% of + // the time, you don't want to execute it -- Jeff Tulley + // + return "java"; + } + + // Figure out the basename + final String baseName; + if( Os.isFamily( Os.OS_FAMILY_WINDOWS) || Os.isFamily( Os.OS_FAMILY_DOS ) ) + { + baseName = "java.exe"; + } + else + { + baseName = "java"; + } + + // Look for java in the ${java.home{/../bin directory. Unfortunately + // on Windows java.home doesn't always refer to the correct location, + // so we need to fall back to assuming java is somewhere on the + // PATH. + File javaExe = + new File( System.getProperty( "java.home" ) + "/../bin/" + baseName ); + + if( javaExe.exists() ) + { + return javaExe.getAbsolutePath(); + } + else + { + return "java"; } } } diff --git a/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Java.java b/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Java.java index b7a949e8b..c342a7010 100644 --- a/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Java.java +++ b/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Java.java @@ -8,14 +8,9 @@ package org.apache.tools.todo.taskdefs; import java.io.File; -import java.util.ArrayList; -import org.apache.aut.nativelib.ExecManager; import org.apache.myrmidon.api.AbstractTask; import org.apache.myrmidon.api.TaskException; -import org.apache.myrmidon.framework.Execute; import org.apache.tools.todo.types.Argument; -import org.apache.tools.todo.types.Commandline; -import org.apache.tools.todo.types.CommandlineJava; import org.apache.tools.todo.types.EnvironmentVariable; import org.apache.tools.todo.types.Path; @@ -26,20 +21,20 @@ import org.apache.tools.todo.types.Path; * @author Stefano Mazzocchi * stefano@apache.org * @author Stefan Bodewig + * + * @ant:task name="java" */ public class Java extends AbstractTask { - private CommandlineJava m_cmdl = new CommandlineJava(); - private boolean m_fork; - private File m_dir; + private final ExecuteJava m_exec = new ExecuteJava(); /** * Set the class name. */ - public void setClassname( String s ) + public void setClassname( final String className ) { - m_cmdl.setClassname( s ); + m_exec.setClassName( className ); } /** @@ -48,7 +43,7 @@ public class Java public void addClasspath( final Path classpath ) throws TaskException { - m_cmdl.createClasspath().addPath( classpath ); + m_exec.getClassPath().addPath( classpath ); } /** @@ -58,7 +53,7 @@ public class Java */ public void setDir( final File dir ) { - m_dir = dir; + m_exec.setWorkingDirectory( dir ); } /** @@ -66,23 +61,23 @@ public class Java */ public void setFork( final boolean fork ) { - m_fork = fork; + m_exec.setFork( fork ); } /** - * set the jar name... + * Set the jar name. */ public void setJar( final File jar ) { - m_cmdl.setJar( jar.getAbsolutePath() ); + m_exec.setJar( jar ); } /** - * Set the command used to start the VM (only if fork==false). + * Set the command used to start the VM (only if fork==true). */ public void setJvm( final String jvm ) { - m_cmdl.setVm( jvm ); + m_exec.setJvm( jvm ); } /** @@ -90,7 +85,7 @@ public class Java */ public void setMaxmemory( final String max ) { - m_cmdl.setMaxmemory( max ); + m_exec.setMaxMemory( max ); } /** @@ -98,7 +93,7 @@ public class Java */ public void addSysproperty( final EnvironmentVariable sysp ) { - m_cmdl.addSysproperty( sysp ); + m_exec.getSysProperties().addVariable( sysp ); } /** @@ -106,7 +101,7 @@ public class Java */ public void addArg( final Argument argument ) { - m_cmdl.addArgument( argument ); + m_exec.getArguments().addArgument( argument ); } /** @@ -114,102 +109,12 @@ public class Java */ public void addJvmarg( final Argument argument ) { - m_cmdl.addVmArgument( argument ); + m_exec.getVmArguments().addArgument( argument ); } public void execute() throws TaskException { - executeJava(); - } - - /** - * Do the execution. - * - * @exception org.apache.myrmidon.api.TaskException Description of Exception - */ - public void executeJava() - throws TaskException - { - final String classname = m_cmdl.getClassname(); - final String jar = m_cmdl.getJar(); - if( classname != null && jar != null ) - { - throw new TaskException( "Only one of Classname and Jar can be set." ); - } - else if( classname == null && jar == null ) - { - throw new TaskException( "Classname must not be null." ); - } - - if( !m_fork && jar != null ) - { - throw new TaskException( "Cannot execute a jar in non-forked mode. Please set fork='true'. " ); - } - - if( m_fork ) - { - getContext().debug( "Forking " + m_cmdl.toString() ); - run( new Commandline( m_cmdl.getCommandline() ) ); - } - else - { - if( m_cmdl.getVmCommand().size() > 1 ) - { - getContext().warn( "JVM args ignored when same JVM is used." ); - } - if( m_dir != null ) - { - getContext().warn( "Working directory ignored when same JVM is used." ); - } - - getContext().debug( "Running in same VM " + m_cmdl.getJavaCommand().toString() ); - run( m_cmdl ); - } - } - - /** - * Executes the given classname with the given arguments as it was a command - * line application. - */ - protected void run( final String classname, final ArrayList args ) - throws TaskException - { - final CommandlineJava java = new CommandlineJava(); - java.setClassname( classname ); - - final int size = args.size(); - for( int i = 0; i < size; i++ ) - { - final String arg = (String)args.get( i ); - java.addArgument( arg ); - } - run( java ); - } - - /** - * Executes the given classname with the given arguments as it was a command - * line application. - */ - private void run( final CommandlineJava command ) - throws TaskException - { - final ExecuteJava exe = new ExecuteJava(); - exe.setJavaCommand( command.getJavaCommand() ); - exe.setClasspath( command.getClasspath() ); - exe.setSystemProperties( command.getSystemProperties() ); - exe.execute(); - } - - /** - * Executes the given classname with the given arguments in a separate VM. - */ - private void run( final Commandline command ) - throws TaskException - { - final Execute exe = new Execute(); - exe.setWorkingDirectory( m_dir ); - exe.setCommandline( command ); - exe.execute( getContext() ); + m_exec.execute( getContext() ); } } diff --git a/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/WLJspc.java b/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/WLJspc.java index a98b9a8eb..0dfab1b73 100644 --- a/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/WLJspc.java +++ b/proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/WLJspc.java @@ -12,9 +12,8 @@ import java.util.ArrayList; import java.util.Date; import java.util.StringTokenizer; import org.apache.myrmidon.api.TaskException; -import org.apache.tools.todo.taskdefs.Java; +import org.apache.tools.todo.taskdefs.ExecuteJava; import org.apache.tools.todo.taskdefs.MatchingTask; -import org.apache.tools.todo.types.Argument; import org.apache.tools.todo.types.DirectoryScanner; import org.apache.tools.todo.types.Path; import org.apache.tools.todo.types.PathUtil; @@ -172,9 +171,6 @@ public class WLJspc extends MatchingTask // Therefore, takes loads of time // Can pass directories at a time (*.jsp) but easily runs out of memory on hefty dirs // (even on a Sun) - Java helperTask = null;//(Java)getProject().createTask( "java" ); - helperTask.setFork( true ); - helperTask.setClassname( "weblogic.jspc" ); String[] args = new String[ 12 ]; File jspFile = null; @@ -220,19 +216,13 @@ public class WLJspc extends MatchingTask } args[ j + 2 ] = sourceDirectory + File.separator + (String)filesToDo.get( i ); - arg = ""; - for( int x = 0; x < 12; x++ ) - { - arg += " " + args[ x ]; - } - - System.out.println( "arg = " + arg ); - - //helperTask.clearArgs(); - helperTask.addArg( new Argument( arg ) ); - helperTask.addClasspath( compileClasspath ); - helperTask.executeJava(); + ExecuteJava helperTask = new ExecuteJava(); + helperTask.setFork( true ); + helperTask.setClassName( "weblogic.jspc" ); + helperTask.getArguments().addArguments( args ); + helperTask.getClassPath().addPath( compileClasspath ); + helperTask.execute( getContext() ); } } diff --git a/proposal/myrmidon/src/todo/org/apache/tools/todo/types/CommandlineJava.java b/proposal/myrmidon/src/todo/org/apache/tools/todo/types/CommandlineJava.java index 5867dbbbc..8537210ec 100644 --- a/proposal/myrmidon/src/todo/org/apache/tools/todo/types/CommandlineJava.java +++ b/proposal/myrmidon/src/todo/org/apache/tools/todo/types/CommandlineJava.java @@ -7,12 +7,11 @@ */ package org.apache.tools.todo.types; -import java.io.File; -import org.apache.aut.nativelib.Os; import org.apache.avalon.excalibur.util.StringUtil; import org.apache.myrmidon.api.TaskException; import org.apache.tools.todo.types.Argument; import org.apache.tools.todo.types.Commandline; +import org.apache.tools.todo.taskdefs.ExecuteJava; /** * A representation of a Java command line that is nothing more than a composite @@ -39,7 +38,7 @@ public class CommandlineJava public CommandlineJava() { - setVm( getJavaExecutableName() ); + setVm( ExecuteJava.getJavaExecutableName() ); } /** @@ -71,7 +70,7 @@ public class CommandlineJava */ public void setMaxmemory( String max ) { - this.m_maxMemory = max; + m_maxMemory = max; } public void setSystemProperties() @@ -261,31 +260,4 @@ public class CommandlineJava } return actualVMCommand; } - - private String getJavaExecutableName() - { - // This is the most common extension case - exe for windows and OS/2, - // nothing for *nix. - String extension = Os.isFamily( Os.OS_FAMILY_DOS ) ? ".exe" : ""; - - // Look for java in the java.home/../bin directory. Unfortunately - // on Windows java.home doesn't always refer to the correct location, - // so we need to fall back to assuming java is somewhere on the - // PATH. - File jExecutable = - new File( System.getProperty( "java.home" ) + - "/../bin/java" + extension ); - - if( jExecutable.exists() && !Os.isFamily( Os.OS_FAMILY_NETWARE ) ) - { - // NetWare may have a "java" in that directory, but 99% of - // the time, you don't want to execute it -- Jeff Tulley - // - return jExecutable.getAbsolutePath(); - } - else - { - return "java"; - } - } } diff --git a/proposal/myrmidon/src/todo/org/apache/tools/todo/types/SysProperties.java b/proposal/myrmidon/src/todo/org/apache/tools/todo/types/SysProperties.java index bd7c61dcc..96e1bba55 100644 --- a/proposal/myrmidon/src/todo/org/apache/tools/todo/types/SysProperties.java +++ b/proposal/myrmidon/src/todo/org/apache/tools/todo/types/SysProperties.java @@ -44,24 +44,13 @@ public class SysProperties } } + /** + * @todo move this to AUT + */ public String[] getJavaVariables() throws TaskException { - String props[] = new String[ 0 ]; - try - { - props = toNativeFormat( super.getVariables() ); - } - catch( final ExecException ee ) - { - throw new TaskException( ee.getMessage(), ee ); - } - - if( props == null ) - { - return null; - } - + String props[] = toNativeFormat( super.getVariables() ); for( int i = 0; i < props.length; i++ ) { props[ i ] = "-D" + props[ i ]; @@ -108,7 +97,6 @@ public class SysProperties } private String[] toNativeFormat( final Properties environment ) - throws ExecException { final ArrayList newEnvironment = new ArrayList(); diff --git a/proposal/myrmidon/src/todo/org/apache/tools/todo/util/FileUtils.java b/proposal/myrmidon/src/todo/org/apache/tools/todo/util/FileUtils.java index 87e9c5e07..079611d6f 100644 --- a/proposal/myrmidon/src/todo/org/apache/tools/todo/util/FileUtils.java +++ b/proposal/myrmidon/src/todo/org/apache/tools/todo/util/FileUtils.java @@ -189,7 +189,7 @@ public class FileUtils * @todo Move to {@link org.apache.aut.nativelib.Os}, and get rid of the * exception. */ - public static String buildCommandLine( final String[] arguments ) + public static String formatCommandLine( final String[] arguments ) throws TaskException { final StringBuffer cmd = new StringBuffer();