bodewig 2005/02/02 04:52:50 Modified: src/main/org/apache/tools/ant/taskdefs ExecuteJava.java Java.java LogOutputStream.java LogStreamHandler.java Redirector.java src/main/org/apache/tools/ant/types CommandlineJava.java src/main/org/apache/tools/ant/util ConcatFileInputStream.java LeadPipeInputStream.java src/testcases/org/apache/tools/ant/taskdefs ExecuteJavaTest.java Log: Simplify forking of new VMs by providing a fork method in ExecuteJava Revision Changes Path 1.45 +78 -2 ant/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java Index: ExecuteJava.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java,v retrieving revision 1.44 retrieving revision 1.45 diff -u -r1.44 -r1.45 --- ExecuteJava.java 24 Jun 2004 11:56:21 -0000 1.44 +++ ExecuteJava.java 2 Feb 2005 12:52:47 -0000 1.45 @@ -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 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 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"); + } + } + } 1.99 +1 -17 ant/src/main/org/apache/tools/ant/taskdefs/Java.java Index: Java.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Java.java,v retrieving revision 1.98 retrieving revision 1.99 diff -u -r1.98 -r1.99 --- Java.java 28 Jan 2005 10:11:16 -0000 1.98 +++ Java.java 2 Feb 2005 12:52:47 -0000 1.99 @@ -840,23 +840,7 @@ * @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); } /** 1.22 +16 -4 ant/src/main/org/apache/tools/ant/taskdefs/LogOutputStream.java Index: LogOutputStream.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/LogOutputStream.java,v retrieving revision 1.21 retrieving revision 1.22 diff -u -r1.21 -r1.22 --- LogOutputStream.java 11 Mar 2004 11:22:10 -0000 1.21 +++ LogOutputStream.java 2 Feb 2005 12:52:47 -0000 1.22 @@ -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.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 @@ = new ByteArrayOutputStream(INTIAL_SIZE); private boolean skip = false; - private Task task; + private ProjectComponent pc; private int level = Project.MSG_INFO; /** @@ -58,7 +59,18 @@ * @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 @@ * @param line the line to log. */ protected void processLine(String line, int level) { - task.log(line, level); + pc.log(line, level); } 1.13 +15 -3 ant/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java Index: LogStreamHandler.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- LogStreamHandler.java 9 Mar 2004 16:48:06 -0000 1.12 +++ LogStreamHandler.java 2 Feb 2005 12:52:47 -0000 1.13 @@ -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 @@ 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 @@ * @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)); } /** 1.25 +18 -6 ant/src/main/org/apache/tools/ant/taskdefs/Redirector.java Index: Redirector.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Redirector.java,v retrieving revision 1.24 retrieving revision 1.25 diff -u -r1.24 -r1.25 --- Redirector.java 27 Jan 2005 16:36:11 -0000 1.24 +++ Redirector.java 2 Feb 2005 12:52:47 -0000 1.25 @@ -31,8 +31,9 @@ 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 @@ /** * 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 @@ 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 @@ * @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 @@ || !(outputEncoding.equalsIgnoreCase(inputEncoding))) { try { LeadPipeInputStream snk = new LeadPipeInputStream(); - snk.setManagingTask(managingTask); + snk.setManagingComponent(managingTask); InputStream outPumpIn = snk; @@ -527,7 +539,7 @@ || !(errorEncoding.equalsIgnoreCase(inputEncoding))) { try { LeadPipeInputStream snk = new LeadPipeInputStream(); - snk.setManagingTask(managingTask); + snk.setManagingComponent(managingTask); InputStream errPumpIn = snk; @@ -563,7 +575,7 @@ } 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); 1.66 +20 -0 ant/src/main/org/apache/tools/ant/types/CommandlineJava.java Index: CommandlineJava.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/types/CommandlineJava.java,v retrieving revision 1.65 retrieving revision 1.66 diff -u -r1.65 -r1.66 --- CommandlineJava.java 18 Jan 2005 10:51:03 -0000 1.65 +++ CommandlineJava.java 2 Feb 2005 12:52:49 -0000 1.66 @@ -192,6 +192,16 @@ } /** + * 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 @@ } return p; } + } /** @@ -247,6 +258,15 @@ } /** + * 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 */ 1.6 +15 -5 ant/src/main/org/apache/tools/ant/util/ConcatFileInputStream.java Index: ConcatFileInputStream.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/util/ConcatFileInputStream.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- ConcatFileInputStream.java 24 Jan 2005 18:13:20 -0000 1.5 +++ ConcatFileInputStream.java 2 Feb 2005 12:52:50 -0000 1.6 @@ -23,8 +23,9 @@ 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 <CODE>InputStream</CODE> that will @@ -37,7 +38,7 @@ private boolean eof = false; private File[] file; private InputStream currentStream; - private Task managingTask; + private ProjectComponent managingPc; /** * Construct a new <CODE>ConcatFileInputStream</CODE> @@ -71,7 +72,16 @@ * @param task the managing <CODE>Task</CODE>. */ public void setManagingTask(Task task) { - this.managingTask = task; + setManagingComponent(task); + } + + /** + * Set a managing <CODE>Task</CODE> for + * this <CODE>ConcatFileInputStream</CODE>. + * @param task the managing <CODE>Task</CODE>. + */ + public void setManagingComponent(ProjectComponent pc) { + this.managingPc = pc; } /** @@ -80,8 +90,8 @@ * @param loglevel the <CODE>int</CODE> 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); 1.3 +14 -4 ant/src/main/org/apache/tools/ant/util/LeadPipeInputStream.java Index: LeadPipeInputStream.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/util/LeadPipeInputStream.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- LeadPipeInputStream.java 24 Jan 2005 18:13:20 -0000 1.2 +++ LeadPipeInputStream.java 2 Feb 2005 12:52:50 -0000 1.3 @@ -21,6 +21,7 @@ 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 @@ * when the writing <CODE>Thread</CODE> is no longer alive. */ public class LeadPipeInputStream extends PipedInputStream { - private Task managingTask; + private ProjectComponent managingPc; /** * Construct a new <CODE>LeadPipeInputStream</CODE>. @@ -73,7 +74,16 @@ * @param task the managing <CODE>Task</CODE>. */ public void setManagingTask(Task task) { - this.managingTask = task; + setManagingComponent(task); + } + + /** + * Set a managing <CODE>ProjectComponent</CODE> for + * this <CODE>LeadPipeInputStream</CODE>. + * @param pc the managing <CODE>ProjectComponent</CODE>. + */ + public void setManagingComponent(ProjectComponent pc) { + this.managingPc = pc; } /** @@ -82,8 +92,8 @@ * @param loglevel the <CODE>int</CODE> 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); 1.9 +28 -2 ant/src/testcases/org/apache/tools/ant/taskdefs/ExecuteJavaTest.java Index: ExecuteJavaTest.java =================================================================== RCS file: /home/cvs/ant/src/testcases/org/apache/tools/ant/taskdefs/ExecuteJavaTest.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- ExecuteJavaTest.java 9 Mar 2004 16:48:57 -0000 1.8 +++ ExecuteJavaTest.java 2 Feb 2005 12:52:50 -0000 1.9 @@ -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 @@ private ExecuteJava ej; private Project project; + private Path cp; public ExecuteJavaTest(String name) { super(name); @@ -50,7 +51,8 @@ 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 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.
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]