Reputation: 119
Running below command using Runtime exec()
method to generate tar of a directory using java
tar -zcvf dest.tar.gz -C dirTotar .
Java code for tar creation
String command = "tar -zcvf dest.tar.gz -C dirTotar .";
Process process = Runtime.getRuntime().exec(command);
process.waitFor()
return process.exitValue();
Java process is a server which creates tar file after processing after each input. After processing for few input, process is stuck at tar step.
Ran strace -p
to find if process is stuck and it shows below output
strace -p 6782
Process 6782 attached - interrupt to quit
write(1, "./file"..., 66
I ran the tar command manually for the input directory and it works perfectly. Any pointers why this is happening?
Update:
For directory structure like below
/tmp/dir1
/tmp/dir2
/tmp/dir3
.
.
Directory for which tar is being generated by process is dir1. There are other process which are generating tar for dir2, dir3...
When process generating tar for dir1 is stuck one of the other process trying to tar other directory (dir2, dir3) is also stuck. Can this be cause of issue?
Upvotes: 4
Views: 3190
Reputation: 38821
Fact 1: tar zcv...
outputs for each file it archives a line containing the filename of that file. GNU tar, which you are apparently using, outputs the list to stdout when you specify f
with an output file, although it uses stderr when f
is specified or defaulted to -
(which uses stdout for the archive). The length of each line in the list depends on each filename, and the total length of this list depends on the number of files and the total length of their filenames.
Fact 2: a process run by Java Runtime.exec
has its stdout directed to a pipe whose other end is provided to the Java program, so the Java code can read the output from the process. The same is true for stderr, and the reverse for stdin, but they aren't relevant in this case. Your code doesn't read this pipe (or make any use of any of the pipes).
Fact 3: when a process (such as tar
) writes to a pipe and nothing reads from (the other end of) that pipe, when the pipe buffer fills the writing process hangs. Your strace
shows tar
is (apparently hanging) in a write
to fd 1 which is stdout. The size of the pipe buffer can vary depending on your system and sometimes other factors, but is usually a few K bytes, which depending on the names of the files you want to archive might be anywhere from tens to hundreds of filenames.
Solution: either change your code to read the output from tar
-- see Process.getInputStream()
-- or change the command (by removing v
) so it doesn't produce (non-error) output.
PS: As noted in the javadoc, ProcessBuilder
is preferred since Java 5. By default it also uses pipes from and to the new process, but has (several) methods to change this since Java 7.
Upvotes: 4