United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 4216884 (process) Runtime.exec() fails
4216884 : (process) Runtime.exec() fails

Details
Type:
Bug
Submit Date:
1999-03-03
Status:
Closed
Updated Date:
2001-11-02
Project Name:
JDK
Resolved Date:
2001-11-02
Component:
core-libs
OS:
windows_nt,windows_95
Sub-Component:
java.lang
CPU:
x86
Priority:
P4
Resolution:
Not an Issue
Affected Versions:
1.2.0,1.3.0
Fixed Versions:

Related Reports

Sub Tasks

Description

Name: dbT83986			Date: 03/03/99


When using:

java version "1.2fcs"
Calssic VM (build JDK-1.2fcs-0, native threads)

Runtime.exe() always returns this error:

java.io.IOException: CreateProcess: 
"c:\windows\command.com /C c:\test\go.bat"
error=0

The same code works fine on 1.1.6 (and others).

javac (1.1.6) and javac (1.2) produce class files
with different sizes.  java (1.1.6) can correctly
execute both and java (1.2) can execute neither.

I have tried every permutation of exec() I can
think of and no luck.

Source code follows:


import java.io.*;
import java.lang.*;


class Test {


   Test () {
      String         WINpath = "c:\\windows\\";

      try {
         Runtime rt = java.lang.Runtime.getRuntime();

         String  st[] = { WINpath + "command.com /C " +
                          "c:\\test\\go.bat" };

         Process pr = rt.exec (st);
         try {
            pr.waitFor();
         } catch (InterruptedException e) {}
      } catch (IOException e) {
         System.out.println ("IOE: " + e);
      }
         
    }


    public static void main (String args[]) {
     new Test();
    }
}


And go.bat consists of a single line:

dir > file.lst
(Review ID: 48389)
======================================================================

                                    

Comments
WORK AROUND



Name: dbT83986			Date: 03/03/99


don't use 1.2, use 1.1.x instead.
======================================================================
                                     
2004-06-11
EVALUATION

SHORT ANSWER

The program specified does not exist, so it can not be created.  Here's the 
reported error message:

  java.io.IOException: CreateProcess: "c:\windows\command.com /C c:\test\go.bat" error=0

Thus, Runtime.exec() is searching for a program called
"c:\windows\command.com /C c:\test\go.bat", not "c:\windows\command.com".

LONG ANSWER

A call to Runtime.exec() will resolve to one of six overloaded methods:

  exec(String cmd)
  exec(String cmd, String envp[])
  exec(String cmd, String envp[], File dir)
  exec(String cmd[])
  exec(String cmd[], String envp[])
  exec(String cmd[], String envp[], File dir)

exec(String cmd)

In the first method, the cmd argument is parsed into tokens where the separator
is ' ', '\t', '\n', '\r', or '\f'.  It is this choice of delimiters that 
causes problems when path components contain spaces (e.g. "c:\Program Files").

The first token is interpreted as the name of the platform-dependent program
that will be executed.  An exception with a detail message beginning with
"java.io.IOException: CreateProcess: ..."  indicates that there was a problem
launching the program.  The full name of the program for which the launch
was attempted is contained within the detail message.  Note that if you provide
bad arguments to program, process creation will succeed and the launched program
will fail.  Assuming that the launched program indicates failure by sending a
message to the error output stream, you can access that stream using 
Process.getErrorStream().

All environment variables set at the time of the call to exec will be propagated
to the newly launched process.

exec(String cmd, String envp[])

The next method treats the cmd as before.  It adds the ability to set the
environment variables.  The envp argument requires the complete specification
of the environment.  It does not add to the environment present at the time of
the launch, it _replaces_ it.  If envp is null, the subprocess will inherit
all of the environment settings of the calling process.  If your program
launches successfully when envp is null but not when it is non-null, then it is
likely that the called program contains hidden or unknown dependencies on a
missing environment variable.

exec(String cmd, String envp[], File dir)

Identical comments for the cmd and envp arguments from the previous methods
apply.  This method adds the ability to set the working directory of the new
process.  If dir is null, then the new process will inherit the current working
directory.  Success when dir is null and failure when dir is not null may
indicate a lack of permission to write in dir or assumptions in the launched
program regarding either its location of that of dependent files.

exec(String cmd[])
exec(String cmd[], String envp[])
exec(String cmd[], String envp[], File dir)

The only difference between these three methods and the corresponding previous
three is in how the cmd is specified.  In these cases, cmd is an array
representing the command and its arguments.  Tokenization as described in the
first method does not occur.  cmd[0] is the platform-dependent program that will
be launched. 


In the code describing the "bug", the problem is with the declaration of st:

   String st[] = { WINpath + "command.com /C " + "c:\\test\\go.bat" };
   Process pr = rt.exec (st);

This means that you're calling Runtime.exec(String cmd[]).  That particular
version will execute the platform-dependent program specified by st[0].  Note
that in this case, st contains exactly one element.  There's the problem.  The
exec method has been asked to locate a program called 

  "...command.com /C c:\\test\\go.bat"

Oops.  The "/C" and "c:\\test\\go.bat" are arguments, not the name of the 
command.  To get this program to work properly with exec(String cmd[]), change
the declaration of st to:

   String st[] = { WINpath + "command.com", "/C", "c:\\test\\go.bat" };

Alternatively, you could use exec(String cmd) with this declaration:

   String st = WINpath + "command.com /C " + "c:\\test\\go.bat";

The key thing to detecting this problem is that the detail message for
the IOException cited a program-name that contained way more than it should
have.

Closing this as "not a bug".

Hope that helps.

Thanks,
-- iag@sfbay 2001-11-02
                                     
2001-11-02



Hardware and Software, Engineered to Work Together