Frage

Ich habe eine Java-Web-Services-Code-Basis (BEA / Oracle Weblogic) geerbt und benötigen eine externe Anwendung im Hintergrund von einem Web-Dienst starten / starten.

Ich habe schon versucht:

ProcessBuilder pb = new ProcessBuilder(arg);
pb.start();

als auch

Runtime.exec(cmdString);

Aber erlebe seltsames Verhalten, wenn Anwendungen auf diese Weise zu starten. (Das heißt die gestartete Anwendung nicht mehr funktionierte, auch wenn der Prozess noch aktiv ist. - Die Anwendung funktioniert gut, wenn sie manuell von einem normalen Befehlszeile ausgeführt)

Gibt es einen besseren Weg, um einen externen Prozesse zu starten?

EDIT: ----------------------

Ich habe einige zusätzliche Informationen, die auf das Problem etwas Licht helfen können.

  • Der Prozess, den wir Stunden zu starten versuchen, erfordert so abzuschließen für die Fertigstellung warten (mit waitfor()) in den Webservice wird kein ideales Szenario sein.
  • Ja, der Prozess, den wir versuchen, von dem Webservice zu starten wurde von einem anderen Teammitglied erstellt [Stichwort: Ihre Augen rollt ... jetzt]

Ich hatte Erfolg , wenn ich Process Builder verwenden, um einen Bash-Skript zu starten, in dem die externen Anwendung als gestartet wird Hintergrundprozess (mit "&").

#!/bin/bash
java -jar myApp.jar &

Das schafft natürlich einen verwaisten Prozess, aber zumindest die Anwendung auszuführen nicht fortgesetzt werden.

War es hilfreich?

Lösung

Einfach ausgedrückt: Wenn die gestartete Anwendung zu SDTOUT / STDIN schreibt und Sie spülen sie nicht häufig (siehe Process.getErrorStream / Process.getInputStream), dann der Prozess blockiert wird, wenn der Puffer voll ist (das ist wirklich klein, 4 KB oder weniger).

Ich empfehle Ihnen ProcessBuilder.redirectErrorStream () aufrufen, bevor der Prozess beginnt. Dann, nachdem das Erstellen eines Gewindes mit dem run () Methode entlang der Linien von:

public void run() {
    BufferedReader reader = 
        new BufferedReader(new InputStreamReader(process.getInputStream()));
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
}

Andere Tipps

Mit dem „nicht mehr funktioniert, auch wenn der Prozess noch aktiv ist:“ Ich gehe davon aus Sie könnten einige Ausgabe der Anwendung erwarten Sie ins Leben gerufen haben und nichts zu bekommen.

Versuchen Sie die folgende Verwendung:

ProcessBuilder pb = new ProcessBuilder(arg);
Process p = pb.start();
p.waitFor();

waitFor () bewirkt, dass der aktuelle Thread, warten, falls erforderlich, bis der Prozess nach diesem Verfahren Objekt dargestellt beendet hat.

http: // java .sun.com / JavaSE / 6 / docs / api / java / lang / Process.html # waitFor ()

Zum einen geschieht dies unter Windows oder Linux? Auch, was ist die gestartete Anwendung sollte mehr oder weniger tun? (Ist es ein Script ist es ein binäres? Ist es Ihre binary?)

Bearbeiten

OK, also einen bash Skript starten (mit ProcessBuilder), die abwechselnd einen neuen JVM laicht (java -jar myApp.jar) funktioniert.

Was genau passiert, wenn Sie versuchen, die neue JVM zum Laichen direkt mit ProcessBuilder? Sie ursprünglich gesagt:

  

die gestartete Anwendung nicht mehr funktioniert

  1. Mit dem gestarteten Anwendung tun Sie bedeuten "java -jar myapp.jar", wenn sie direkt aufgerufen, nicht über eine Zwischen bash Skript?
  2. Was sind die genauen und vollständigen Parameter (und ihre Werte) übergeben Sie an die verschiedenen ProcessBuilder Methoden (und in welcher Reihenfolge), wenn Sie versuchen, Java direkt zu starten und diese neue JVM nicht mehr funktioniert? (Z kommentierte Code zur Verfügung stellen)
  3. Wenn Sie lsof auf * nix-Maschine installieren, welche Datei mit Dateideskriptor 2 verbunden sein gezeigt wird (Blick auf die FD Spalte) beim Laufen: lsof -p 1234 (wo 1234 die Prozess-ID von dem „aufgehängt“ JVM?) es könnte interessant sein, hier die gesamte Ausgabe des lsof Befehls zu befestigen.
  4. Was an die Datei angefügt wird Sie in Schritt 3 oben identifiziert haben (für Dateideskriptor 2), bis zu mehreren Sekunden, nachdem Sie den Befehl: (wo kill -QUIT 1234 die Prozess-ID des „gehängt“ JVM) 1234

Umgang Sie richtig die Standardeingabe und -ausgabe des Prozesses? Wenn die Standard-Ein- oder Ausgang wird von der Anwendung verarbeitet werden, und Sie sind nicht richtig es Handhabung, dann geht der Prozess Sie hängt ausführen für E / A warten.

Ein Weg, dies zu testen, ist ein Skript zu schreiben, die Ihr Programm läuft, Umleitung der Standardeingabe, Ausgabe und Fehler auf Dateien. Dann haben Sie Ihre Web-Service-App das Skript anstelle des Programms ausgeführt werden. Wenn das Programm bis zum Ende läuft auf diese Weise, dann wird das Problem des Ausgangs des Verfahrens der Handhabung.

Ich vermute, dass das Problem könnte der Faden sein, dass der Prozess startet wird BEENDET oder was auch immer nach dem Antrag ist vorbei. Versuchen Sie, ein einzelner Thread im applicaton mit, dass Sie sicher sind, ist am Leben immer gehalten, Sie können damit für die Prozesse beginnend von Anrufen, um es von anderen Threads zu machen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top