2016-09-17 50 views
6

Jestem w trakcie budowania słoja opakowania dla słoika, który zbudowałem. Zajmie się aktualizacją głównej aplikacji i upewnieniem się, że użytkownicy są ważnymi użytkownikami. Mam jednak poważny problem, ponieważ nie mogę uruchomić zewnętrznej funkcji uruchamiania słoika. Oto, co mam do tej pory:Java rozpoczyna inną aplikację Java

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

Jednak otrzymuję wyjątek od pliku.

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 

Po skopiowaniu java -jar ~/Documents.Java/myJar.jar i wklejeniu go do terminala działa i uruchamia się słoik. Nie mam pojęcia, co się tutaj dzieje. Czy ścieżka powinna być względna względem położenia działającego słoika?

Odpowiedz

6

pobliżu naiwniaczek Java execute process on linux i Difference between ProcessBuilder and Runtime.exec()

Oprócz odpowiednich punktów o tilde- (nie) ekspansja są przechodzącą całą wiersza poleceń jako jeden argument new ProcesssBuilder. W przeciwieństwie do Runtime.exec(), który traktuje pojedynczy String jako specjalny przypadek i dzieli go na znaczniki rozdzielone białymi znakami głównie (ale nie dokładnie) jak typowe powłoki uniksowe, ctor tego nie robi. Można to zobaczyć w komunikacie wyjątku na początku publikowanego przez ciebie postu. Musisz oddzielne argumenty jak:

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 

lub ewentualnie (ale nie polecam)

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 

I zastąpić java przez pełną ścieżkę jeśli pożądany java program (lub link do niego) nie zostanie znaleziony jako pierwszy podczas wyszukiwania PATH obowiązującej dla procesu JVM.

8

Ekspansja tyldy (wiodąca ~) jest cechą powłoki. Nie wywołujesz java przez powłokę, więc to się nie dzieje. Użyj metody System.getProperty("user.home"), aby znaleźć katalog domowy użytkownika i zbuduj polecenie, używając zamiast tego tyldy.

+0

OK, nadal otrzymuję wyjątek od znalezienia pliku. Zmieniłem to, co sugerowałeś, a potem odmówiono mi pozwolenia. Wyjaśniłem, jak ustawić plik do pliku wykonywalnego, ale wróciłem do pliku, który nie został znaleziony ponownie. – Aaron

+0

Czy potwierdziłeś, że 'user.dir' ma poprawną wartość? Czy potwierdziłeś, że budujesz ścieżkę poprawnie? Pokaż kompletną końcową złożoną linię komend, którą przechodzisz do 'ProcessBuilder' –

+0

Tak, ścieżka jest teraz poprawna. Potwierdziłem to. – Aaron

1

Mam nieco inny pomysł - oczywiście Jim ma rację, ponieważ "~" nie zadziała w konstruktorze procesu; i używanie preferencji systemowych jest zwykle drogą do zrobienia.

Dodatkowo zasugerowałem: po prostu weryfikuj z góry, że nazwa pliku, którego używasz w linii poleceń wskazuje na istniejący plik.

Dlaczego nie utworzyć obiektu pliku wskazującego na plik JAR? Nie musisz więc czekać na pojawienie się wyjątków IOExceptions, wykonujesz proste wywołanie exist(), aby zrozumieć, czy ścieżka, którą zebrałeś dla JAR, ma sens. I możesz zrobić to samo dla pliku wykonywalnego java!

+0

W końcu skończyłem robić to dla celów debugowania, ale zachowam go do sprawdzenia, tak jak sugerowałeś. – Aaron