55 Stimmen

Ausführen einer Java-Anwendung in einem separaten Prozess

Kann eine Java-Anwendung plattformunabhängig in einem separaten Prozess unter Verwendung ihres Namens und nicht ihres Speicherorts geladen werden?

Ich weiß, dass man ein Programm über ... ausführen kann.

Process process = Runtime.getRuntime().exec( COMMAND );

... das Hauptproblem dieser Methode ist, dass solche Aufrufe dann plattformspezifisch sind.

Im Idealfall würde ich eine Methode in etwas so Einfaches wie... verpacken.

EXECUTE.application( CLASS_TO_BE_EXECUTED );

... und geben Sie den voll qualifizierten Namen einer Anwendungsklasse als CLASS_TO_BE_EXECUTED .

1 Stimmen

Also, wenn ich Sie richtig verstehe, haben Sie mehrere Klassen mit main()-Methoden und Sie wollen sie in separaten Prozessen zu starten?

0 Stimmen

Wie wäre es, wenn Sie exec("java.exe", CLASS_TO_BE_EXECUTED.class.getName()) ?

0 Stimmen

Wie man Eingaben von einem Benutzer für eine Java-Klasse, die als Prozess läuft, der selbst von einem Java-Programm gestartet wird, mit etwas wie br.readLine() entgegennimmt

4voto

lothar Punkte 19157

Haben Sie sich die ProcessBuilder API angesehen? Sie ist seit 1.5 verfügbar

http://java.sun.com/javase/6/docs/api/java/lang/ProcessBuilder.html

3voto

TofuBeer Punkte 59410

Müssen Sie sie wirklich nativ starten? Könnten Sie einfach ihre "main"-Methoden direkt aufrufen? Das einzig Besondere an main ist, dass der VM-Launcher es aufruft, nichts hält Sie davon ab, main selbst aufzurufen.

2voto

jasonnerothin Punkte 1516

Im Anschluss an die Ausführungen von TofuBeer: Sind Sie sicher, dass Sie wirklich eine weitere JVM abspalten müssen? Die JVM hat heutzutage eine wirklich gute Unterstützung für Parallelität, so dass Sie eine Menge Funktionalität für relativ billig erhalten können, indem Sie einfach einen oder zwei neue Threads abspinnen (die möglicherweise oder möglicherweise nicht in Foo#main(String[]) aufrufen müssen). Schauen Sie sich java.util.concurrent für weitere Informationen an.

Wenn Sie sich für eine Abspaltung entscheiden, müssen Sie mit einer gewissen Komplexität bei der Suche nach den erforderlichen Ressourcen rechnen. Das heißt, wenn sich Ihre Anwendung häufig ändert und von einer Reihe von Jar-Dateien abhängt, müssen Sie sie alle im Auge behalten, damit sie an das Klassenpfad-Arg weitergegeben werden können. Darüber hinaus erfordert ein solcher Ansatz, dass man sowohl den Standort der (aktuell ausgeführten) JVM (der möglicherweise nicht genau ist) als auch den Standort des aktuellen Klassenpfads ableitet (was noch weniger wahrscheinlich ist, je nachdem, wie der Spawning-Thread aufgerufen wurde - jar, jnlp, explodiertes .classes-Verzeichnis, irgendein Container, usw.).

Andererseits hat das Einbinden in statische #main-Methoden auch seine Tücken. Statische Modifikatoren haben die unangenehme Tendenz, in anderen Code durchzusickern, und sind bei designorientierten Leuten generell verpönt.

0 Stimmen

In der Folge wird RMI involviert sein, die Prozesse fungieren als Daemons für den Haupt-"Kernel"-Prozess, und es besteht die Möglichkeit, dass sie sich nicht auf demselben Computer, sondern irgendwo anders im Netzwerk befinden. Ich dachte jedoch, dass die ursprüngliche Formulierung für mehr Leser nützlich ist.

1voto

Matiaan Punkte 11

Ein Problem, das auftritt, wenn Sie dieses Programm über eine Java-GUI ausführen, ist, dass es im Hintergrund läuft. Sie können die Eingabeaufforderung also überhaupt nicht sehen.

Um dies zu umgehen, müssen Sie die java.exe über "cmd.exe" UND "start" ausführen. Ich weiß nicht warum, aber wenn Sie "cmd /c start" eingeben, wird die Eingabeaufforderung angezeigt, während sie ausgeführt wird.

Das Problem mit "start" ist jedoch, dass wenn der Pfad zur Anwendung ein Leerzeichen enthält (der Pfad zur Java-Exe hat normalerweise ein Leerzeichen, da er in C:\Program Archivos \Java\jre6\bin\java.exe oder ähnlich), dann scheitert der Start einfach mit "cannot find c: \Program "

Sie müssen also Anführungszeichen um Folgendes setzen C:\Program Archivos \Java\jre6\bin\java.exe Jetzt beschwert sich der Start über Parameter, die Sie an java.exe übergeben: "Das System kann die Datei -cp nicht finden."

Das Leerzeichen in "Program Files" durch einen Backslash zu ersetzen, funktioniert ebenfalls nicht. Die Idee ist also, kein Leerzeichen zu verwenden. Erzeugen Sie eine temporäre Datei mit der Erweiterung "bat" und fügen Sie dann Ihren Befehl mit Leerzeichen darin ein und führen Sie die bat aus. Wenn Sie eine Bat-Datei über Start ausführen, wird sie jedoch nicht beendet, Sie müssen also "exit" an das Ende der Batch-Datei setzen.

Das scheint immer noch eklig zu sein.

Auf der Suche nach Alternativen habe ich herausgefunden, dass die Verwendung von Anführungszeichen in der Leerstelle von "Program Files" tatsächlich mit Start funktioniert.

Ändern Sie in der obigen EXECUTE-Klasse den String builder appends to:

append( "cmd /C start \"Some title\" " ).
append( java.lang.System.getProperty( "java.home" ).replaceAll(" ", "\" \"") ).
append( java.io.File.separator ).
append( "bin" ).
append( java.io.File.separator ).
append( "java" ).
append( " " ).
append( new java.io.File( "." ).getAbsolutePath() ).
append( java.io.File.separator ).
append( CLASS_TO_BE_EXECUTED ).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X