Browse Source

Add spawn attribute to java task as well

PR: 5907


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274992 13f79535-47bb-0310-9956-ffa450edef68
master
Antoine Levy-Lambert 22 years ago
parent
commit
3b3a4cd29f
5 changed files with 163 additions and 19 deletions
  1. +3
    -0
      WHATSNEW
  2. +8
    -0
      docs/manual/CoreTasks/java.html
  3. +25
    -15
      src/etc/testcases/taskdefs/java.xml
  4. +75
    -2
      src/main/org/apache/tools/ant/taskdefs/Java.java
  5. +52
    -2
      src/testcases/org/apache/tools/ant/taskdefs/JavaTest.java

+ 3
- 0
WHATSNEW View File

@@ -530,6 +530,9 @@ Other changes:
* <exec> will now have a new attribute spawn (default false). * <exec> will now have a new attribute spawn (default false).
If set to true, the process will be spawned. Bugzilla Report 5907. If set to true, the process will be spawned. Bugzilla Report 5907.


* <java> will now have a new attribute spawn (default false).
If set to true, the process will be spawned. Bugzilla Report 5907.

* <parallel> now supports a timeout which can be used to recover * <parallel> now supports a timeout which can be used to recover
from deadlocks, etc in the parallel threads. <parallel> also from deadlocks, etc in the parallel threads. <parallel> also
now supports a <daemons> nested element. This can be used to now supports a <daemons> nested element. This can be used to


+ 8
- 0
docs/manual/CoreTasks/java.html View File

@@ -56,6 +56,14 @@ JVM.
(disabled by default)</td> (disabled by default)</td>
<td align="center" valign="top">No</td> <td align="center" valign="top">No</td>
</tr> </tr>
<tr>
<td valign="top">spawn</td>
<td valign="top">if enabled allows to start a process which will outlive ant.<br/>
Requires fork=true, and not compatible
with timeout, input, output, error, result attributes.<br/>
(disabled by default)</td>
<td align="center" valign="top">No</td>
</tr>
<tr> <tr>
<td valign="top">jvm</td> <td valign="top">jvm</td>
<td valign="top">the command used to invoke the Java Virtual Machine, <td valign="top">the command used to invoke the Java Virtual Machine,


+ 25
- 15
src/etc/testcases/taskdefs/java.xml View File

@@ -2,41 +2,44 @@


<project name="java-test" basedir="." default="foo"> <project name="java-test" basedir="." default="foo">


<property name="app"
<property name="app"
value="org.apache.tools.ant.taskdefs.JavaTest$$EntryPoint" /> value="org.apache.tools.ant.taskdefs.JavaTest$$EntryPoint" />


<property name="app2"
<property name="app2"
value="org.apache.tools.ant.taskdefs.JavaTest$$ExceptingEntryPoint" /> value="org.apache.tools.ant.taskdefs.JavaTest$$ExceptingEntryPoint" />

<property name="spawnapp"
value="org.apache.tools.ant.taskdefs.JavaTest$$SpawnEntryPoint" />

<path id="test.classpath"> <path id="test.classpath">
<pathelement location="${build.tests}"/> <pathelement location="${build.tests}"/>
</path> </path>
<target name="testNoJarNoClassname"> <target name="testNoJarNoClassname">
<java/> <java/>
</target> </target>


<target name="testJarNoFork"> <target name="testJarNoFork">
<java jar="test.jar" fork="false"/> <java jar="test.jar" fork="false"/>
</target>
</target>
<target name="testJarAndClassName"> <target name="testJarAndClassName">
<java jar="test.jar" classname="${app}" /> <java jar="test.jar" classname="${app}" />
</target> </target>
<target name="testClassnameAndJar"> <target name="testClassnameAndJar">
<java classname="${app}" jar="test.jar" /> <java classname="${app}" jar="test.jar" />
</target>
</target>
<target name="testRun"> <target name="testRun">
<fail unless="tests-classpath.value" />
<fail unless="tests-classpath.value" />
<java classname="${app}" <java classname="${app}"
classpath="${tests-classpath.value}"/> classpath="${tests-classpath.value}"/>
</target> </target>


<target name="testRunFail"> <target name="testRunFail">
<java classname="${app}"
<java classname="${app}"
classpath="${tests-classpath.value}" classpath="${tests-classpath.value}"
> >
<arg value="-1"/> <arg value="-1"/>
@@ -88,7 +91,7 @@
fork="true"> fork="true">
</java> </java>
</target> </target>
<target name="testResultPropertyZero"> <target name="testResultPropertyZero">
<java classname="${app}" <java classname="${app}"
classpath="${tests-classpath.value}" classpath="${tests-classpath.value}"
@@ -97,7 +100,7 @@
</java> </java>
<echo message="exitcode = ${exitcode}"/> <echo message="exitcode = ${exitcode}"/>
</target> </target>
<target name="testResultPropertyNonZero"> <target name="testResultPropertyNonZero">
<java classname="${app}" <java classname="${app}"
classpath="${tests-classpath.value}" classpath="${tests-classpath.value}"
@@ -109,6 +112,13 @@
</java> </java>
<echo message="exitcode = ${exitcode}"/> <echo message="exitcode = ${exitcode}"/>
</target> </target>

