JDK-4202425 : Java Runtime.exec() tries to execute a directory
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.1.7,1.2.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: solaris_2.6
  • CPU: generic
  • Submitted: 1999-01-12
  • Updated: 1999-05-20
  • Resolved: 1999-05-20
Related Reports
Duplicate :  
Description
Copy of bug 4199993 in java_solaris category - fixed in Solaris Java,
needs to be fixed in reference platforms.
--------------------------------------------------------------------------
	If Runtime.exec() locates a directory (with execute permission, I
	assume) in the PATH, it will try to execute it and will get an error.
	For example, I have a Java program which calls
	Runtime.exec("netscape"). If I run this program, it normally starts
	netscape. However, if I run this program in a location which contains
	a directory called "netscape", I get an error.
	
	From the command line, if I type "netscape" from the same location, it
	starts netscape despite the presence of the "netscape" directory.
	
	Here's how to reproduce the problem.
	
	1) Make sure "." is the first thing in your PATH.
	
	2) Create an executable script called "foo" and place it anywhere on
	   your path except the directory in which we will be performing the
	   test. The script can be something like:
	
	   #!/bin/ksh
	   print "Hello from foo!"
	
	3) Create a new directory for testing. Compile this Java program in
	   that directory:
	
	   import java.io.*;
	
	   public class Main
	   {
	
	   static public void
	   main(
	       String[] args)
	       throws IOException, InterruptedException
	   {
	       String[] command = {
		   "foo"
	       };
	
		   Runtime runtime = Runtime.getRuntime();
	
		   Process process = runtime.exec(command);
		   process.waitFor();
	
		   System.out.println("Exit value = " + process.exitValue());
	   }
	
	   }
	
	
	4) Create a sub-directory called "foo". Make sure it has execute
	   permission for the owner (this should be the default setting).
	
	5) From the command line, try this sequence, execute "foo" and verify
	   that the script in step (2) is executed properly.
	
	6) Run the Java program. The output will be:
	
	   java.io.IOException: foo: cannot execute
		   at java.lang.Runtime.exec(Compiled Code)
		   at java.lang.Runtime.exec(Compiled Code)
		   at Main.main(Compiled Code)
	   *** Error code 1
	
	7) Delete the "foo" directory and re-run the program. The output is
	   now
	
	   Exit value = 0
	
	8) Re-create the "foo" directory, but now place it somewhere else on
	   the PATH, *before* the "foo" script. Re-run the program. The output
	   is again:
	
	   java.io.IOException: foo: cannot execute
		   at java.lang.Runtime.exec(Compiled Code)
		   at java.lang.Runtime.exec(Compiled Code)
		   at Main.main(Compiled Code)
	   *** Error code 1
	
	
	The presence of a directory should not affect whether a Java program
	can execute a sub-process or not. This is specially bad since the
	directory can be anywhere in the PATH ahead of the desired executable.

Comments
SUGGESTED FIX In the routine fullPath(), in process_md.c (1.1.7) or UNIXProcess_md.c (1.2): --- UNIXProcess_md.c Tue Jan 12 13:19:17 1999 *************** *** 121,129 **** if (ret == -1) { /* doesn't exist */ continue; } else if (ret == -2) { /* can't execute */ ! jio_snprintf(full, MAXPATHLEN, "%s: cannot execute", part); ! JNU_ThrowByName(env, "java/io/IOException", full); ! return 0; } else { return full; } --- 121,127 ---- if (ret == -1) { /* doesn't exist */ continue; } else if (ret == -2) { /* can't execute */ ! continue; /* bug 4199993 - got to keep searching. */ } else { return full; }
11-06-2004

EVALUATION Please see Bug 4109888. The JLS does not specify the sematic behavior of Runtime.exec(). The method internal will call system api, whatever the api returns will be the result. I don't think the runtime should do the path searching, unless we have a clear spec how to do it. ###@###.### 1999-01-13 If your PATH is "/a:/b" and "/a/foo" is a directory, then even your shell (I tested bash and csh) will complain about not being able to run "foo" and quit -- it will not ignore/continue/find/run "/b/foo" (which is a runnable program). Silently skipping the error, and finding the next (potentially) random thing on the PATH will be counter-intuitive to Unix users, so IMO this is not a bug, and the suggested fix should not be incorporated. However the error reporting can be better: bash says "can't execute because it is a directory" as opposed to Runtime.exec and csh which just say "can't execute." But it isn't hard to figure this out though. anand.palaniswamy@Eng 1999-01-20
20-01-1999