Search code examples
javabashjarexecute

executing bash commands from a specific directory


From my application I have to execute an external jar of which I do not have the source. Given an input file, it processes it, creates an "output" directory and puts in it an mxml output file. Problem is: it creates said directory in tomcat/bin instead of inside the directory of the original file.

Here's what I've tried so far. Initially

Process p = new ProcessBuilder("java -jar "+newfile.getParent()+"\\converter.jar "+newfile.getPath()+" -mxml").start();

Then, seeing how from console the "output" directory was created in the directory the command was called from, I tried:

String startSim[] = {"cd "+newfile.getParent()+"\\" , "java -jar converter.jar "+newfile.getName()+" -mxml"};

try {
    Runtime.getRuntime().exec(startSim).waitFor();
} catch (Exception e) {
    e.printStackTrace();
    System.out.println("Log non creato.");
}

But with this I get the "file not found" exception for the first instruction. Does anyone know how to possibly solve this problem? I'd like to avoid having to reach for my output file all the way in my tomcat/bin directory.

Thanks for any suggestion! Paolo

P.s.: by the way, before trying all this I tried simply calling the method I need from the library, but had the same exact problem. So I resolved to execute the jar, instead. And here we are. :)


Solution

  • You can set working directory using ProcessBuilder.directory() method:

    ProcessBuilder pb = new ProcessBuilder();
    pb.directory(new File("mydirectory"));
    pb.command(......);
    

    etc

    This does not work for you when you are using Runtime.exec() because cd command is a functionality of shell. You could solve it using this technique but you have to create platform specific command with prefix like cmd /c on windows or /bin/sh on Linux. This way is definitely not recommended.

    But in your specific case you do not neither first nor second solution. Actually you are starting one java process from another. Why? you can easily invoke the main() method of the second process directly.

    Take a look on META-INF/MANIFEST.mf file from converter.jar. Field Main-Class contains the fully qualified name of main class. Let's say it is com.converters.Main (just for example). In this case you can invoke

    com.converters.Main.main(new String[] {newFile.getPath(), "-mxml"});
    

    directly from your code. Just add the jar to your classpath.

    Concerning to changing working directory in this case. Check again whether you really need this or your converters.jar supports parameter that does this.