<target name="testSpawn">
<java classname="${spawnapp}" fork="true" spawn="true" classpath="${tests-classpath.value}">
<arg value="${timeToWait}"/>
<arg value="${logFile}" />
</java>
</target>

<target name="foo" /> <target name="foo" />
</project> </project>

+ 75
- 2
src/main/org/apache/tools/ant/taskdefs/Java.java View File

@@ -94,6 +94,8 @@ public class Java extends Task {
private Long timeout = null; private Long timeout = null;
private Redirector redirector = new Redirector(this); private Redirector redirector = new Redirector(this);
private String resultProperty; private String resultProperty;
private boolean spawn = false;
private boolean incompatibleWithSpawn = false;
/** /**
* Do the execution. * Do the execution.
* @throws BuildException if failOnError is set to true and the application * @throws BuildException if failOnError is set to true and the application
@@ -136,7 +138,17 @@ public class Java extends Task {
throw new BuildException("Cannot execute a jar in non-forked mode." throw new BuildException("Cannot execute a jar in non-forked mode."
+ " Please set fork='true'. "); + " Please set fork='true'. ");
} }

if (spawn && !fork) {
throw new BuildException("Cannot spawn a java process in non-forked mode."
+ " Please set fork='true'. ");
}
if (spawn && incompatibleWithSpawn) {
getProject().log("spawn does not allow attributes related to input, "
+ "output, error, result", Project.MSG_ERR);
getProject().log("spawn does not also not allow timeout", Project.MSG_ERR);
throw new BuildException("You have used an attribute which is "
+ "not compatible with spawn");
}
if (fork) { if (fork) {
log(cmdl.describeCommand(), Project.MSG_VERBOSE); log(cmdl.describeCommand(), Project.MSG_VERBOSE);
} else { } else {
@@ -165,7 +177,12 @@ public class Java extends Task {


try { try {
if (fork) { if (fork) {
return run(cmdl.getCommandline());
if (!spawn) {
return run(cmdl.getCommandline());
} else {
spawn(cmdl.getCommandline());
return 0;
}
} else { } else {
try { try {
run(cmdl); run(cmdl);
@@ -191,6 +208,16 @@ public class Java extends Task {
} }
} }


/**
* set whether or not you want the process to be spawned
* default is not spawned
* @param spawn if true you do not want ant to wait for the end of the process
* @since ant 1.6
*/
public void setSpawn(boolean spawn) {
this.spawn = spawn;
}

/** /**
* Set the classpath to be used when running the Java class * Set the classpath to be used when running the Java class
* *
@@ -373,6 +400,7 @@ public class Java extends Task {
*/ */
public void setFailonerror(boolean fail) { public void setFailonerror(boolean fail) {
failOnError = fail; failOnError = fail;
incompatibleWithSpawn = true;
} }


/** /**
@@ -392,6 +420,7 @@ public class Java extends Task {
*/ */
public void setOutput(File out) { public void setOutput(File out) {
redirector.setOutput(out); redirector.setOutput(out);
incompatibleWithSpawn = true;
} }


/** /**
@@ -401,6 +430,7 @@ public class Java extends Task {
*/ */
public void setInput(File input) { public void setInput(File input) {
redirector.setInput(input); redirector.setInput(input);
incompatibleWithSpawn = true;
} }


/** /**
@@ -410,6 +440,7 @@ public class Java extends Task {
*/ */
public void setInputString(String inputString) { public void setInputString(String inputString) {
redirector.setInputString(inputString); redirector.setInputString(inputString);
incompatibleWithSpawn = true;
} }


/** /**
@@ -422,6 +453,7 @@ public class Java extends Task {
*/ */
public void setLogError(boolean logError) { public void setLogError(boolean logError) {
redirector.setLogError(logError); redirector.setLogError(logError);
incompatibleWithSpawn = true;
} }


/** /**
@@ -433,6 +465,7 @@ public class Java extends Task {
*/ */
public void setError(File error) { public void setError(File error) {
redirector.setError(error); redirector.setError(error);
incompatibleWithSpawn = true;
} }


/** /**
@@ -444,6 +477,7 @@ public class Java extends Task {
*/ */
public void setOutputproperty(String outputProp) { public void setOutputproperty(String outputProp) {
redirector.setOutputProperty(outputProp); redirector.setOutputProperty(outputProp);
incompatibleWithSpawn = true;
} }


/** /**
@@ -456,6 +490,7 @@ public class Java extends Task {
*/ */
public void setErrorProperty(String errorProperty) { public void setErrorProperty(String errorProperty) {
redirector.setErrorProperty(errorProperty); redirector.setErrorProperty(errorProperty);
incompatibleWithSpawn = true;
} }


/** /**
@@ -510,6 +545,7 @@ public class Java extends Task {
*/ */
public void setAppend(boolean append) { public void setAppend(boolean append) {
this.append = append; this.append = append;
incompatibleWithSpawn = true;
} }


/** /**
@@ -521,6 +557,7 @@ public class Java extends Task {
*/ */
public void setTimeout(Long value) { public void setTimeout(Long value) {
timeout = value; timeout = value;
incompatibleWithSpawn = true;
} }


/** /**
@@ -665,6 +702,42 @@ public class Java extends Task {
} }
} }


/**
* Executes the given classname with the given arguments in a separate VM.
*/
private void spawn(String[] command) throws BuildException {

Execute exe
= new Execute();
exe.setAntRun(getProject());

if (dir == null) {
dir = getProject().getBaseDir();
} else if (!dir.exists() || !dir.isDirectory()) {
throw new BuildException(dir.getAbsolutePath()
+ " is not a valid directory",
getLocation());
}

exe.setWorkingDirectory(dir);

String[] environment = env.getVariables();
if (environment != null) {
for (int i = 0; i < environment.length; i++) {
log("Setting environment variable: " + environment[i],
Project.MSG_VERBOSE);
}
}
exe.setNewenvironment(newEnvironment);
exe.setEnvironment(environment);

exe.setCommandline(command);
try {
exe.spawn();
} catch (IOException e) {
throw new BuildException(e, getLocation());
}
}
/** /**
* Executes the given classname with the given arguments as it * Executes the given classname with the given arguments as it
* was a command line application. * was a command line application.


+ 52
- 2
src/testcases/org/apache/tools/ant/taskdefs/JavaTest.java View File

@@ -57,6 +57,7 @@ package org.apache.tools.ant.taskdefs;
import junit.framework.*; import junit.framework.*;
import java.io.*; import java.io.*;
import org.apache.tools.ant.*; import org.apache.tools.ant.*;
import org.apache.tools.ant.util.FileUtils;


/** /**
* stress out java task * stress out java task
@@ -65,7 +66,8 @@ import org.apache.tools.ant.*;
* @author <a href="mailto:donal@savvion.com">Donal Quinlan</a> * @author <a href="mailto:donal@savvion.com">Donal Quinlan</a>
* */ * */
public class JavaTest extends BuildFileTest { public class JavaTest extends BuildFileTest {

private static final int TIME_TO_WAIT = 4;
private boolean runFatalTests=false; private boolean runFatalTests=false;
public JavaTest(String name) { public JavaTest(String name) {
@@ -176,7 +178,23 @@ public class JavaTest extends BuildFileTest {
executeTarget("testResultPropertyNonZero"); executeTarget("testResultPropertyNonZero");
assertEquals("-1",project.getProperty("exitcode")); assertEquals("-1",project.getProperty("exitcode"));
} }

public void testSpawn() {
FileUtils fileutils = FileUtils.newFileUtils();
File logFile = fileutils.createTempFile("spawn","log", project.getBaseDir());
// this is guaranteed by FileUtils#createTempFile
assertTrue("log file not existing", !logFile.exists());
project.setProperty("logFile", logFile.getAbsolutePath());
project.setProperty("timeToWait", Long.toString(TIME_TO_WAIT));
project.executeTarget("testSpawn");
try {
Thread.sleep(TIME_TO_WAIT * 1000 + 400);
} catch (Exception ex) {
System.out.println("my sleep was interrupted");
}
assertTrue("log file exists", logFile.exists());
}

/** /**
* entry point class with no dependencies other * entry point class with no dependencies other
* than normal JRE runtime * than normal JRE runtime
@@ -225,4 +243,36 @@ public class JavaTest extends BuildFileTest {
throw new NullPointerException("Exception raised inside called program"); throw new NullPointerException("Exception raised inside called program");
} }
} }
/**
* test class for spawn
*/
public static class SpawnEntryPoint {
public static void main(String [] argv) {
int sleepTime = 10;
String logFile = "spawn.log";
if (argv.length >= 1) {
sleepTime = Integer.parseInt(argv[0]);
}
if (argv.length >= 2)
{
logFile = argv[1];
}
OutputStreamWriter out = null;
try {
Thread.sleep(sleepTime * 1000);
} catch (InterruptedException ex) {
System.out.println("my sleep was interrupted");
}

try {
File dest = new File(logFile);
FileOutputStream fos = new FileOutputStream(dest);
out = new OutputStreamWriter(fos);
out.write("bye bye\n");
} catch (Exception ex) {}
finally {
try {out.close();} catch (IOException ioe) {}}

}
}
} }

Loading…
Cancel
Save