Question

I'm currently working on a web application that involves mounting a drive and extracting a tar.gz file, all in Java. Since the application runs in a linux environment, I figured I'd try using unix commands like "mount" and "tar".

Runtime runtime = Runtime.getRuntime();
Process proc;

String mountCommand = "mount -t cifs -o username=...";
String extractCommand = "tar xzf ..."

proc = runtime.exec(mountCommand);
proc.waitFor();

proc = runtime.exec(extractCommand);
proc.waitFor();

Running the mount command and extract command in the terminal works fine, but fails when FIRST run in java. The second proc.waitFor() returns exit code 2. However, running this code after the first failed attempt works fine. I have a feeling that the problem is that waitFor() isn't waiting until the mount command is fully completed. Am I missing anything important in my code?

Also, I'd rather do this all in Java, but I had a really hard time figuring out how to untar a file, so I'm taking this approach. (oh if anyone can tell me how to do this i would be very happy). Any suggestions would be muuuuuuuuuuch appreciated!

Was it helpful?

Solution 2

Making progress. In case anyone was wondering, here is how I am extracting a tar.gz file in Java. Put together from a few online tutorials.

public static void extract(String tgzFile, String outputDirectory)
    throws Exception {

// Create the Tar input stream.
FileInputStream fin = new FileInputStream(tgzFile);
GZIPInputStream gin = new GZIPInputStream(fin);
TarInputStream tin = new TarInputStream(gin);

// Create the destination directory.
File outputDir = new File(outputDirectory);
outputDir.mkdir();

// Extract files.
TarEntry tarEntry = tin.getNextEntry();
while (tarEntry != null) {
    File destPath = new File(outputDirectory + File.separator + tarEntry.getName());

    if (tarEntry.isDirectory()) {
    destPath.mkdirs();
    } else {
    // If the parent directory of a file doesn't exist, create it.
    if (!destPath.getParentFile().exists())
        destPath.getParentFile().mkdirs();

    FileOutputStream fout = new FileOutputStream(destPath);
    tin.copyEntryContents(fout);
    fout.close();
    // Presserve the last modified date of the tar'd files.
    destPath.setLastModified(tarEntry.getModTime().getTime());
    }
    tarEntry = tin.getNextEntry();
}
tin.close();
}

OTHER TIPS

Quick Answer

Since a dependency on external commands exists, simplify it like this:

#!/bin/bash
mount -t cifs -o username=...
tar xzf ...

Name it mount-extract.sh then call it using a single Runtime.exec() call.

Semi-integrated Answer

Use Java APIs.

You will need Runtime.exec to execute the mount command.

Forward Looking

Since Java is a cross-platform software development tool, consider abstracting the mount command in your application to be derived dynamically based on the underlying operating system.

See: How can I mount a windows drive in Java?

See: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#getProperties()

Of course, Agile development would insist that this not be done until it is needed. So keep it in the back of your mind until then (as you might never run the application on anything but Unix-based systems).

Take a look at the org.apache.tools.tar package in the Ant codebase. There is a class in that package, TarInputStream, that can be used to read tar archives.

It may be related to the way you call the method.

See this answer

Basically try using

.exec( String [] command );

instead of

.exec( String command );

I'm not sure if it is even related, because you mention it runs the second time. Give it a try and let us know.

This can all be done in Java, but you have to be aware of caveats when dealing with native processes.

The waitFor() command may not be doing what you hope: if the process you started has a child process that does the actual work you need then the waitFor(), which returns when the parent process has finished, has not allowed enough time for the child process to finish.

One way to get around this is to loop over some test to see that the native processes you started have finished to your satisfaction---in this case perhaps checking if some java.io.File exists.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top