Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java starting another Java Application

Tags:

java

jar

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?

like image 529
Aaron Avatar asked Sep 17 '16 04:09

Aaron


3 Answers

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.

like image 164
Jim Garrison Avatar answered Nov 06 '22 22:11

Jim Garrison


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.

like image 20
dave_thompson_085 Avatar answered Nov 06 '22 23:11

dave_thompson_085


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!

like image 1
GhostCat Avatar answered Nov 06 '22 21:11

GhostCat