问题
I'm moving our servlets (pure Java, running in Tomcat 6) from CentOS to Debian, and faced the problem with executing commands with Runtime.exec()
.
(The command should be ImageMagick's convert
in production, but I have simplified the calls to find the source of problems, so all the following code with echo
is tested and not working as well).
String command = "echo test123 > /tmp/tomcat6-tmp/1";
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(command);
int exitVal = process.waitFor();
Seems to be pretty common way to call an external program. It does run, returns 0
in exitVal
, but fails to create file and put text in it.
So does low-level approach:
ProcessBuilder pb = new ProcessBuilder("echo", "test123 > /tmp/tomcat6-tmp/3");
Process process = pb.start();
int resInt = process.waitFor();
But it is possible to create a file and put some text in it using Java code placed in the same method:
String fname = "/tmp/tomcat6-tmp/2";
File file = new File(fname);
file.createNewFile();
FileWriter fileWriter = new FileWriter(file);
fileWriter.write("test123");
fileWriter.close();
Runtime.exec("whoami")
successfully returns tomcat6
, the folder /tmp/tomcat6-tmp/
does exist, all permissions are set correctly.
$ ls -al /tmp/tomcat6-tmp/
total 60
drwxr-xr-x 2 tomcat6 root 4096 Mar 2 15:26 .
drwxrwxrwt 6 root root 4096 Mar 2 15:25 ..
-rw-r--r-- 1 tomcat6 tomcat6 7 Mar 2 15:26 2
All commands without need to access files in system are seem to execute normally with Runtime.exec()
in the same context.
I use fresh install of debian squeeze with tomcat6 installed from packages, without any modifications in configuration:
$ aptitude show tomcat6
Package: tomcat6
State: installed
Version: 6.0.28-9+squeeze1
.....
$ cat /etc/issue
Debian GNU/Linux 6.0 \n \l
How can I solve the issue? Or at least where should I look? I've googled every imaginable reason for Java to misbehave this way, but failed to find a clue.
P.S. As this is default installation, Java security manager is disabled in /etc/init.d/tomcat6
# Use the Java security manager? (yes/no)
TOMCAT6_SECURITY=no
回答1:
Put the action you want into a single executable shell script, then exec
the shell script.
Java's Runtime.exec()
is a wrapper around the exec
system call, which will run the process directly, rather than under a sub-shell. The >
redirection is carried out by the shell, and will not work as an argument to a directly exec
ed process.
回答2:
Don't know if this "echo test123 > /tmp/tomcat6-tmp/1" can be run as one command. I remember that I had similar problem and I had to split it, so try to run "echo test123" and then obtain an input stream with the output of the command. If you have a stream you can easily write to file.
Moreover, you execute command with args so try to use method that takes array as a parameter.
来源:https://stackoverflow.com/questions/5168806/runtime-exec-from-tomcat6-succeeds-but-cannot-access-any-files