Browse Source

First pass of making ExecuteJava responsible for all java application

execution (after which it can be split into AUT):

* ExecuteJava now handles both in-jvm and forked java app execution.  Logging
  and error reporting are pretty rough.

* Moved most of the guts of <java> into ExecuteJava.

* Copied most of CommandlineJava into ExecuteJava.  Haven't changed
  CommandlineJava (much) yet.

* Removed the ability to use system properties when executing in-jvm.

* Another attempt at fixing the ant1 descriptor to enable <java> and <path>.


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271899 13f79535-47bb-0310-9956-ffa450edef68
master
adammurdoch 23 years ago
parent
commit
3fee832d25
8 changed files with 274 additions and 236 deletions
  1. +7
    -6
      proposal/myrmidon/build.xml
  2. +8
    -9
      proposal/myrmidon/src/manifest/ant1-ant-descriptor.xml
  3. +227
    -44
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/ExecuteJava.java
  4. +17
    -112
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Java.java
  5. +7
    -17
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/WLJspc.java
  6. +3
    -31
      proposal/myrmidon/src/todo/org/apache/tools/todo/types/CommandlineJava.java
  7. +4
    -16
      proposal/myrmidon/src/todo/org/apache/tools/todo/types/SysProperties.java
  8. +1
    -1
      proposal/myrmidon/src/todo/org/apache/tools/todo/util/FileUtils.java

+ 7
- 6
proposal/myrmidon/build.xml View File

@@ -235,7 +235,7 @@ Legal:
<patternset refid="myrmidon-api.include"/>
<patternset refid="myrmidon-container.include"/>
<patternset refid="aut.include"/>
<patternset refid="ant1.include"/>
<patternset refid="ant1.todo.include"/>
<patternset refid="selftest.include"/>
<patternset refid="selftest-extension1.include"/>
<include name="org/apache/antlib/**"/>
@@ -281,7 +281,7 @@ Legal:
<property name="util.package" value="${ant.package}/util"/>
<property name="regexp.package" value="${util.package}/regexp"/>

<patternset id="ant1.include">
<patternset id="ant1.todo.include">
<include name="org/apache/tools/**" />
<exclude name="${regexp.package}/JakartaRegexp*.java"
unless="jakarta.regexp.present" />
@@ -450,10 +450,11 @@ Legal:
<patternset refid="aut.include"/>
</antlib-jar>

<jar jarfile="${build.lib}/ant1.jar"
basedir="${build.classes}" >
<patternset refid="ant1.include"/>
</jar>
<antlib-jar jarfile="${build.lib}/ant1_todo.jar"
basedir="${build.classes}"
descriptor="${manifest.dir}/ant1-ant-descriptor.xml" >
<patternset refid="ant1.todo.include"/>
</antlib-jar>

<antlib-jar jarfile="${build.ext}/selftest.atl"
basedir="${build.classes}"


+ 8
- 9
proposal/myrmidon/src/manifest/ant1-ant-descriptor.xml View File

@@ -1,13 +1,12 @@
<ant-lib version="1.0">

<types>
<data-type name="path" classname="org.apache.tools.ant.types.Path" />
<task name="path" classname="org.apache.myrmidon.framework.TypeInstanceTask" />
<converter
classname="org.apache.tools.ant.types.converters.StringToPathConverter"
source="java.lang.String"
destination="org.apache.tools.ant.types.Path"
/>
</types>
<types>
<task name="java" classname="org.apache.tools.todo.taskdefs.Java" />
<data-type name="path" classname="org.apache.tools.todo.types.Path" />
<task name="path" classname="org.apache.myrmidon.framework.TypeInstanceTask" />
<converter classname="org.apache.tools.ant.types.converters.StringToPathConverter"
source="java.lang.String"
destination="org.apache.tools.ant.types.Path" />
</types>

</ant-lib>

+ 227
- 44
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/ExecuteJava.java View File

@@ -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 <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
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
// <JTULLEY@novell.com>
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";
}
}
}

+ 17
- 112
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Java.java View File

@@ -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 <a href="mailto:stefano@apache.org">
* stefano@apache.org</a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*
* @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() );
}
}

+ 7
- 17
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/WLJspc.java View File

@@ -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() );
}
}



+ 3
- 31
proposal/myrmidon/src/todo/org/apache/tools/todo/types/CommandlineJava.java View File

@@ -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
// <JTULLEY@novell.com>
return jExecutable.getAbsolutePath();
}
else
{
return "java";
}
}
}

+ 4
- 16
proposal/myrmidon/src/todo/org/apache/tools/todo/types/SysProperties.java View File

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



+ 1
- 1
proposal/myrmidon/src/todo/org/apache/tools/todo/util/FileUtils.java View File

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


Loading…
Cancel
Save