6

I am in the process of building a wrapper jar for a jar that I built. It will handle updating the main application and making sure users are valid users. I am having a major issue though, because I can't get the external jar launching function working. This is what I have so far:

ProcessBuilder builder = new ProcessBuilder("java -jar ~/Documents.Java/myJar.jar");
try {
    Process process = builder.start();
} catch (Exception e) {
    e.printStackTrace();
}

However, I am just getting a file not found exception.

java.io.IOException: Cannot run program "java -jar ~/Documents/Java/myJar.jar": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at com.mycompany.DHSLauncher.Launcher.lambda$4(Launcher.java:109)
at java.util.Optional.ifPresent(Optional.java:159)
at com.mycompany.DHSLauncher.Launcher.showLogin(Launcher.java:102)
at com.mycompany.DHSLauncher.Launcher.start(Launcher.java:35)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)

Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:248)
at java.lang.ProcessImpl.start(ProcessImpl.java:134)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 10 more

If I copy java -jar ~/Documents.Java/myJar.jar and paste it right into terminal, it works and the jar launches. I have no idea what is going on here. Is the path supposed to be relative to the location of the running jar?

3 Answers 3

8

Tilde expansion (the leading ~) is a feature of the shell. You are not invoking java through a shell, so that is not happening. Use the System.getProperty("user.home") method to find the user's home directory and build the command using that instead of the tilde.

Sign up to request clarification or add additional context in comments.

9 Comments

Ok, I am still getting the file not found exception. I changed to what you suggested, and then I got a permission denied. I figured out how to set the file to executable, but I am back to the file not found again.
Did you confirm that user.dir has the correct value? Did you confirm that you are building the path correctly? Show the complete final assembled command line that you are passing to ProcessBuilder
Show the complete final assembled command line that you are passing to ProcessBuilder. You will also need to provide the complete path to the java command, as it may not be on the path.
ProcessBuilder builder = new ProcessBuilder("java -jar " + System.getProperty("user.home") + "/Documents/Java/myJar.jar"); I also echoed builder.directory(), and it returns null.
No. Put the concatenated command into a String before invoking ProcessBuilder and print out that string.
|
6

Near dupe Java execute process on linux and Difference between ProcessBuilder and Runtime.exec()

In addition to the correct points about tilde-(non-)expansion, you are passing an entire commandline as one argument to new ProcesssBuilder. Unlike Runtime.exec() which treats a single String as a special case and splits into whitespace-delimited tokens mostly (but not exactly) like typical Unix shells, the ProcessBuilder ctor does not do this. This can be seen in the exception message at the beginning of the traceback you posted. You need separate arguments like:

ProcessBuilder builder = new ProcessBuilder("java", "-jar", 
    System.getProperty("user.home")+"/Documents.Java/myJar.jar");
// three String's passed to vararg, compiler makes array for you

or possibly (but I don't recommend)

String line = "java -jar " + System.getProperty("user.home")+"/Documents.Java/myJar.jar";
ProcessBuilder builder = new ProcessBuilder( line.split(" ") );
// array of three String's passed directly to vararg

And replace java by a full pathname if the desired java program (or a link to it) isn't found first when searching the PATH in effect for your JVM process.

Comments

1

I have a somewhat different idea - of course Jim is correct as in "~" will not work within the process builder; and using the System prefs is normally the way to go.

On top of that I suggested: simply verify in advance that any filename you are using on the command line points to an existing file.

Why not create a File object pointing to your JAR? So you don't need to wait for IOExceptions to happen, you do a simple exists() call to understand if path that you pulled together for your JAR makes sense. And you could do the same for your java executable!

1 Comment

In the end I ended up doing this for debugging purposes, but I will keep it to validate like you suggested.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.