diff --git a/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java b/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
index b2b327382..60d874281 100644
--- a/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
+++ b/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2004 The Apache Software Foundation
+ * Copyright 2000-2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,9 +15,10 @@
*
*/
-
package org.apache.tools.ant.taskdefs;
+import java.io.File;
+import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -25,11 +26,14 @@ import java.lang.reflect.Modifier;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.condition.Os;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.CommandlineJava;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Permissions;
+import org.apache.tools.ant.util.JavaEnvUtils;
import org.apache.tools.ant.util.TimeoutObserver;
import org.apache.tools.ant.util.Watchdog;
@@ -226,4 +230,76 @@ public class ExecuteJava implements Runnable, TimeoutObserver {
public synchronized boolean killedProcess() {
return timedOut;
}
+
+ /**
+ * Runs the Java command in a separate VM, this does not give you
+ * the full flexibility of the Java task, but may be enough for
+ * simple needs.
+ *
+ * @since Ant 1.6.3
+ */
+ public int fork(ProjectComponent pc) throws BuildException {
+ CommandlineJava cmdl = new CommandlineJava();
+ cmdl.setClassname(javaCommand.getExecutable());
+ String[] args = javaCommand.getArguments();
+ for (int i = 0; i < args.length; i++) {
+ cmdl.createArgument().setValue(args[i]);
+ }
+ if (classpath != null) {
+ cmdl.createClasspath(pc.getProject()).append(classpath);
+ }
+ if (sysProperties != null) {
+ cmdl.addSysproperties(sysProperties);
+ }
+
+ Redirector redirector = new Redirector(pc);
+ Execute exe
+ = new Execute(redirector.createHandler(),
+ timeout == null
+ ? null
+ : new ExecuteWatchdog(timeout.longValue()));
+ exe.setAntRun(pc.getProject());
+ if (Os.isFamily("openvms")) {
+ setupCommandLineForVMS(exe, cmdl.getCommandline());
+ } else {
+ exe.setCommandline(cmdl.getCommandline());
+ }
+ try {
+ int rc = exe.execute();
+ redirector.complete();
+ timedOut = exe.killedProcess();
+ return rc;
+ } catch (IOException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * On VMS platform, we need to create a special java options file
+ * containing the arguments and classpath for the java command.
+ * The special file is supported by the "-V" switch on the VMS JVM.
+ *
+ * @param exe
+ * @param command
+ */
+ public static void setupCommandLineForVMS(Execute exe, String[] command) {
+ //Use the VM launcher instead of shell launcher on VMS
+ exe.setVMLauncher(true);
+ File vmsJavaOptionFile = null;
+ try {
+ String [] args = new String[command.length - 1];
+ System.arraycopy(command, 1, args, 0, command.length - 1);
+ vmsJavaOptionFile = JavaEnvUtils.createVmsJavaOptionFile(args);
+ //we mark the file to be deleted on exit.
+ //the alternative would be to cache the filename and delete
+ //after execution finished, which is much better for long-lived runtimes
+ //though spawning complicates things...
+ vmsJavaOptionFile.deleteOnExit();
+ String [] vmsCmd = {command[0], "-V", vmsJavaOptionFile.getPath()};
+ exe.setCommandline(vmsCmd);
+ } catch (IOException e) {
+ throw new BuildException("Failed to create a temporary file for \"-V\" switch");
+ }
+ }
+
}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Java.java b/src/main/org/apache/tools/ant/taskdefs/Java.java
index 68b5f5f35..3cea9c1ae 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Java.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Java.java
@@ -840,23 +840,7 @@ public class Java extends Task {
* @param command
*/
private void setupCommandLineForVMS(Execute exe, String[] command) {
- //Use the VM launcher instead of shell launcher on VMS
- exe.setVMLauncher(true);
- File vmsJavaOptionFile = null;
- try {
- String [] args = new String[command.length - 1];
- System.arraycopy(command, 1, args, 0, command.length - 1);
- vmsJavaOptionFile = JavaEnvUtils.createVmsJavaOptionFile(args);
- //we mark the file to be deleted on exit.
- //the alternative would be to cache the filename and delete
- //after execution finished, which is much better for long-lived runtimes
- //though spawning complicates things...
- vmsJavaOptionFile.deleteOnExit();
- String [] vmsCmd = {command[0], "-V", vmsJavaOptionFile.getPath()};
- exe.setCommandline(vmsCmd);
- } catch (IOException e) {
- throw new BuildException("Failed to create a temporary file for \"-V\" switch");
- }
+ ExecuteJava.setupCommandLineForVMS(exe, command);
}
/**
diff --git a/src/main/org/apache/tools/ant/taskdefs/LogOutputStream.java b/src/main/org/apache/tools/ant/taskdefs/LogOutputStream.java
index 8b78e5f2e..263ba531a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/LogOutputStream.java
+++ b/src/main/org/apache/tools/ant/taskdefs/LogOutputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2004 The Apache Software Foundation
+ * Copyright 2000-2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
import org.apache.tools.ant.Task;
@@ -48,7 +49,7 @@ public class LogOutputStream extends OutputStream {
= new ByteArrayOutputStream(INTIAL_SIZE);
private boolean skip = false;
- private Task task;
+ private ProjectComponent pc;
private int level = Project.MSG_INFO;
/**
@@ -58,7 +59,18 @@ public class LogOutputStream extends OutputStream {
* @param level loglevel used to log data written to this stream.
*/
public LogOutputStream(Task task, int level) {
- this.task = task;
+ this((ProjectComponent) task, level);
+ }
+
+ /**
+ * Creates a new instance of this class.
+ *
+ * @param task the task for whom to log
+ * @param level loglevel used to log data written to this stream.
+ * @since Ant 1.6.3
+ */
+ public LogOutputStream(ProjectComponent pc, int level) {
+ this.pc = pc;
this.level = level;
}
@@ -114,7 +126,7 @@ public class LogOutputStream extends OutputStream {
* @param line the line to log.
*/
protected void processLine(String line, int level) {
- task.log(line, level);
+ pc.log(line, level);
}
diff --git a/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java b/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java
index 5d5074ff1..36e8738bf 100644
--- a/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java
+++ b/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000,2002,2004 The Apache Software Foundation
+ * Copyright 2000,2002,2004-2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ package org.apache.tools.ant.taskdefs;
import java.io.IOException;
import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
import org.apache.tools.ant.Task;
/**
@@ -36,8 +37,19 @@ public class LogStreamHandler extends PumpStreamHandler {
* @param errlevel the loglevel used to log standard error
*/
public LogStreamHandler(Task task, int outlevel, int errlevel) {
- super(new LogOutputStream(task, outlevel),
- new LogOutputStream(task, errlevel));
+ this((ProjectComponent) task, outlevel, errlevel);
+ }
+
+ /**
+ * Creates log stream handler
+ *
+ * @param pc the project component for whom to log
+ * @param outlevel the loglevel used to log standard output
+ * @param errlevel the loglevel used to log standard error
+ */
+ public LogStreamHandler(ProjectComponent pc, int outlevel, int errlevel) {
+ super(new LogOutputStream(pc, outlevel),
+ new LogOutputStream(pc, errlevel));
}
/**
diff --git a/src/main/org/apache/tools/ant/taskdefs/Redirector.java b/src/main/org/apache/tools/ant/taskdefs/Redirector.java
index 4ba4a6257..54b234ee7 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Redirector.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Redirector.java
@@ -31,8 +31,9 @@ import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.Vector;
-import org.apache.tools.ant.Task;
import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.Task;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.filters.util.ChainReaderHelper;
import org.apache.tools.ant.util.StringUtils;
@@ -46,7 +47,7 @@ import org.apache.tools.ant.util.KeepAliveOutputStream;
/**
* The Redirector class manages the setup and connection of
- * input and output redirection for an Ant task.
+ * input and output redirection for an Ant project component.
*
* @since Ant 1.6
*/
@@ -125,7 +126,7 @@ public class Redirector {
private boolean createEmptyFiles = true;
/** The task for which this redirector is working */
- private Task managingTask;
+ private ProjectComponent managingTask;
/** The stream for output data */
private OutputStream outputStream = null;
@@ -172,6 +173,17 @@ public class Redirector {
* @param managingTask the task for which the redirector is to work
*/
public Redirector(Task managingTask) {
+ this((ProjectComponent) managingTask);
+ }
+
+ /**
+ * Create a redirector instance for the given task
+ *
+ * @param managingTask the project component for which the
+ * redirector is to work
+ * @since Ant 1.6.3
+ */
+ public Redirector(ProjectComponent managingTask) {
this.managingTask = managingTask;
}
@@ -498,7 +510,7 @@ public class Redirector {
|| !(outputEncoding.equalsIgnoreCase(inputEncoding))) {
try {
LeadPipeInputStream snk = new LeadPipeInputStream();
- snk.setManagingTask(managingTask);
+ snk.setManagingComponent(managingTask);
InputStream outPumpIn = snk;
@@ -527,7 +539,7 @@ public class Redirector {
|| !(errorEncoding.equalsIgnoreCase(inputEncoding))) {
try {
LeadPipeInputStream snk = new LeadPipeInputStream();
- snk.setManagingTask(managingTask);
+ snk.setManagingComponent(managingTask);
InputStream errPumpIn = snk;
@@ -563,7 +575,7 @@ public class Redirector {
} catch (IOException eyeOhEx) {
throw new BuildException(eyeOhEx);
}
- ((ConcatFileInputStream) inputStream).setManagingTask(managingTask);
+ ((ConcatFileInputStream) inputStream).setManagingComponent(managingTask);
} else if (inputString != null) {
managingTask.log("Using input \"" + inputString + "\"",
Project.MSG_VERBOSE);
diff --git a/src/main/org/apache/tools/ant/types/CommandlineJava.java b/src/main/org/apache/tools/ant/types/CommandlineJava.java
index 81734e6fe..8e0f7b6f6 100644
--- a/src/main/org/apache/tools/ant/types/CommandlineJava.java
+++ b/src/main/org/apache/tools/ant/types/CommandlineJava.java
@@ -191,6 +191,16 @@ public class CommandlineJava implements Cloneable {
propertySets.addElement(ps);
}
+ /**
+ * add a propertyset to the total set
+ * @param ps the new property set
+ * @since Ant 1.6.3
+ */
+ public void addSysproperties(SysProperties ps) {
+ variables.addAll(ps.variables);
+ propertySets.addAll(ps.propertySets);
+ }
+
/**
* merge all property sets into a single Properties object
* @return the merged object
@@ -204,6 +214,7 @@ public class CommandlineJava implements Cloneable {
}
return p;
}
+
}
/**
@@ -246,6 +257,15 @@ public class CommandlineJava implements Cloneable {
sysProperties.addSyspropertyset(sysp);
}
+ /**
+ * add a set of system properties
+ * @param sysp a set of properties
+ * @since Ant 1.6.3
+ */
+ public void addSysproperties(SysProperties sysp) {
+ sysProperties.addSysproperties(sysp);
+ }
+
/**
* Set the executable used to start the new JVM.
* @param vm the executable to use
diff --git a/src/main/org/apache/tools/ant/util/ConcatFileInputStream.java b/src/main/org/apache/tools/ant/util/ConcatFileInputStream.java
index aa66ce868..f401424e7 100755
--- a/src/main/org/apache/tools/ant/util/ConcatFileInputStream.java
+++ b/src/main/org/apache/tools/ant/util/ConcatFileInputStream.java
@@ -23,8 +23,9 @@ import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.FileInputStream;
-import org.apache.tools.ant.Task;
import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.Task;
/**
* Special InputStream
that will
@@ -37,7 +38,7 @@ public class ConcatFileInputStream extends InputStream {
private boolean eof = false;
private File[] file;
private InputStream currentStream;
- private Task managingTask;
+ private ProjectComponent managingPc;
/**
* Construct a new ConcatFileInputStream
@@ -71,7 +72,16 @@ public class ConcatFileInputStream extends InputStream {
* @param task the managing Task
.
*/
public void setManagingTask(Task task) {
- this.managingTask = task;
+ setManagingComponent(task);
+ }
+
+ /**
+ * Set a managing Task
for
+ * this ConcatFileInputStream
.
+ * @param task the managing Task
.
+ */
+ public void setManagingComponent(ProjectComponent pc) {
+ this.managingPc = pc;
}
/**
@@ -80,8 +90,8 @@ public class ConcatFileInputStream extends InputStream {
* @param loglevel the int
logging level.
*/
public void log(String message, int loglevel) {
- if (managingTask != null) {
- managingTask.log(message, loglevel);
+ if (managingPc != null) {
+ managingPc.log(message, loglevel);
} else {
if (loglevel > Project.MSG_WARN) {
System.out.println(message);
diff --git a/src/main/org/apache/tools/ant/util/LeadPipeInputStream.java b/src/main/org/apache/tools/ant/util/LeadPipeInputStream.java
index 3a0187966..b6675d438 100755
--- a/src/main/org/apache/tools/ant/util/LeadPipeInputStream.java
+++ b/src/main/org/apache/tools/ant/util/LeadPipeInputStream.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
+import org.apache.tools.ant.ProjectComponent;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.Project;
@@ -29,7 +30,7 @@ import org.apache.tools.ant.Project;
* when the writing Thread
is no longer alive.
*/
public class LeadPipeInputStream extends PipedInputStream {
- private Task managingTask;
+ private ProjectComponent managingPc;
/**
* Construct a new LeadPipeInputStream
.
@@ -73,7 +74,16 @@ public class LeadPipeInputStream extends PipedInputStream {
* @param task the managing Task
.
*/
public void setManagingTask(Task task) {
- this.managingTask = task;
+ setManagingComponent(task);
+ }
+
+ /**
+ * Set a managing ProjectComponent
for
+ * this LeadPipeInputStream
.
+ * @param pc the managing ProjectComponent
.
+ */
+ public void setManagingComponent(ProjectComponent pc) {
+ this.managingPc = pc;
}
/**
@@ -82,8 +92,8 @@ public class LeadPipeInputStream extends PipedInputStream {
* @param loglevel the int
logging level.
*/
public void log(String message, int loglevel) {
- if (managingTask != null) {
- managingTask.log(message, loglevel);
+ if (managingPc != null) {
+ managingPc.log(message, loglevel);
} else {
if (loglevel > Project.MSG_WARN) {
System.out.println(message);
diff --git a/src/testcases/org/apache/tools/ant/taskdefs/ExecuteJavaTest.java b/src/testcases/org/apache/tools/ant/taskdefs/ExecuteJavaTest.java
index ca60bb07f..8829b9e5f 100644
--- a/src/testcases/org/apache/tools/ant/taskdefs/ExecuteJavaTest.java
+++ b/src/testcases/org/apache/tools/ant/taskdefs/ExecuteJavaTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002,2004 The Apache Software Foundation
+ * Copyright 2002,2004-2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,6 +40,7 @@ public class ExecuteJavaTest extends TestCase {
private ExecuteJava ej;
private Project project;
+ private Path cp;
public ExecuteJavaTest(String name) {
super(name);
@@ -50,7 +51,8 @@ public class ExecuteJavaTest extends TestCase {
ej.setTimeout(new Long(TIME_OUT));
project = new Project();
project.setBasedir(".");
- ej.setClasspath(new Path(project, getTestClassPath()));
+ cp = new Path(project, getTestClassPath());
+ ej.setClasspath(cp);
}
private Commandline getCommandline(int timetorun) throws Exception {
@@ -85,6 +87,30 @@ public class ExecuteJavaTest extends TestCase {
}
+ public void testNoTimeOutForked() throws Exception {
+ Commandline cmd = getCommandline(TIME_OUT/2);
+ ej.setJavaCommand(cmd);
+ ej.fork(cp);
+ assertTrue("process should not have been killed", !ej.killedProcess());
+ }
+
+ // test that the watchdog ends the process
+ public void testTimeOutForked() throws Exception {
+ Commandline cmd = getCommandline(TIME_OUT*2);
+ ej.setJavaCommand(cmd);
+ long now = System.currentTimeMillis();
+ ej.fork(cp);
+ long elapsed = System.currentTimeMillis() - now;
+ assertTrue("process should have been killed", ej.killedProcess());
+
+ assertTrue("elapse time of "+elapsed
+ +" ms is less than timeout value of "+TIME_OUT_TEST+" ms",
+ elapsed >= TIME_OUT_TEST);
+ assertTrue("elapse time of "+elapsed
+ +" ms is greater than run value of "+(TIME_OUT*2)+" ms",
+ elapsed < TIME_OUT*2);
+ }
+
/**
* Dangerous method to obtain the classpath for the test. This is
* severely tighted to the build.xml properties.