git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@270269 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -12,11 +12,8 @@ import java.io.ByteArrayOutputStream; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.io.StringReader; | import java.io.StringReader; | ||||
| import java.lang.reflect.InvocationTargetException; | |||||
| import java.lang.reflect.Method; | |||||
| import java.util.Locale; | import java.util.Locale; | ||||
| import java.util.Vector; | import java.util.Vector; | ||||
| import org.apache.avalon.excalibur.io.FileUtil; | |||||
| import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
| import org.apache.myrmidon.framework.Os; | import org.apache.myrmidon.framework.Os; | ||||
| import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
| @@ -35,29 +32,29 @@ public class Execute | |||||
| */ | */ | ||||
| public final static int INVALID = Integer.MAX_VALUE; | public final static int INVALID = Integer.MAX_VALUE; | ||||
| private static String antWorkingDirectory = System.getProperty( "user.dir" ); | |||||
| private static CommandLauncher vmLauncher; | |||||
| private static CommandLauncher shellLauncher; | |||||
| private static Vector procEnvironment; | |||||
| private static String c_antWorkingDirectory = System.getProperty( "user.dir" ); | |||||
| private static CommandLauncher c_vmLauncher; | |||||
| private static CommandLauncher c_shellLauncher; | |||||
| private static Vector c_procEnvironment; | |||||
| /** | /** | ||||
| * Used to destroy processes when the VM exits. | * Used to destroy processes when the VM exits. | ||||
| */ | */ | ||||
| private static ProcessDestroyer processDestroyer = new ProcessDestroyer(); | |||||
| private static ProcessDestroyer c_processDestroyer = new ProcessDestroyer(); | |||||
| private String[] cmdl = null; | |||||
| private String[] env = null; | |||||
| private int exitValue = INVALID; | |||||
| private File workingDirectory = null; | |||||
| private Project project = null; | |||||
| private boolean newEnvironment = false; | |||||
| private String[] m_command; | |||||
| private String[] m_environment; | |||||
| private int m_exitValue = INVALID; | |||||
| private File m_workingDirectory; | |||||
| private Project m_project; | |||||
| private boolean m_newEnvironment; | |||||
| /** | /** | ||||
| * Controls whether the VM is used to launch commands, where possible | * Controls whether the VM is used to launch commands, where possible | ||||
| */ | */ | ||||
| private boolean useVMLauncher = true; | |||||
| private ExecuteStreamHandler streamHandler; | |||||
| private ExecuteWatchdog watchdog; | |||||
| private boolean m_useVMLauncher = true; | |||||
| private ExecuteStreamHandler m_streamHandler; | |||||
| private ExecuteWatchdog m_watchdog; | |||||
| /** | /** | ||||
| * Builds a command launcher for the OS and JVM we are running under | * Builds a command launcher for the OS and JVM we are running under | ||||
| @@ -70,7 +67,7 @@ public class Execute | |||||
| // Try using a JDK 1.3 launcher | // Try using a JDK 1.3 launcher | ||||
| try | try | ||||
| { | { | ||||
| vmLauncher = new Java13CommandLauncher(); | |||||
| c_vmLauncher = new Java13CommandLauncher(); | |||||
| } | } | ||||
| catch( NoSuchMethodException exc ) | catch( NoSuchMethodException exc ) | ||||
| { | { | ||||
| @@ -80,12 +77,12 @@ public class Execute | |||||
| if( Os.isFamily( "mac" ) ) | if( Os.isFamily( "mac" ) ) | ||||
| { | { | ||||
| // Mac | // Mac | ||||
| shellLauncher = new MacCommandLauncher( new CommandLauncher() ); | |||||
| c_shellLauncher = new MacCommandLauncher( new CommandLauncher() ); | |||||
| } | } | ||||
| else if( Os.isFamily( "os/2" ) ) | else if( Os.isFamily( "os/2" ) ) | ||||
| { | { | ||||
| // OS/2 - use same mechanism as Windows 2000 | // OS/2 - use same mechanism as Windows 2000 | ||||
| shellLauncher = new WinNTCommandLauncher( new CommandLauncher() ); | |||||
| c_shellLauncher = new WinNTCommandLauncher( new CommandLauncher() ); | |||||
| } | } | ||||
| else if( Os.isFamily( "windows" ) ) | else if( Os.isFamily( "windows" ) ) | ||||
| { | { | ||||
| @@ -110,15 +107,15 @@ public class Execute | |||||
| if( osname.indexOf( "nt" ) >= 0 || osname.indexOf( "2000" ) >= 0 ) | if( osname.indexOf( "nt" ) >= 0 || osname.indexOf( "2000" ) >= 0 ) | ||||
| { | { | ||||
| // Windows 2000/NT | // Windows 2000/NT | ||||
| shellLauncher = new WinNTCommandLauncher( baseLauncher ); | |||||
| c_shellLauncher = new WinNTCommandLauncher( baseLauncher ); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| // Windows 98/95 - need to use an auxiliary script | // Windows 98/95 - need to use an auxiliary script | ||||
| shellLauncher = new ScriptCommandLauncher( "bin/antRun.bat", baseLauncher ); | |||||
| c_shellLauncher = new ScriptCommandLauncher( "bin/antRun.bat", baseLauncher ); | |||||
| } | } | ||||
| } | } | ||||
| else if( ( new Os( "netware" ) ).eval() ) | |||||
| else if( (new Os( "netware" )).eval() ) | |||||
| { | { | ||||
| // NetWare. Need to determine which JDK we're running in | // NetWare. Need to determine which JDK we're running in | ||||
| CommandLauncher baseLauncher; | CommandLauncher baseLauncher; | ||||
| @@ -133,12 +130,12 @@ public class Execute | |||||
| baseLauncher = new CommandLauncher(); | baseLauncher = new CommandLauncher(); | ||||
| } | } | ||||
| shellLauncher = new PerlScriptCommandLauncher( "bin/antRun.pl", baseLauncher ); | |||||
| c_shellLauncher = new PerlScriptCommandLauncher( "bin/antRun.pl", baseLauncher ); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| // Generic | // Generic | ||||
| shellLauncher = new ScriptCommandLauncher( "bin/antRun", new CommandLauncher() ); | |||||
| c_shellLauncher = new ScriptCommandLauncher( "bin/antRun", new CommandLauncher() ); | |||||
| } | } | ||||
| } | } | ||||
| catch( TaskException e ) | catch( TaskException e ) | ||||
| @@ -177,8 +174,8 @@ public class Execute | |||||
| */ | */ | ||||
| public Execute( ExecuteStreamHandler streamHandler, ExecuteWatchdog watchdog ) | public Execute( ExecuteStreamHandler streamHandler, ExecuteWatchdog watchdog ) | ||||
| { | { | ||||
| this.streamHandler = streamHandler; | |||||
| this.watchdog = watchdog; | |||||
| this.m_streamHandler = streamHandler; | |||||
| this.m_watchdog = watchdog; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -189,10 +186,10 @@ public class Execute | |||||
| public static synchronized Vector getProcEnvironment() | public static synchronized Vector getProcEnvironment() | ||||
| throws TaskException | throws TaskException | ||||
| { | { | ||||
| if( procEnvironment != null ) | |||||
| return procEnvironment; | |||||
| if( c_procEnvironment != null ) | |||||
| return c_procEnvironment; | |||||
| procEnvironment = new Vector(); | |||||
| c_procEnvironment = new Vector(); | |||||
| try | try | ||||
| { | { | ||||
| ByteArrayOutputStream out = new ByteArrayOutputStream(); | ByteArrayOutputStream out = new ByteArrayOutputStream(); | ||||
| @@ -211,7 +208,7 @@ public class Execute | |||||
| String var = null; | String var = null; | ||||
| String line; | String line; | ||||
| String lineSep = System.getProperty( "line.separator" ); | String lineSep = System.getProperty( "line.separator" ); | ||||
| while( ( line = in.readLine() ) != null ) | |||||
| while( (line = in.readLine()) != null ) | |||||
| { | { | ||||
| if( line.indexOf( '=' ) == -1 ) | if( line.indexOf( '=' ) == -1 ) | ||||
| { | { | ||||
| @@ -231,20 +228,20 @@ public class Execute | |||||
| // New env var...append the previous one if we have it. | // New env var...append the previous one if we have it. | ||||
| if( var != null ) | if( var != null ) | ||||
| { | { | ||||
| procEnvironment.addElement( var ); | |||||
| c_procEnvironment.addElement( var ); | |||||
| } | } | ||||
| var = line; | var = line; | ||||
| } | } | ||||
| } | } | ||||
| // Since we "look ahead" before adding, there's one last env var. | // Since we "look ahead" before adding, there's one last env var. | ||||
| procEnvironment.addElement( var ); | |||||
| c_procEnvironment.addElement( var ); | |||||
| } | } | ||||
| catch( IOException exc ) | catch( IOException exc ) | ||||
| { | { | ||||
| exc.printStackTrace(); | exc.printStackTrace(); | ||||
| // Just try to see how much we got | // Just try to see how much we got | ||||
| } | } | ||||
| return procEnvironment; | |||||
| return c_procEnvironment; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -335,7 +332,7 @@ public class Execute | |||||
| public void setAntRun( Project project ) | public void setAntRun( Project project ) | ||||
| throws TaskException | throws TaskException | ||||
| { | { | ||||
| this.project = project; | |||||
| this.m_project = project; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -345,7 +342,7 @@ public class Execute | |||||
| */ | */ | ||||
| public void setCommandline( String[] commandline ) | public void setCommandline( String[] commandline ) | ||||
| { | { | ||||
| cmdl = commandline; | |||||
| m_command = commandline; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -355,7 +352,7 @@ public class Execute | |||||
| */ | */ | ||||
| public void setEnvironment( String[] env ) | public void setEnvironment( String[] env ) | ||||
| { | { | ||||
| this.env = env; | |||||
| this.m_environment = env; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -365,7 +362,7 @@ public class Execute | |||||
| */ | */ | ||||
| public void setNewenvironment( boolean newenv ) | public void setNewenvironment( boolean newenv ) | ||||
| { | { | ||||
| newEnvironment = newenv; | |||||
| m_newEnvironment = newenv; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -378,7 +375,7 @@ public class Execute | |||||
| */ | */ | ||||
| public void setVMLauncher( boolean useVMLauncher ) | public void setVMLauncher( boolean useVMLauncher ) | ||||
| { | { | ||||
| this.useVMLauncher = useVMLauncher; | |||||
| this.m_useVMLauncher = useVMLauncher; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -392,10 +389,10 @@ public class Execute | |||||
| */ | */ | ||||
| public void setWorkingDirectory( File wd ) | public void setWorkingDirectory( File wd ) | ||||
| { | { | ||||
| if( wd == null || wd.getAbsolutePath().equals( antWorkingDirectory ) ) | |||||
| workingDirectory = null; | |||||
| if( wd == null || wd.getAbsolutePath().equals( c_antWorkingDirectory ) ) | |||||
| m_workingDirectory = null; | |||||
| else | else | ||||
| workingDirectory = wd; | |||||
| m_workingDirectory = wd; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -405,7 +402,7 @@ public class Execute | |||||
| */ | */ | ||||
| public String[] getCommandline() | public String[] getCommandline() | ||||
| { | { | ||||
| return cmdl; | |||||
| return m_command; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -416,8 +413,8 @@ public class Execute | |||||
| public String[] getEnvironment() | public String[] getEnvironment() | ||||
| throws TaskException | throws TaskException | ||||
| { | { | ||||
| if( env == null || newEnvironment ) | |||||
| return env; | |||||
| if( m_environment == null || m_newEnvironment ) | |||||
| return m_environment; | |||||
| return patchEnvironment(); | return patchEnvironment(); | ||||
| } | } | ||||
| @@ -429,7 +426,7 @@ public class Execute | |||||
| */ | */ | ||||
| public int getExitValue() | public int getExitValue() | ||||
| { | { | ||||
| return exitValue; | |||||
| return m_exitValue; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -441,43 +438,43 @@ public class Execute | |||||
| public int execute() | public int execute() | ||||
| throws IOException, TaskException | throws IOException, TaskException | ||||
| { | { | ||||
| CommandLauncher launcher = vmLauncher != null ? vmLauncher : shellLauncher; | |||||
| if( !useVMLauncher ) | |||||
| CommandLauncher launcher = c_vmLauncher != null ? c_vmLauncher : c_shellLauncher; | |||||
| if( !m_useVMLauncher ) | |||||
| { | { | ||||
| launcher = shellLauncher; | |||||
| launcher = c_shellLauncher; | |||||
| } | } | ||||
| final Process process = launcher.exec( project, getCommandline(), getEnvironment(), workingDirectory ); | |||||
| final Process process = launcher.exec( m_project, getCommandline(), getEnvironment(), m_workingDirectory ); | |||||
| try | try | ||||
| { | { | ||||
| streamHandler.setProcessInputStream( process.getOutputStream() ); | |||||
| streamHandler.setProcessOutputStream( process.getInputStream() ); | |||||
| streamHandler.setProcessErrorStream( process.getErrorStream() ); | |||||
| m_streamHandler.setProcessInputStream( process.getOutputStream() ); | |||||
| m_streamHandler.setProcessOutputStream( process.getInputStream() ); | |||||
| m_streamHandler.setProcessErrorStream( process.getErrorStream() ); | |||||
| } | } | ||||
| catch( IOException e ) | catch( IOException e ) | ||||
| { | { | ||||
| process.destroy(); | process.destroy(); | ||||
| throw e; | throw e; | ||||
| } | } | ||||
| streamHandler.start(); | |||||
| m_streamHandler.start(); | |||||
| // add the process to the list of those to destroy if the VM exits | // add the process to the list of those to destroy if the VM exits | ||||
| // | // | ||||
| processDestroyer.add( process ); | |||||
| c_processDestroyer.add( process ); | |||||
| if( watchdog != null ) | |||||
| watchdog.start( process ); | |||||
| if( m_watchdog != null ) | |||||
| m_watchdog.start( process ); | |||||
| waitFor( process ); | waitFor( process ); | ||||
| // remove the process to the list of those to destroy if the VM exits | // remove the process to the list of those to destroy if the VM exits | ||||
| // | // | ||||
| processDestroyer.remove( process ); | |||||
| c_processDestroyer.remove( process ); | |||||
| if( watchdog != null ) | |||||
| watchdog.stop(); | |||||
| streamHandler.stop(); | |||||
| if( watchdog != null ) | |||||
| watchdog.checkException(); | |||||
| if( m_watchdog != null ) | |||||
| m_watchdog.stop(); | |||||
| m_streamHandler.stop(); | |||||
| if( m_watchdog != null ) | |||||
| m_watchdog.checkException(); | |||||
| return getExitValue(); | return getExitValue(); | ||||
| } | } | ||||
| @@ -489,12 +486,12 @@ public class Execute | |||||
| */ | */ | ||||
| public boolean killedProcess() | public boolean killedProcess() | ||||
| { | { | ||||
| return watchdog != null && watchdog.killedProcess(); | |||||
| return m_watchdog != null && m_watchdog.killedProcess(); | |||||
| } | } | ||||
| protected void setExitValue( int value ) | |||||
| private void setExitValue( final int value ) | |||||
| { | { | ||||
| exitValue = value; | |||||
| m_exitValue = value; | |||||
| } | } | ||||
| protected void waitFor( Process process ) | protected void waitFor( Process process ) | ||||
| @@ -518,443 +515,25 @@ public class Execute | |||||
| throws TaskException | throws TaskException | ||||
| { | { | ||||
| Vector osEnv = (Vector)getProcEnvironment().clone(); | Vector osEnv = (Vector)getProcEnvironment().clone(); | ||||
| for( int i = 0; i < env.length; i++ ) | |||||
| for( int i = 0; i < m_environment.length; i++ ) | |||||
| { | { | ||||
| int pos = env[ i ].indexOf( '=' ); | |||||
| int pos = m_environment[ i ].indexOf( '=' ); | |||||
| // Get key including "=" | // Get key including "=" | ||||
| String key = env[ i ].substring( 0, pos + 1 ); | |||||
| String key = m_environment[ i ].substring( 0, pos + 1 ); | |||||
| int size = osEnv.size(); | int size = osEnv.size(); | ||||
| for( int j = 0; j < size; j++ ) | for( int j = 0; j < size; j++ ) | ||||
| { | { | ||||
| if( ( (String)osEnv.elementAt( j ) ).startsWith( key ) ) | |||||
| if( ((String)osEnv.elementAt( j )).startsWith( key ) ) | |||||
| { | { | ||||
| osEnv.removeElementAt( j ); | osEnv.removeElementAt( j ); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| osEnv.addElement( env[ i ] ); | |||||
| osEnv.addElement( m_environment[ i ] ); | |||||
| } | } | ||||
| String[] result = new String[ osEnv.size() ]; | String[] result = new String[ osEnv.size() ]; | ||||
| osEnv.copyInto( result ); | osEnv.copyInto( result ); | ||||
| return result; | return result; | ||||
| } | } | ||||
| /** | |||||
| * A command launcher for a particular JVM/OS platform. This class is a | |||||
| * general purpose command launcher which can only launch commands in the | |||||
| * current working directory. | |||||
| * | |||||
| * @author RT | |||||
| */ | |||||
| private static class CommandLauncher | |||||
| { | |||||
| /** | |||||
| * Launches the given command in a new process. | |||||
| * | |||||
| * @param project The project that the command is part of | |||||
| * @param cmd The command to execute | |||||
| * @param env The environment for the new process. If null, the | |||||
| * environment of the current proccess is used. | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| if( project != null ) | |||||
| { | |||||
| project.log( "Execute:CommandLauncher: " + | |||||
| Commandline.toString( cmd ), Project.MSG_DEBUG ); | |||||
| } | |||||
| return Runtime.getRuntime().exec( cmd, env ); | |||||
| } | |||||
| /** | |||||
| * Launches the given command in a new process, in the given working | |||||
| * directory. | |||||
| * | |||||
| * @param project The project that the command is part of | |||||
| * @param cmd The command to execute | |||||
| * @param env The environment for the new process. If null, the | |||||
| * environment of the current proccess is used. | |||||
| * @param workingDir The directory to start the command in. If null, the | |||||
| * current directory is used | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env, File workingDir ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| if( workingDir == null ) | |||||
| { | |||||
| return exec( project, cmd, env ); | |||||
| } | |||||
| throw new IOException( "Cannot execute a process in different directory under this JVM" ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * A command launcher that proxies another command launcher. Sub-classes | |||||
| * override exec(args, env, workdir) | |||||
| * | |||||
| * @author RT | |||||
| */ | |||||
| private static class CommandLauncherProxy extends CommandLauncher | |||||
| { | |||||
| private CommandLauncher _launcher; | |||||
| CommandLauncherProxy( CommandLauncher launcher ) | |||||
| { | |||||
| _launcher = launcher; | |||||
| } | |||||
| /** | |||||
| * Launches the given command in a new process. Delegates this method to | |||||
| * the proxied launcher | |||||
| * | |||||
| * @param project Description of Parameter | |||||
| * @param cmd Description of Parameter | |||||
| * @param env Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| return _launcher.exec( project, cmd, env ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * A command launcher for JDK/JRE 1.1 under Windows. Fixes quoting problems | |||||
| * in Runtime.exec(). Can only launch commands in the current working | |||||
| * directory | |||||
| * | |||||
| * @author RT | |||||
| */ | |||||
| private static class Java11CommandLauncher extends CommandLauncher | |||||
| { | |||||
| /** | |||||
| * Launches the given command in a new process. Needs to quote arguments | |||||
| * | |||||
| * @param project Description of Parameter | |||||
| * @param cmd Description of Parameter | |||||
| * @param env Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| // Need to quote arguments with spaces, and to escape quote characters | |||||
| String[] newcmd = new String[ cmd.length ]; | |||||
| for( int i = 0; i < cmd.length; i++ ) | |||||
| { | |||||
| newcmd[ i ] = Commandline.quoteArgument( cmd[ i ] ); | |||||
| } | |||||
| if( project != null ) | |||||
| { | |||||
| project.log( "Execute:Java11CommandLauncher: " + | |||||
| Commandline.toString( newcmd ), Project.MSG_DEBUG ); | |||||
| } | |||||
| return Runtime.getRuntime().exec( newcmd, env ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * A command launcher for JDK/JRE 1.3 (and higher). Uses the built-in | |||||
| * Runtime.exec() command | |||||
| * | |||||
| * @author RT | |||||
| */ | |||||
| private static class Java13CommandLauncher extends CommandLauncher | |||||
| { | |||||
| private Method _execWithCWD; | |||||
| public Java13CommandLauncher() | |||||
| throws NoSuchMethodException | |||||
| { | |||||
| // Locate method Runtime.exec(String[] cmdarray, String[] envp, File dir) | |||||
| _execWithCWD = Runtime.class.getMethod( "exec", new Class[]{String[].class, String[].class, File.class} ); | |||||
| } | |||||
| /** | |||||
| * Launches the given command in a new process, in the given working | |||||
| * directory | |||||
| * | |||||
| * @param project Description of Parameter | |||||
| * @param cmd Description of Parameter | |||||
| * @param env Description of Parameter | |||||
| * @param workingDir Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env, File workingDir ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| try | |||||
| { | |||||
| if( project != null ) | |||||
| { | |||||
| project.log( "Execute:Java13CommandLauncher: " + | |||||
| Commandline.toString( cmd ), Project.MSG_DEBUG ); | |||||
| } | |||||
| Object[] arguments = {cmd, env, workingDir}; | |||||
| return (Process)_execWithCWD.invoke( Runtime.getRuntime(), arguments ); | |||||
| } | |||||
| catch( InvocationTargetException exc ) | |||||
| { | |||||
| Throwable realexc = exc.getTargetException(); | |||||
| if( realexc instanceof ThreadDeath ) | |||||
| { | |||||
| throw (ThreadDeath)realexc; | |||||
| } | |||||
| else if( realexc instanceof IOException ) | |||||
| { | |||||
| throw (IOException)realexc; | |||||
| } | |||||
| else | |||||
| { | |||||
| throw new TaskException( "Unable to execute command", realexc ); | |||||
| } | |||||
| } | |||||
| catch( Exception exc ) | |||||
| { | |||||
| // IllegalAccess, IllegalArgument, ClassCast | |||||
| throw new TaskException( "Unable to execute command", exc ); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * A command launcher for Mac that uses a dodgy mechanism to change working | |||||
| * directory before launching commands. | |||||
| * | |||||
| * @author RT | |||||
| */ | |||||
| private static class MacCommandLauncher extends CommandLauncherProxy | |||||
| { | |||||
| MacCommandLauncher( CommandLauncher launcher ) | |||||
| { | |||||
| super( launcher ); | |||||
| } | |||||
| /** | |||||
| * Launches the given command in a new process, in the given working | |||||
| * directory | |||||
| * | |||||
| * @param project Description of Parameter | |||||
| * @param cmd Description of Parameter | |||||
| * @param env Description of Parameter | |||||
| * @param workingDir Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env, File workingDir ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| if( workingDir == null ) | |||||
| { | |||||
| return exec( project, cmd, env ); | |||||
| } | |||||
| System.getProperties().put( "user.dir", workingDir.getAbsolutePath() ); | |||||
| try | |||||
| { | |||||
| return exec( project, cmd, env ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| System.getProperties().put( "user.dir", antWorkingDirectory ); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * A command launcher that uses an auxiliary perl script to launch commands | |||||
| * in directories other than the current working directory. | |||||
| * | |||||
| * @author RT | |||||
| */ | |||||
| private static class PerlScriptCommandLauncher extends CommandLauncherProxy | |||||
| { | |||||
| private String _script; | |||||
| PerlScriptCommandLauncher( String script, CommandLauncher launcher ) | |||||
| { | |||||
| super( launcher ); | |||||
| _script = script; | |||||
| } | |||||
| /** | |||||
| * Launches the given command in a new process, in the given working | |||||
| * directory | |||||
| * | |||||
| * @param project Description of Parameter | |||||
| * @param cmd Description of Parameter | |||||
| * @param env Description of Parameter | |||||
| * @param workingDir Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env, File workingDir ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| if( project == null ) | |||||
| { | |||||
| if( workingDir == null ) | |||||
| { | |||||
| return exec( project, cmd, env ); | |||||
| } | |||||
| throw new IOException( "Cannot locate antRun script: No project provided" ); | |||||
| } | |||||
| // Locate the auxiliary script | |||||
| String antHome = project.getProperty( "ant.home" ); | |||||
| if( antHome == null ) | |||||
| { | |||||
| throw new IOException( "Cannot locate antRun script: Property 'ant.home' not found" ); | |||||
| } | |||||
| String antRun = FileUtil. | |||||
| resolveFile( project.getBaseDir(), antHome + File.separator + _script ).toString(); | |||||
| // Build the command | |||||
| File commandDir = workingDir; | |||||
| if( workingDir == null && project != null ) | |||||
| { | |||||
| commandDir = project.getBaseDir(); | |||||
| } | |||||
| String[] newcmd = new String[ cmd.length + 3 ]; | |||||
| newcmd[ 0 ] = "perl"; | |||||
| newcmd[ 1 ] = antRun; | |||||
| newcmd[ 2 ] = commandDir.getAbsolutePath(); | |||||
| System.arraycopy( cmd, 0, newcmd, 3, cmd.length ); | |||||
| return exec( project, newcmd, env ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * A command launcher that uses an auxiliary script to launch commands in | |||||
| * directories other than the current working directory. | |||||
| * | |||||
| * @author RT | |||||
| */ | |||||
| private static class ScriptCommandLauncher extends CommandLauncherProxy | |||||
| { | |||||
| private String _script; | |||||
| ScriptCommandLauncher( String script, CommandLauncher launcher ) | |||||
| { | |||||
| super( launcher ); | |||||
| _script = script; | |||||
| } | |||||
| /** | |||||
| * Launches the given command in a new process, in the given working | |||||
| * directory | |||||
| * | |||||
| * @param project Description of Parameter | |||||
| * @param cmd Description of Parameter | |||||
| * @param env Description of Parameter | |||||
| * @param workingDir Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env, File workingDir ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| if( project == null ) | |||||
| { | |||||
| if( workingDir == null ) | |||||
| { | |||||
| return exec( project, cmd, env ); | |||||
| } | |||||
| throw new IOException( "Cannot locate antRun script: No project provided" ); | |||||
| } | |||||
| // Locate the auxiliary script | |||||
| String antHome = project.getProperty( "ant.home" ); | |||||
| if( antHome == null ) | |||||
| { | |||||
| throw new IOException( "Cannot locate antRun script: Property 'ant.home' not found" ); | |||||
| } | |||||
| String antRun = FileUtil. | |||||
| resolveFile( project.getBaseDir(), antHome + File.separator + _script ).toString(); | |||||
| // Build the command | |||||
| File commandDir = workingDir; | |||||
| if( workingDir == null && project != null ) | |||||
| { | |||||
| commandDir = project.getBaseDir(); | |||||
| } | |||||
| String[] newcmd = new String[ cmd.length + 2 ]; | |||||
| newcmd[ 0 ] = antRun; | |||||
| newcmd[ 1 ] = commandDir.getAbsolutePath(); | |||||
| System.arraycopy( cmd, 0, newcmd, 2, cmd.length ); | |||||
| return exec( project, newcmd, env ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * A command launcher for Windows 2000/NT that uses 'cmd.exe' when launching | |||||
| * commands in directories other than the current working directory. | |||||
| * | |||||
| * @author RT | |||||
| */ | |||||
| private static class WinNTCommandLauncher extends CommandLauncherProxy | |||||
| { | |||||
| WinNTCommandLauncher( CommandLauncher launcher ) | |||||
| { | |||||
| super( launcher ); | |||||
| } | |||||
| /** | |||||
| * Launches the given command in a new process, in the given working | |||||
| * directory. | |||||
| * | |||||
| * @param project Description of Parameter | |||||
| * @param cmd Description of Parameter | |||||
| * @param env Description of Parameter | |||||
| * @param workingDir Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env, File workingDir ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| File commandDir = workingDir; | |||||
| if( workingDir == null ) | |||||
| { | |||||
| if( project != null ) | |||||
| { | |||||
| commandDir = project.getBaseDir(); | |||||
| } | |||||
| else | |||||
| { | |||||
| return exec( project, cmd, env ); | |||||
| } | |||||
| } | |||||
| // Use cmd.exe to change to the specified directory before running | |||||
| // the command | |||||
| final int preCmdLength = 6; | |||||
| String[] newcmd = new String[ cmd.length + preCmdLength ]; | |||||
| newcmd[ 0 ] = "cmd"; | |||||
| newcmd[ 1 ] = "/c"; | |||||
| newcmd[ 2 ] = "cd"; | |||||
| newcmd[ 3 ] = "/d"; | |||||
| newcmd[ 4 ] = commandDir.getAbsolutePath(); | |||||
| newcmd[ 5 ] = "&&"; | |||||
| System.arraycopy( cmd, 0, newcmd, preCmdLength, cmd.length ); | |||||
| return exec( project, newcmd, env ); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -12,11 +12,8 @@ import java.io.ByteArrayOutputStream; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.io.StringReader; | import java.io.StringReader; | ||||
| import java.lang.reflect.InvocationTargetException; | |||||
| import java.lang.reflect.Method; | |||||
| import java.util.Locale; | import java.util.Locale; | ||||
| import java.util.Vector; | import java.util.Vector; | ||||
| import org.apache.avalon.excalibur.io.FileUtil; | |||||
| import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
| import org.apache.myrmidon.framework.Os; | import org.apache.myrmidon.framework.Os; | ||||
| import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
| @@ -35,29 +32,29 @@ public class Execute | |||||
| */ | */ | ||||
| public final static int INVALID = Integer.MAX_VALUE; | public final static int INVALID = Integer.MAX_VALUE; | ||||
| private static String antWorkingDirectory = System.getProperty( "user.dir" ); | |||||
| private static CommandLauncher vmLauncher; | |||||
| private static CommandLauncher shellLauncher; | |||||
| private static Vector procEnvironment; | |||||
| private static String c_antWorkingDirectory = System.getProperty( "user.dir" ); | |||||
| private static CommandLauncher c_vmLauncher; | |||||
| private static CommandLauncher c_shellLauncher; | |||||
| private static Vector c_procEnvironment; | |||||
| /** | /** | ||||
| * Used to destroy processes when the VM exits. | * Used to destroy processes when the VM exits. | ||||
| */ | */ | ||||
| private static ProcessDestroyer processDestroyer = new ProcessDestroyer(); | |||||
| private static ProcessDestroyer c_processDestroyer = new ProcessDestroyer(); | |||||
| private String[] cmdl = null; | |||||
| private String[] env = null; | |||||
| private int exitValue = INVALID; | |||||
| private File workingDirectory = null; | |||||
| private Project project = null; | |||||
| private boolean newEnvironment = false; | |||||
| private String[] m_command; | |||||
| private String[] m_environment; | |||||
| private int m_exitValue = INVALID; | |||||
| private File m_workingDirectory; | |||||
| private Project m_project; | |||||
| private boolean m_newEnvironment; | |||||
| /** | /** | ||||
| * Controls whether the VM is used to launch commands, where possible | * Controls whether the VM is used to launch commands, where possible | ||||
| */ | */ | ||||
| private boolean useVMLauncher = true; | |||||
| private ExecuteStreamHandler streamHandler; | |||||
| private ExecuteWatchdog watchdog; | |||||
| private boolean m_useVMLauncher = true; | |||||
| private ExecuteStreamHandler m_streamHandler; | |||||
| private ExecuteWatchdog m_watchdog; | |||||
| /** | /** | ||||
| * Builds a command launcher for the OS and JVM we are running under | * Builds a command launcher for the OS and JVM we are running under | ||||
| @@ -70,7 +67,7 @@ public class Execute | |||||
| // Try using a JDK 1.3 launcher | // Try using a JDK 1.3 launcher | ||||
| try | try | ||||
| { | { | ||||
| vmLauncher = new Java13CommandLauncher(); | |||||
| c_vmLauncher = new Java13CommandLauncher(); | |||||
| } | } | ||||
| catch( NoSuchMethodException exc ) | catch( NoSuchMethodException exc ) | ||||
| { | { | ||||
| @@ -80,12 +77,12 @@ public class Execute | |||||
| if( Os.isFamily( "mac" ) ) | if( Os.isFamily( "mac" ) ) | ||||
| { | { | ||||
| // Mac | // Mac | ||||
| shellLauncher = new MacCommandLauncher( new CommandLauncher() ); | |||||
| c_shellLauncher = new MacCommandLauncher( new CommandLauncher() ); | |||||
| } | } | ||||
| else if( Os.isFamily( "os/2" ) ) | else if( Os.isFamily( "os/2" ) ) | ||||
| { | { | ||||
| // OS/2 - use same mechanism as Windows 2000 | // OS/2 - use same mechanism as Windows 2000 | ||||
| shellLauncher = new WinNTCommandLauncher( new CommandLauncher() ); | |||||
| c_shellLauncher = new WinNTCommandLauncher( new CommandLauncher() ); | |||||
| } | } | ||||
| else if( Os.isFamily( "windows" ) ) | else if( Os.isFamily( "windows" ) ) | ||||
| { | { | ||||
| @@ -110,15 +107,15 @@ public class Execute | |||||
| if( osname.indexOf( "nt" ) >= 0 || osname.indexOf( "2000" ) >= 0 ) | if( osname.indexOf( "nt" ) >= 0 || osname.indexOf( "2000" ) >= 0 ) | ||||
| { | { | ||||
| // Windows 2000/NT | // Windows 2000/NT | ||||
| shellLauncher = new WinNTCommandLauncher( baseLauncher ); | |||||
| c_shellLauncher = new WinNTCommandLauncher( baseLauncher ); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| // Windows 98/95 - need to use an auxiliary script | // Windows 98/95 - need to use an auxiliary script | ||||
| shellLauncher = new ScriptCommandLauncher( "bin/antRun.bat", baseLauncher ); | |||||
| c_shellLauncher = new ScriptCommandLauncher( "bin/antRun.bat", baseLauncher ); | |||||
| } | } | ||||
| } | } | ||||
| else if( ( new Os( "netware" ) ).eval() ) | |||||
| else if( (new Os( "netware" )).eval() ) | |||||
| { | { | ||||
| // NetWare. Need to determine which JDK we're running in | // NetWare. Need to determine which JDK we're running in | ||||
| CommandLauncher baseLauncher; | CommandLauncher baseLauncher; | ||||
| @@ -133,12 +130,12 @@ public class Execute | |||||
| baseLauncher = new CommandLauncher(); | baseLauncher = new CommandLauncher(); | ||||
| } | } | ||||
| shellLauncher = new PerlScriptCommandLauncher( "bin/antRun.pl", baseLauncher ); | |||||
| c_shellLauncher = new PerlScriptCommandLauncher( "bin/antRun.pl", baseLauncher ); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| // Generic | // Generic | ||||
| shellLauncher = new ScriptCommandLauncher( "bin/antRun", new CommandLauncher() ); | |||||
| c_shellLauncher = new ScriptCommandLauncher( "bin/antRun", new CommandLauncher() ); | |||||
| } | } | ||||
| } | } | ||||
| catch( TaskException e ) | catch( TaskException e ) | ||||
| @@ -177,8 +174,8 @@ public class Execute | |||||
| */ | */ | ||||
| public Execute( ExecuteStreamHandler streamHandler, ExecuteWatchdog watchdog ) | public Execute( ExecuteStreamHandler streamHandler, ExecuteWatchdog watchdog ) | ||||
| { | { | ||||
| this.streamHandler = streamHandler; | |||||
| this.watchdog = watchdog; | |||||
| this.m_streamHandler = streamHandler; | |||||
| this.m_watchdog = watchdog; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -189,10 +186,10 @@ public class Execute | |||||
| public static synchronized Vector getProcEnvironment() | public static synchronized Vector getProcEnvironment() | ||||
| throws TaskException | throws TaskException | ||||
| { | { | ||||
| if( procEnvironment != null ) | |||||
| return procEnvironment; | |||||
| if( c_procEnvironment != null ) | |||||
| return c_procEnvironment; | |||||
| procEnvironment = new Vector(); | |||||
| c_procEnvironment = new Vector(); | |||||
| try | try | ||||
| { | { | ||||
| ByteArrayOutputStream out = new ByteArrayOutputStream(); | ByteArrayOutputStream out = new ByteArrayOutputStream(); | ||||
| @@ -211,7 +208,7 @@ public class Execute | |||||
| String var = null; | String var = null; | ||||
| String line; | String line; | ||||
| String lineSep = System.getProperty( "line.separator" ); | String lineSep = System.getProperty( "line.separator" ); | ||||
| while( ( line = in.readLine() ) != null ) | |||||
| while( (line = in.readLine()) != null ) | |||||
| { | { | ||||
| if( line.indexOf( '=' ) == -1 ) | if( line.indexOf( '=' ) == -1 ) | ||||
| { | { | ||||
| @@ -231,20 +228,20 @@ public class Execute | |||||
| // New env var...append the previous one if we have it. | // New env var...append the previous one if we have it. | ||||
| if( var != null ) | if( var != null ) | ||||
| { | { | ||||
| procEnvironment.addElement( var ); | |||||
| c_procEnvironment.addElement( var ); | |||||
| } | } | ||||
| var = line; | var = line; | ||||
| } | } | ||||
| } | } | ||||
| // Since we "look ahead" before adding, there's one last env var. | // Since we "look ahead" before adding, there's one last env var. | ||||
| procEnvironment.addElement( var ); | |||||
| c_procEnvironment.addElement( var ); | |||||
| } | } | ||||
| catch( IOException exc ) | catch( IOException exc ) | ||||
| { | { | ||||
| exc.printStackTrace(); | exc.printStackTrace(); | ||||
| // Just try to see how much we got | // Just try to see how much we got | ||||
| } | } | ||||
| return procEnvironment; | |||||
| return c_procEnvironment; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -335,7 +332,7 @@ public class Execute | |||||
| public void setAntRun( Project project ) | public void setAntRun( Project project ) | ||||
| throws TaskException | throws TaskException | ||||
| { | { | ||||
| this.project = project; | |||||
| this.m_project = project; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -345,7 +342,7 @@ public class Execute | |||||
| */ | */ | ||||
| public void setCommandline( String[] commandline ) | public void setCommandline( String[] commandline ) | ||||
| { | { | ||||
| cmdl = commandline; | |||||
| m_command = commandline; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -355,7 +352,7 @@ public class Execute | |||||
| */ | */ | ||||
| public void setEnvironment( String[] env ) | public void setEnvironment( String[] env ) | ||||
| { | { | ||||
| this.env = env; | |||||
| this.m_environment = env; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -365,7 +362,7 @@ public class Execute | |||||
| */ | */ | ||||
| public void setNewenvironment( boolean newenv ) | public void setNewenvironment( boolean newenv ) | ||||
| { | { | ||||
| newEnvironment = newenv; | |||||
| m_newEnvironment = newenv; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -378,7 +375,7 @@ public class Execute | |||||
| */ | */ | ||||
| public void setVMLauncher( boolean useVMLauncher ) | public void setVMLauncher( boolean useVMLauncher ) | ||||
| { | { | ||||
| this.useVMLauncher = useVMLauncher; | |||||
| this.m_useVMLauncher = useVMLauncher; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -392,10 +389,10 @@ public class Execute | |||||
| */ | */ | ||||
| public void setWorkingDirectory( File wd ) | public void setWorkingDirectory( File wd ) | ||||
| { | { | ||||
| if( wd == null || wd.getAbsolutePath().equals( antWorkingDirectory ) ) | |||||
| workingDirectory = null; | |||||
| if( wd == null || wd.getAbsolutePath().equals( c_antWorkingDirectory ) ) | |||||
| m_workingDirectory = null; | |||||
| else | else | ||||
| workingDirectory = wd; | |||||
| m_workingDirectory = wd; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -405,7 +402,7 @@ public class Execute | |||||
| */ | */ | ||||
| public String[] getCommandline() | public String[] getCommandline() | ||||
| { | { | ||||
| return cmdl; | |||||
| return m_command; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -416,8 +413,8 @@ public class Execute | |||||
| public String[] getEnvironment() | public String[] getEnvironment() | ||||
| throws TaskException | throws TaskException | ||||
| { | { | ||||
| if( env == null || newEnvironment ) | |||||
| return env; | |||||
| if( m_environment == null || m_newEnvironment ) | |||||
| return m_environment; | |||||
| return patchEnvironment(); | return patchEnvironment(); | ||||
| } | } | ||||
| @@ -429,7 +426,7 @@ public class Execute | |||||
| */ | */ | ||||
| public int getExitValue() | public int getExitValue() | ||||
| { | { | ||||
| return exitValue; | |||||
| return m_exitValue; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -441,43 +438,43 @@ public class Execute | |||||
| public int execute() | public int execute() | ||||
| throws IOException, TaskException | throws IOException, TaskException | ||||
| { | { | ||||
| CommandLauncher launcher = vmLauncher != null ? vmLauncher : shellLauncher; | |||||
| if( !useVMLauncher ) | |||||
| CommandLauncher launcher = c_vmLauncher != null ? c_vmLauncher : c_shellLauncher; | |||||
| if( !m_useVMLauncher ) | |||||
| { | { | ||||
| launcher = shellLauncher; | |||||
| launcher = c_shellLauncher; | |||||
| } | } | ||||
| final Process process = launcher.exec( project, getCommandline(), getEnvironment(), workingDirectory ); | |||||
| final Process process = launcher.exec( m_project, getCommandline(), getEnvironment(), m_workingDirectory ); | |||||
| try | try | ||||
| { | { | ||||
| streamHandler.setProcessInputStream( process.getOutputStream() ); | |||||
| streamHandler.setProcessOutputStream( process.getInputStream() ); | |||||
| streamHandler.setProcessErrorStream( process.getErrorStream() ); | |||||
| m_streamHandler.setProcessInputStream( process.getOutputStream() ); | |||||
| m_streamHandler.setProcessOutputStream( process.getInputStream() ); | |||||
| m_streamHandler.setProcessErrorStream( process.getErrorStream() ); | |||||
| } | } | ||||
| catch( IOException e ) | catch( IOException e ) | ||||
| { | { | ||||
| process.destroy(); | process.destroy(); | ||||
| throw e; | throw e; | ||||
| } | } | ||||
| streamHandler.start(); | |||||
| m_streamHandler.start(); | |||||
| // add the process to the list of those to destroy if the VM exits | // add the process to the list of those to destroy if the VM exits | ||||
| // | // | ||||
| processDestroyer.add( process ); | |||||
| c_processDestroyer.add( process ); | |||||
| if( watchdog != null ) | |||||
| watchdog.start( process ); | |||||
| if( m_watchdog != null ) | |||||
| m_watchdog.start( process ); | |||||
| waitFor( process ); | waitFor( process ); | ||||
| // remove the process to the list of those to destroy if the VM exits | // remove the process to the list of those to destroy if the VM exits | ||||
| // | // | ||||
| processDestroyer.remove( process ); | |||||
| c_processDestroyer.remove( process ); | |||||
| if( watchdog != null ) | |||||
| watchdog.stop(); | |||||
| streamHandler.stop(); | |||||
| if( watchdog != null ) | |||||
| watchdog.checkException(); | |||||
| if( m_watchdog != null ) | |||||
| m_watchdog.stop(); | |||||
| m_streamHandler.stop(); | |||||
| if( m_watchdog != null ) | |||||
| m_watchdog.checkException(); | |||||
| return getExitValue(); | return getExitValue(); | ||||
| } | } | ||||
| @@ -489,12 +486,12 @@ public class Execute | |||||
| */ | */ | ||||
| public boolean killedProcess() | public boolean killedProcess() | ||||
| { | { | ||||
| return watchdog != null && watchdog.killedProcess(); | |||||
| return m_watchdog != null && m_watchdog.killedProcess(); | |||||
| } | } | ||||
| protected void setExitValue( int value ) | |||||
| private void setExitValue( final int value ) | |||||
| { | { | ||||
| exitValue = value; | |||||
| m_exitValue = value; | |||||
| } | } | ||||
| protected void waitFor( Process process ) | protected void waitFor( Process process ) | ||||
| @@ -518,443 +515,25 @@ public class Execute | |||||
| throws TaskException | throws TaskException | ||||
| { | { | ||||
| Vector osEnv = (Vector)getProcEnvironment().clone(); | Vector osEnv = (Vector)getProcEnvironment().clone(); | ||||
| for( int i = 0; i < env.length; i++ ) | |||||
| for( int i = 0; i < m_environment.length; i++ ) | |||||
| { | { | ||||
| int pos = env[ i ].indexOf( '=' ); | |||||
| int pos = m_environment[ i ].indexOf( '=' ); | |||||
| // Get key including "=" | // Get key including "=" | ||||
| String key = env[ i ].substring( 0, pos + 1 ); | |||||
| String key = m_environment[ i ].substring( 0, pos + 1 ); | |||||
| int size = osEnv.size(); | int size = osEnv.size(); | ||||
| for( int j = 0; j < size; j++ ) | for( int j = 0; j < size; j++ ) | ||||
| { | { | ||||
| if( ( (String)osEnv.elementAt( j ) ).startsWith( key ) ) | |||||
| if( ((String)osEnv.elementAt( j )).startsWith( key ) ) | |||||
| { | { | ||||
| osEnv.removeElementAt( j ); | osEnv.removeElementAt( j ); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| osEnv.addElement( env[ i ] ); | |||||
| osEnv.addElement( m_environment[ i ] ); | |||||
| } | } | ||||
| String[] result = new String[ osEnv.size() ]; | String[] result = new String[ osEnv.size() ]; | ||||
| osEnv.copyInto( result ); | osEnv.copyInto( result ); | ||||
| return result; | return result; | ||||
| } | } | ||||
| /** | |||||
| * A command launcher for a particular JVM/OS platform. This class is a | |||||
| * general purpose command launcher which can only launch commands in the | |||||
| * current working directory. | |||||
| * | |||||
| * @author RT | |||||
| */ | |||||
| private static class CommandLauncher | |||||
| { | |||||
| /** | |||||
| * Launches the given command in a new process. | |||||
| * | |||||
| * @param project The project that the command is part of | |||||
| * @param cmd The command to execute | |||||
| * @param env The environment for the new process. If null, the | |||||
| * environment of the current proccess is used. | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| if( project != null ) | |||||
| { | |||||
| project.log( "Execute:CommandLauncher: " + | |||||
| Commandline.toString( cmd ), Project.MSG_DEBUG ); | |||||
| } | |||||
| return Runtime.getRuntime().exec( cmd, env ); | |||||
| } | |||||
| /** | |||||
| * Launches the given command in a new process, in the given working | |||||
| * directory. | |||||
| * | |||||
| * @param project The project that the command is part of | |||||
| * @param cmd The command to execute | |||||
| * @param env The environment for the new process. If null, the | |||||
| * environment of the current proccess is used. | |||||
| * @param workingDir The directory to start the command in. If null, the | |||||
| * current directory is used | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env, File workingDir ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| if( workingDir == null ) | |||||
| { | |||||
| return exec( project, cmd, env ); | |||||
| } | |||||
| throw new IOException( "Cannot execute a process in different directory under this JVM" ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * A command launcher that proxies another command launcher. Sub-classes | |||||
| * override exec(args, env, workdir) | |||||
| * | |||||
| * @author RT | |||||
| */ | |||||
| private static class CommandLauncherProxy extends CommandLauncher | |||||
| { | |||||
| private CommandLauncher _launcher; | |||||
| CommandLauncherProxy( CommandLauncher launcher ) | |||||
| { | |||||
| _launcher = launcher; | |||||
| } | |||||
| /** | |||||
| * Launches the given command in a new process. Delegates this method to | |||||
| * the proxied launcher | |||||
| * | |||||
| * @param project Description of Parameter | |||||
| * @param cmd Description of Parameter | |||||
| * @param env Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| return _launcher.exec( project, cmd, env ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * A command launcher for JDK/JRE 1.1 under Windows. Fixes quoting problems | |||||
| * in Runtime.exec(). Can only launch commands in the current working | |||||
| * directory | |||||
| * | |||||
| * @author RT | |||||
| */ | |||||
| private static class Java11CommandLauncher extends CommandLauncher | |||||
| { | |||||
| /** | |||||
| * Launches the given command in a new process. Needs to quote arguments | |||||
| * | |||||
| * @param project Description of Parameter | |||||
| * @param cmd Description of Parameter | |||||
| * @param env Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| // Need to quote arguments with spaces, and to escape quote characters | |||||
| String[] newcmd = new String[ cmd.length ]; | |||||
| for( int i = 0; i < cmd.length; i++ ) | |||||
| { | |||||
| newcmd[ i ] = Commandline.quoteArgument( cmd[ i ] ); | |||||
| } | |||||
| if( project != null ) | |||||
| { | |||||
| project.log( "Execute:Java11CommandLauncher: " + | |||||
| Commandline.toString( newcmd ), Project.MSG_DEBUG ); | |||||
| } | |||||
| return Runtime.getRuntime().exec( newcmd, env ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * A command launcher for JDK/JRE 1.3 (and higher). Uses the built-in | |||||
| * Runtime.exec() command | |||||
| * | |||||
| * @author RT | |||||
| */ | |||||
| private static class Java13CommandLauncher extends CommandLauncher | |||||
| { | |||||
| private Method _execWithCWD; | |||||
| public Java13CommandLauncher() | |||||
| throws NoSuchMethodException | |||||
| { | |||||
| // Locate method Runtime.exec(String[] cmdarray, String[] envp, File dir) | |||||
| _execWithCWD = Runtime.class.getMethod( "exec", new Class[]{String[].class, String[].class, File.class} ); | |||||
| } | |||||
| /** | |||||
| * Launches the given command in a new process, in the given working | |||||
| * directory | |||||
| * | |||||
| * @param project Description of Parameter | |||||
| * @param cmd Description of Parameter | |||||
| * @param env Description of Parameter | |||||
| * @param workingDir Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env, File workingDir ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| try | |||||
| { | |||||
| if( project != null ) | |||||
| { | |||||
| project.log( "Execute:Java13CommandLauncher: " + | |||||
| Commandline.toString( cmd ), Project.MSG_DEBUG ); | |||||
| } | |||||
| Object[] arguments = {cmd, env, workingDir}; | |||||
| return (Process)_execWithCWD.invoke( Runtime.getRuntime(), arguments ); | |||||
| } | |||||
| catch( InvocationTargetException exc ) | |||||
| { | |||||
| Throwable realexc = exc.getTargetException(); | |||||
| if( realexc instanceof ThreadDeath ) | |||||
| { | |||||
| throw (ThreadDeath)realexc; | |||||
| } | |||||
| else if( realexc instanceof IOException ) | |||||
| { | |||||
| throw (IOException)realexc; | |||||
| } | |||||
| else | |||||
| { | |||||
| throw new TaskException( "Unable to execute command", realexc ); | |||||
| } | |||||
| } | |||||
| catch( Exception exc ) | |||||
| { | |||||
| // IllegalAccess, IllegalArgument, ClassCast | |||||
| throw new TaskException( "Unable to execute command", exc ); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * A command launcher for Mac that uses a dodgy mechanism to change working | |||||
| * directory before launching commands. | |||||
| * | |||||
| * @author RT | |||||
| */ | |||||
| private static class MacCommandLauncher extends CommandLauncherProxy | |||||
| { | |||||
| MacCommandLauncher( CommandLauncher launcher ) | |||||
| { | |||||
| super( launcher ); | |||||
| } | |||||
| /** | |||||
| * Launches the given command in a new process, in the given working | |||||
| * directory | |||||
| * | |||||
| * @param project Description of Parameter | |||||
| * @param cmd Description of Parameter | |||||
| * @param env Description of Parameter | |||||
| * @param workingDir Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env, File workingDir ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| if( workingDir == null ) | |||||
| { | |||||
| return exec( project, cmd, env ); | |||||
| } | |||||
| System.getProperties().put( "user.dir", workingDir.getAbsolutePath() ); | |||||
| try | |||||
| { | |||||
| return exec( project, cmd, env ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| System.getProperties().put( "user.dir", antWorkingDirectory ); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * A command launcher that uses an auxiliary perl script to launch commands | |||||
| * in directories other than the current working directory. | |||||
| * | |||||
| * @author RT | |||||
| */ | |||||
| private static class PerlScriptCommandLauncher extends CommandLauncherProxy | |||||
| { | |||||
| private String _script; | |||||
| PerlScriptCommandLauncher( String script, CommandLauncher launcher ) | |||||
| { | |||||
| super( launcher ); | |||||
| _script = script; | |||||
| } | |||||
| /** | |||||
| * Launches the given command in a new process, in the given working | |||||
| * directory | |||||
| * | |||||
| * @param project Description of Parameter | |||||
| * @param cmd Description of Parameter | |||||
| * @param env Description of Parameter | |||||
| * @param workingDir Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env, File workingDir ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| if( project == null ) | |||||
| { | |||||
| if( workingDir == null ) | |||||
| { | |||||
| return exec( project, cmd, env ); | |||||
| } | |||||
| throw new IOException( "Cannot locate antRun script: No project provided" ); | |||||
| } | |||||
| // Locate the auxiliary script | |||||
| String antHome = project.getProperty( "ant.home" ); | |||||
| if( antHome == null ) | |||||
| { | |||||
| throw new IOException( "Cannot locate antRun script: Property 'ant.home' not found" ); | |||||
| } | |||||
| String antRun = FileUtil. | |||||
| resolveFile( project.getBaseDir(), antHome + File.separator + _script ).toString(); | |||||
| // Build the command | |||||
| File commandDir = workingDir; | |||||
| if( workingDir == null && project != null ) | |||||
| { | |||||
| commandDir = project.getBaseDir(); | |||||
| } | |||||
| String[] newcmd = new String[ cmd.length + 3 ]; | |||||
| newcmd[ 0 ] = "perl"; | |||||
| newcmd[ 1 ] = antRun; | |||||
| newcmd[ 2 ] = commandDir.getAbsolutePath(); | |||||
| System.arraycopy( cmd, 0, newcmd, 3, cmd.length ); | |||||
| return exec( project, newcmd, env ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * A command launcher that uses an auxiliary script to launch commands in | |||||
| * directories other than the current working directory. | |||||
| * | |||||
| * @author RT | |||||
| */ | |||||
| private static class ScriptCommandLauncher extends CommandLauncherProxy | |||||
| { | |||||
| private String _script; | |||||
| ScriptCommandLauncher( String script, CommandLauncher launcher ) | |||||
| { | |||||
| super( launcher ); | |||||
| _script = script; | |||||
| } | |||||
| /** | |||||
| * Launches the given command in a new process, in the given working | |||||
| * directory | |||||
| * | |||||
| * @param project Description of Parameter | |||||
| * @param cmd Description of Parameter | |||||
| * @param env Description of Parameter | |||||
| * @param workingDir Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env, File workingDir ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| if( project == null ) | |||||
| { | |||||
| if( workingDir == null ) | |||||
| { | |||||
| return exec( project, cmd, env ); | |||||
| } | |||||
| throw new IOException( "Cannot locate antRun script: No project provided" ); | |||||
| } | |||||
| // Locate the auxiliary script | |||||
| String antHome = project.getProperty( "ant.home" ); | |||||
| if( antHome == null ) | |||||
| { | |||||
| throw new IOException( "Cannot locate antRun script: Property 'ant.home' not found" ); | |||||
| } | |||||
| String antRun = FileUtil. | |||||
| resolveFile( project.getBaseDir(), antHome + File.separator + _script ).toString(); | |||||
| // Build the command | |||||
| File commandDir = workingDir; | |||||
| if( workingDir == null && project != null ) | |||||
| { | |||||
| commandDir = project.getBaseDir(); | |||||
| } | |||||
| String[] newcmd = new String[ cmd.length + 2 ]; | |||||
| newcmd[ 0 ] = antRun; | |||||
| newcmd[ 1 ] = commandDir.getAbsolutePath(); | |||||
| System.arraycopy( cmd, 0, newcmd, 2, cmd.length ); | |||||
| return exec( project, newcmd, env ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * A command launcher for Windows 2000/NT that uses 'cmd.exe' when launching | |||||
| * commands in directories other than the current working directory. | |||||
| * | |||||
| * @author RT | |||||
| */ | |||||
| private static class WinNTCommandLauncher extends CommandLauncherProxy | |||||
| { | |||||
| WinNTCommandLauncher( CommandLauncher launcher ) | |||||
| { | |||||
| super( launcher ); | |||||
| } | |||||
| /** | |||||
| * Launches the given command in a new process, in the given working | |||||
| * directory. | |||||
| * | |||||
| * @param project Description of Parameter | |||||
| * @param cmd Description of Parameter | |||||
| * @param env Description of Parameter | |||||
| * @param workingDir Description of Parameter | |||||
| * @return Description of the Returned Value | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public Process exec( Project project, String[] cmd, String[] env, File workingDir ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| File commandDir = workingDir; | |||||
| if( workingDir == null ) | |||||
| { | |||||
| if( project != null ) | |||||
| { | |||||
| commandDir = project.getBaseDir(); | |||||
| } | |||||
| else | |||||
| { | |||||
| return exec( project, cmd, env ); | |||||
| } | |||||
| } | |||||
| // Use cmd.exe to change to the specified directory before running | |||||
| // the command | |||||
| final int preCmdLength = 6; | |||||
| String[] newcmd = new String[ cmd.length + preCmdLength ]; | |||||
| newcmd[ 0 ] = "cmd"; | |||||
| newcmd[ 1 ] = "/c"; | |||||
| newcmd[ 2 ] = "cd"; | |||||
| newcmd[ 3 ] = "/d"; | |||||
| newcmd[ 4 ] = commandDir.getAbsolutePath(); | |||||
| newcmd[ 5 ] = "&&"; | |||||
| System.arraycopy( cmd, 0, newcmd, preCmdLength, cmd.length ); | |||||
| return exec( project, newcmd, env ); | |||||
| } | |||||
| } | |||||
| } | } | ||||