Problem: Ein Process aus Servlet starten - bleibt hängen

Andron

Erfahrenes Mitglied
Hallo,
ich versuche mein Problem datailierter zu beschreiben.

Nach einem Klick auf ein Link im Browser wird ein Servlet aufgerufen. Dieser ruft folgende Methode auf:

Code:
public String startProcess() 
{
File scripFile = new File(dir + "startbeangen.bat");
ProcessBuilder processBuilder = new ProcessBuilder("cmd", "/c",
scripFile.getAbsolutePath(), propdatei, archivname, dir,">test.txt");
processBuilder.directory(scripFile.getParentFile());
try {
System.out.println("[BeanGeneratorThread] startProcess - starte Process in "+ dir);
Process process = processBuilder.start();
System.err.println( "--------->"+process.toString());
System.out.println("[BeanGeneratorThread] startProcess - Process wurde gestartet");
// System.out.println(process.waitFor());
} catch (IOException e) {e.printStackTrace();}
System.out.println("[BeanGeneratorThread] startProcess return: "+dir+archivname);
return dir+archivname;
}

Die Methode startet ein batch-File mit einigen Parametern.

Code:
set jahr=%date:~-4%
set monat=%date:~-7,2%
set tag=%date:~-10,2%
set propdatei=%1
set archivname=%2
set generatorpath=%3
echo 1
set f=log_%jahr%%monat%%tag%
echo 2
mkdir %f%
echo 3
java -jar beangen.jar %propdatei% %generatorpath%> %f%/beangen.txt
echo 4
java -jar compiler.jar src test testsuite > %f%/compiler.txt
echo 5
java -cp ./bin;./test/lib/junit.jar;./test/bin;./testsuite/bin junit.textui.TestRunner com.is_teledata.AllBeanTest > %f%/tests.txt
echo 6
java -jar zipper.jar %archivname% %generatorpath% > %f%/zipper.txt
echo 7

Das ganze läuft aber nur bis Zeile:
java -jar beangen.jar %propdatei% %generatorpath%> %f%/beangen.txt

Dann passiert nichts. Servlet arbeitet den Request ab und schickt die Seite an den Client, aber der Prozess läuft nicht.

Nun, ich weiß, ihr werdet jetzt sagen, ich soll in der Datei beangen.jar nach dem Problem suchen, habe ich schon. Daran liegt es nicht. Denn, wenn ich den Tomcat abschiesse, läuft der Prozess, wie gewünscht, zu Ende.

Vielleicht hat jemand eine Idee?


EDIT: habe eben noch festgestellt, dass das doch zu ende läuft, aber nach ca. 5-10 Minuten.
Beim manuellen Start über die Konsole dauert das ca. 3 Sekunden.
 
Zuletzt bearbeitet:
habe hier noch rumprobiert und mein Aufruf vereinfacht.
Jetzt möchte ich nur ein jar-File aus dem Servlet starten:

Code:
private void startGenerateSource(File logpath) throws IOException
{
StringBuffer buffer=new StringBuffer();
buffer.append("java ");
buffer.append("-jar ");
buffer.append("beangen.jar ");
buffer.append(propdatei+" ");
buffer.append(dir+" ");
String command = "cmd";
String commandpath= "/c";	
System.out.println("[BeanGeneratorThread] startGenerateSource - Kommando: "+buffer.toString());
ProcessBuilder processBuilder = new ProcessBuilder(command, commandpath,buffer.toString());	
processBuilder.directory(new File(dir));
Process process = processBuilder.start();
}

Daraus wird ein Kommando erzeugt:
Code:
java -jar beangen.jar bean.properties c:/tools/generator/
Die Zeile sollte dem Aufruf über die Konsole ähneln.
Kein Erfolg. Der Prozess läuft zwar (im Taskmanager), passieren tut aber nichts. Erst, wenn ich den Tomcat abschiesse, läuft der Prozess zu ende.

Kann sein, dass man keine jar's aus dem laufenden Tomcat ausführen kann?
 
Hallo,

mach mal explizit die input / output Streams des Prozesses zu / bzw. flushe sie entsprechend.

Gruß Tom


Da bleibt er hängen. Es wird nichts ausgegeben. Der Tomcat läuft weiter und der Process scheinbar auch, nur es tut sich nichts. Aber sobald ich den Tomcat beende mit Strg+c wird der Process dann auch erfolgreich abgearbeitet.
 
Eigentlich hole ich mir keine input / output Streams.
Habe mal versucht zu schauen, was da passiert und das getInputStream auszugeben, da bleibt er hängen, sprich es passiert nichts. Dann habe ich die Zeilen auskommentiert und es läuft trotzdem nicht.

Code:
	private void startGenerateSource(File logpath) throws IOException
	{
		//java -jar beangen.jar %propdatei% %generatorpath%> %f%/beangen.txt
		
		StringBuffer buffer=new StringBuffer();
		buffer.append("java ");
		buffer.append("-jar ");
		buffer.append("beangen.jar ");
		buffer.append(propdatei+" ");
		buffer.append(dir+" ");
		//buffer.append(logpath+"/"+"beangen.txt");
		String command = "cmd";
		String commandpath= "/c";
		
		System.out.println("[BeanGeneratorThread] startGenerateSource - Kommando: "+buffer.toString());
		
		ProcessBuilder processBuilder = new ProcessBuilder(command, commandpath, buffer.toString());
		
		processBuilder.directory(new File(dir));
		Process process = processBuilder.start();
		
	
		

		/*
		BufferedReader in = new BufferedReader(
			      new InputStreamReader(process.getInputStream()) );
		for ( String s; (s = in.readLine()) != null; )
		{	
			System.out.println(s+"\n");
		}
		*/
	}
 
Hallo,

mach mal explizit die input / output Streams des Prozesses zu / bzw. flushe sie entsprechend.

Gruß Tom

DANKE DANKE DANKE

Es hat geholfen.

Code:
			process.getOutputStream().close();
			process.getErrorStream().close();
			process.getInputStream().close();

Und es läuft :).

Nur WARUM?
Wenn ich keine Streams des Prozesses benutze, warum soll ich die schliessen?


EDIT: Es reicht auch nur das Error-Stream zu schliessen.

Die Frage bleibt aber noch offen: WARUM?
 
Zuletzt bearbeitet:
Zurück