process.getInputStream() hängt auf merkwürdige Art und Weise

Status
Nicht offen für weitere Antworten.

jollyroger

Bekanntes Mitglied
Hallo zusammen,

ich habe ein völlig merkwürdiges Problem bei dem ich nach einem Tag rumprobieren überhaupt nicht mehr weiterkomme...

Folgendes:

- ich verwende das Microsoft-Tool "handle" (eine simple exe) um aus einer java-Applikation heraus zu prüfen
ob irgendein Prozess auf eine Datei zugreift.

Eine einfache Testklasse funktioniert auch bestens:

Code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;


public class TestIt {

	public static void main(String[] args){

		String pathToFileHandleTool = "C:\\tmp\\Handle\\handle.exe";
		String pathToFile = "C:\\tmp\\openSUSE-10.2-GM-i386-CD3.iso";
		String expectedFileHandleSuccessOutput = "(.*)No matching handles found(.*)";
		System.out.println("pathToFileHandleTool:" + pathToFileHandleTool);
		System.out.println("pathToFile: " + pathToFile);
		System.out.println("expectedFileHandleSuccessOutput: " + expectedFileHandleSuccessOutput);
		
		ProcessBuilder builder = null;
		// check for os
		if(System.getProperty("os.name").matches("(.*)Windows(.*)")) {
			System.out.println("we are on windows..");
		} else {
			System.out.println("we are on linux..");
		}
		builder = new ProcessBuilder( pathToFileHandleTool, pathToFile);
		Process process = null;
		String commandOutput = "";
		String line = null;
		BufferedReader bufferedReader = null;
		try {
			process = builder.start();
			// read command output
			bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
			if(!bufferedReader.ready()) {
				System.out.println("bufferedReader not ready!");
			}
	    	System.out.println("bin vor readline!");
	    	while((line = bufferedReader.readLine()) != null) {
	    		commandOutput += line;
  		        System.out.println("reading in line....");
	    	}
	    	System.out.println("bin nach readline!");
	    	System.out.println("commandoutput: " + commandOutput);
			// wait till process has finished
			process.waitFor();
		} catch (IOException e) {
			System.out.println(e.getMessage());
			e.printStackTrace();
		}  catch (InterruptedException e) {
			System.out.println(e.getMessage());
			e.printStackTrace();		}
		// check output to assure that no process uses file
		if(commandOutput.matches(expectedFileHandleSuccessOutput))
			System.out.println("no other processes accesses file!");
		else
			System.out.println("one or more other processes access file!");
	}
}

(Wundert euch nicht wegen sinnlos aussehenden Ausgaben wie "bin vor readline!" usw., Begründung kommt
später)

Rufe ich diese Klasse auf und niemand greift auf die Datei "C:\\tmp\\openSUSE-10.2-GM-i386-CD3.iso" zu
sieht die Ausgabe des Programms so aus:


Code:
pathToFileHandleTool:C:\tmp\Handle\handle.exe
pathToFile: C:\tmp\openSUSE-10.2-GM-i386-CD3.iso
expectedFileHandleSuccessOutput: (.*)No matching handles found(.*)
we are on windows..
bufferedReader not ready!
bin vor readline!
reading in line....
reading in line....
reading in line....
reading in line....
reading in line....
reading in line....
bin nach readline!
commandoutput: Handle v3.2Copyright (C) 1997-2006 Mark RussinovichSysinternals - [url]www.sysinternals.com[/url]
No matching handles found.
no other processes accesses file!

Greift irgendein Prozess auf die Datei zu sieht die Ausgabe so aus:

Code:
pathToFileHandleTool:C:\tmp\Handle\handle.exe
pathToFile: C:\tmp\openSUSE-10.2-GM-i386-CD3.iso
expectedFileHandleSuccessOutput: (.*)No matching handles found(.*)
we are on windows..
bufferedReader not ready!
bin vor readline!
reading in line....
reading in line....
reading in line....
reading in line....
reading in line....
reading in line....
bin nach readline!
commandoutput: Handle v3.2Copyright (C) 1997-2006 Mark RussinovichSysinternals - [url]www.sysinternals.com[/url]
WinSCP3.exe        pid: 1108    1AC: C:\tmp\openSUSE-10.2-GM-i386-CD3.iso.filepart
one or more other processes access file!

Also alles ok soweit, das Programm tut was es soll....

Verwende ich aber nun __exakt__ denselben Code in meiner (Servlet-) Applikation funktioniert er nicht mehr:

Code:
	private boolean isWritten(File file) {	
		
		String pathToFileHandleTool = "C:\\tmp\\Handle\\handle.exe";
		String pathToFile = "C:\\tmp\\openSUSE-10.2-GM-i386-CD3.iso";
		String expectedFileHandleSuccessOutput = "(.*)No matching handles found(.*)";
		logger.debug("pathToFileHandleTool: " + pathToFileHandleTool);
		logger.debug("pathToFile: " + pathToFile);
		logger.debug("expectedFileHandleSuccessOutput: " + expectedFileHandleSuccessOutput);
				
		ProcessBuilder builder = null;
		// check for os
		if(System.getProperty("os.name").matches("(.*)Windows(.*)")) {
			logger.debug("we are on windows..");
		} else {
			logger.debug("we are on linux..");
		}  
		builder = new ProcessBuilder( pathToFileHandleTool, pathToFile);
		Process process = null;
		String commandOutput = "";
		String line = null;
		BufferedReader bufferedReader = null;
		try {
			process = builder.start();
			// read command output
			bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
			if(!bufferedReader.ready()) {
				logger.debug("bufferedReader not ready!");
			}
			logger.debug("bin vor readline!");
	    		while((line = bufferedReader.readLine()) != null) {
				commandOutput += line;
				logger.debug("reading in line....");
	    		}
			logger.debug("bin nach readline!");
			logger.debug("commandoutput: " + commandOutput);
			// wait till process has finished
			process.waitFor();
		} catch (IOException e) {
			logger.debug(e.getMessage());
			logger.debug(e);
		}  catch (InterruptedException e) {
			logger.debug(e.getMessage());
			logger.debug(e);
		}
		// check output to assure that no process uses file
		if(commandOutput.matches(expectedFileHandleSuccessOutput)) {
			logger.debug("no other processes accesses file!");
			return true;
		}
		else {
			logger.debug("one or more other processes access file!");
			return false;
		}	
	}

Nun sieht die Ausgabe so aus:

Code:
 pathToFileHandleTool: C:\tmp\Handle\handle.exe
 pathToFile: C:\tmp\openSUSE-10.2-GM-i386-CD3.iso
 expectedFileHandleSuccessOutput: (.*)No matching handles found(.*)
 we are on windows..
 bufferedReader not ready
 bin vor readline!

Sprich wie man sieht hängt es genau hier:

Code:
			logger.debug("bin vor readline!");
	    	while((line = bufferedReader.readLine()) != null) {
	    		commandOutput += line;
	    		logger.debug("reading in line....");
	    	}
	    	logger.debug("bin nach readline!");

Es passiert also einfach nichts mehr?!

WTF ist hier los?

Ich sehe keine relevanten Unterschiede zwischen dem Testprogramm und der Applikation, ich sehe nur
3 Punkte die anders sind:

1) Statt System.out.println wird logger.debug() verwendet -> unkritisch
2) Die Methode in der Applikation enthält am Ende return-Statements -> unkritisch, bis dahin kommt es ja gar nicht
3) Das Testprogramm starte ich direkt über "java TestIt" bzw. über Eclipse heraus, die Applikation
ist eine Servlet-Applikation die über den Tomcat läuft. Aber alles was ich gestart habe, habe ich
zu Testzwecken als Administrator gestartet, sprich sowohl Tomcat als auch das Programm in der
Kommandozeile.

Vielleicht sehe ich hier den Wald vor lauter Bäumen nicht mehr, aber es gibt IMHO keinen Unterschied...

Anmerkung (1): pathToFileHandleTool, pathToFile usw. hab ich in der Applikation natürlich nicht fest verdrahtet,
die Konfiguration läuft über spring. Sprich der ganze Kram ist hier nur zu debugging-Zwecken.Ebenso
wie die ganzen Ausgaben.

Anmerkung (2): Unter Linux mit "lsof" läuft sowohl die Applikation als auch das Testprogrammm

Ich hoffe wirklich jemand hat eine Idee, weil ich hab jetzt keine Ahnung mehr woran das liegen könnte....
 

NTB

Bekanntes Mitglied
geht er denn noch in die while Schleife rein?
sprich: Hängt er am .readline() oder am += vom String? (ich vermute mal ersteres, aber damit wäre das ganze noch einen Tick weiter eingegrenzt)

Vielleicht erkennt der .readLine() das Ende einer Zeile nicht? Hast Du mal eine kleine Datei ausprobiert und nicht gleich ein ganzes ISO?
 
G

Guest

Gast
Hi,

geht er denn noch in die while Schleife rein?
sprich: Hängt er am .readline() oder am += vom String? (ich vermute mal ersteres, aber damit wäre das ganze noch einen Tick weiter eingegrenzt)

Habs gerade nochmal eingegrenzt, er hängt am readline()...

Vielleicht erkennt der .readLine() das Ende einer Zeile nicht? Hast Du mal eine kleine Datei ausprobiert und nicht gleich ein ganzes ISO?

readline() liest ja nicht das iso ein, sondern nur die Ausgabe des Programms handle.
Welche Datei ich also verwende spielt keine Rolle.

Aber ich habs trotzdem mit allen möglichen Dateien probiert (auch kleine textfiles usw.......:)

Weitere Ideen? (**verzweifelt in die Runde schau**)
 

jollyroger

Bekanntes Mitglied
Arggh,

schon wieder nicht angemeldet gewesen.

Noch eine kurze Anmerkung zu "Handle":

Gibt man dem Tool irgendwas was nicht existiert, spielt das für handle keine Rolle.

Sprich ich könnte auch "foo" als Datei-Pfad angeben, "handle" würde mir dann einfach

Code:
No matching handles found.

ausgeben.

Der ProcessBuilder hingegen würde mir eine IOException schmeissen wenn der Pfad zum Programm nicht stimmen würde.

(Wollte es nur erwähnen damit Fehler dieser Art ausgeschlossen werden können.)
 

André Uhres

Top Contributor
Wenn der ErrorStream etwas enthält, dann könnte das die Ursache sein,
weswegen das Programm hängt. Versuch's mal so:
Code:
builder.redirectErrorStream(true);
dann wird beim Auslesen des InputStreams gleichzeitig auch der ErrorStream mit ausgelesen.
 
G

Guest

Gast
Hi,


Wenn der ErrorStream etwas enthält, dann könnte das die Ursache sein,
weswegen das Programm hängt. Versuch's mal so:
Code:

builder.redirectErrorStream(true);

dann wird beim Auslesen des InputStreams gleichzeitig auch der ErrorStream mit ausgelesen.


Ich hab nun

Code:

builder.redirectErrorStream(true);

hinzugefügt.

Ergebis: Gar keines, sprich ich krieg immer noch keine Fehlerausgabe.

Ich hab jetzt noch folgende Sachen hinzugefügt, die ich neu probiert habe / vergessen zu erwähnen:


-> logs

Auch die Tomcat-Logs bringen keine Error / Exception, die Ausgabe ist identisch zu dem was ich in meinen separaten logfiles mitlogge.

-> die Rechte auf "handle.exe" sehen so aus, das "jeder" "Vollzugriff" hat.

-> Um Betriebssystem-Fehler auszuschließen, hab ich es noch auf einer anderen Windows 2000 Maschine getestet. Ergebnis: Das Gleiche.

-> Um zu testen, ob es daran liegt, das ich aus dem Tomcat heraus keine Applikationen aufrufen, hab ich mit dem identischen Code mal "nslookup www.google" aufgerufen, klappt aus der Applikation heraus einwandfrei.
"Handle" greift aber auch nur lesend auf das System zu.

Noch mal kurz zusammengefaßt:

-> Handle in einer separaten Testklasse unter Windows -> funktioniert
-> Handle in die Applikation eingebaut unter Windows -> funktioniert nicht
-> identischer Code in die Applikation eingebaut unter linux ("handle" durch "lsof" ersetzt) funktioniert.

Tja, nun hab ich keine Idee mehr.

Bin für jeden noch so absurden Tipp zu haben.....
 

jollyroger

Bekanntes Mitglied
Hmm,

"automatisch anmelden" klappt irgendwie nicht so richtig.

Kurzer Nachtrag noch:

Ich dachte mir, das evtl. der security manager des Tomcats da noch irgendwie rumpfuscht, das tomcat-manual sagt aber dazu:

Once you have configured the catalina.policy file for use with a SecurityManager, Tomcat can be started with a SecurityManager in place by using the "-security" option

Ich starte ihn ohne diese Option, daran sollte es nicht liegen.
catalina.policy hab ich auch nicht angerührt.
Und wie schon erwähnt: andere Programme kann ich ausführen..........

Es muss doch irgendeinen Weg geben zumindest mal eine Fehlermeldung ausgeben zu lassen?
 

jollyroger

Bekanntes Mitglied
Hallo,

nochmal ein Update:

auch mit read() funktioniert es nicht:

Code:
			logger.debug("bin vor read()-Aufruf!");
			int iChar = 0; 
			
	    	while((iChar = bufferedReader.read()) != -1) {
	    		logger.debug("before reading in char....");
	    		commandOutput += iChar;
	    		logger.debug("after reading in char....");
	    	}

Das Resultat ist das gleiche:

Code:
bin vor read()-Aufruf

und dann hängt das Ganze wieder.......

Was ich jetzt noch alles probiert (das nachstehende mag sinnlos erscheinen, aber wenn man so einen Hänger kriegt und keine Ausgabe probiert man halt jeden noch so bescheuerten Schritt durch):

-> den BufferedReader durch einen InputStreamReader ersetzt:

Code:
InputStreamReader iStreamReader = new InputStreamReader(p.getInputStream());
			int iChar = 0; 
			//bufferedReader.f
	    	while((iChar = iStreamReader.read()) != -1) {
	    		logger.debug("before reading in char....");
	    		commandOutput += iChar;
	    		logger.debug("after reading in char....");
	    	}

Gleiches Ergebnis, sprich keines.

-> statt dem ProcessBuilder Runtime.exec genommen:


Code:
runtime = Runtime.getRuntime();
	Process p = runtime.exec("C:\\tmp\\Handle\\handle C:\\tmp\\openSUSE-10.2-GM-i386-CD3.iso");


Gleiches Ergebnis, sprich keines.

-> handle in den pfad aufgenommen

Ergebnis:

Code:
IOException: CreateProcess:  error=2

Das soll laut google heissen:

Code:
A value of 2 at that point means "file not found". One of the files in the process is missing.

Tomcat scheint also Umgebungsvariablen zu ignorieren.

Habs dann noch so probiert:

Code:
builder = new ProcessBuilder( "cmd", "/c", pathToFileHandleTool, pathToFile);

und so:
Code:
Process process = runtime.exec( "cmd", "/c","C:\\tmp\\Handle\\han C:\\tmp\\openSUSE-10.2-GM-i386-CD3.iso");

Also nochmal zusammengefasst:

Rufe ich z.b. nslookup genau wie oben auf:

Code:
		ProcessBuilder builder = null;
		builder = new ProcessBuilder( "cmd", "/c", "nslookup", "www.google.de");
		builder.redirectErrorStream(true);
		Process process = null;
		String commandOutput = "";
		BufferedReader bufferedReader = null;

		try {
			logger.debug("builder-call: new ProcessBuilder( cmd, /c, pathToFileHandleTool, pathToFile)");

			process = builder.start();			
			logger.debug("called builder.start()");
			// read command output
			bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
			logger.debug("before read()-call...");
			int iChar = 0; 
	    	while((iChar = bufferedReader.read()) != -1) {
	    		logger.debug("before reading in char....");
	    		commandOutput += iChar;
	    		logger.debug("after reading in char....");
	    	}
	    	logger.debug("after read() call....");
	    	logger.debug("command-output: " + commandOutput);			
			// wait till process has finished
			process.waitFor();
		} catch (IOException e) {
			logger.debug(e.getMessage());
			logger.debug(e);
		}  catch (InterruptedException e) {
			logger.debug(e.getMessage());
			logger.debug(e);
		}

funktioniert!

Rufe ich nun handle direkt auf:

Code:
		ProcessBuilder builder = null;
		builder = new ProcessBuilder( "cmd", "/c", "C:\\tmp\\Handle\\handle.exe", "C:\\tmp\\foo");
		
		builder.redirectErrorStream(true);
		Process process = null;
		String commandOutput = "";
		BufferedReader bufferedReader = null;

		try {
			logger.debug("builder-call: new ProcessBuilder( cmd, /c, pathToFileHandleTool, pathToFile)");
			logger.debug("test mit handle!!!!!");
			process = builder.start();			
			logger.debug("called builder.start()");
			// read command output
			bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
			logger.debug("before read()-call...");
			int iChar = 0; 
	    	while((iChar = bufferedReader.read()) != -1) {
	    		logger.debug("before reading in char....");
	    		commandOutput += iChar;
	    		logger.debug("after reading in char....");
	    	}
	    	logger.debug("after read() call....");
	    	logger.debug("command-output: " + commandOutput);			
			// wait till process has finished
			process.waitFor();
		} catch (IOException e) {
			logger.debug(e.getMessage());
			logger.debug(e);
		}  catch (InterruptedException e) {
			logger.debug(e.getMessage());
			logger.debug(e);
		}

hängt!

Hab dann handle in das nslookup-Verzeichnis kopiert und probiert:

Code:
String pathToFileHandleTool = "C:\\WINNT\\system32\\handle.exe";

hängt ebenso..........

Sieht jemand wie das doch noch laufen könnte?
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
F Process.getInputStream unter Linux Allgemeine Java-Themen 7
G ungepufferter Process.getInputStream Allgemeine Java-Themen 10
M Process -> getInputStream -> nur gepuffert ? Allgemeine Java-Themen 12
D Compiler-Fehler child process exited with code 1 Allgemeine Java-Themen 1
K Threads Runtime und Process Probleme Allgemeine Java-Themen 3
P Herausfinden, ob ein Process ein Fenster hat Allgemeine Java-Themen 1
D Java Process OutputStream ist null Allgemeine Java-Themen 4
X Problem bei process.start() ExitValue Allgemeine Java-Themen 5
T Mit Java auf die Konsole eines Process-Objekts zugreifen Allgemeine Java-Themen 10
P Input/Output Process.getErrorStream = OutputStream Allgemeine Java-Themen 11
J Download: Filename + Process waitFor() Allgemeine Java-Themen 5
S Wie beendet man einen Process in Java Platform unabhänging? Allgemeine Java-Themen 8
M Process wird gestoppt und nach beenden der Anwendung fortgeführt Allgemeine Java-Themen 4
G Process.destory() == CTRL+C Allgemeine Java-Themen 2
P Swing GUI Process anzeigen Allgemeine Java-Themen 10
schlingel Process - Ausgabe leer Allgemeine Java-Themen 5
J Process beenden ...aber wie ? Allgemeine Java-Themen 19
G Process - mehrere Commands?! Allgemeine Java-Themen 2
MQue auf gestarteten Process warten Allgemeine Java-Themen 7
G Process.wait() auf Folgeprozesse mitwarten Allgemeine Java-Themen 29
P Bedeutung der Process.exitValue() Werte? Allgemeine Java-Themen 3
J Process auf Console anzeigen lassen. Allgemeine Java-Themen 5
S Process - Befehle senden Allgemeine Java-Themen 13
B Process Builder Allgemeine Java-Themen 10
D Thread & Process: Beenden einer Batch-Datei Allgemeine Java-Themen 8
D Fremdes Programm schließen (ohne process.destroy()) Allgemeine Java-Themen 8
S process.waitFor() endet mit -1 Allgemeine Java-Themen 3
A Runtime Process bricht nicht ab! Allgemeine Java-Themen 7
C Process output Allgemeine Java-Themen 7
A Eclipse hängt sich auf Allgemeine Java-Themen 7
Viper13125 Eclipse Hängt sich auf, wenn ich SimpelDateFormat drin lasse Allgemeine Java-Themen 2
Tiago1234 Warum hängt sich mein Programm auf? Allgemeine Java-Themen 22
N Quicksort Programm hängt sich auf Allgemeine Java-Themen 6
kodela Programm hängt in der Ereigniswarteschlange Allgemeine Java-Themen 13
S Programm hängt sich manchmal (selten) auf Allgemeine Java-Themen 9
T Minimax/Alphabeta Algorithmus hängt sich auf (?) Allgemeine Java-Themen 2
Z Eclipse hängt sich alle paar Sekunden auf (Keine Rückmeldung). Allgemeine Java-Themen 4
F JavaFX Gui hängt counter++ Allgemeine Java-Themen 0
L Prog läuft in der IDE, hängt sich aber am Mac auf Allgemeine Java-Themen 0
1 InputStream hängt Allgemeine Java-Themen 4
P Threads Programm hängt Allgemeine Java-Themen 9
Jats Programm mit CMD Befehl hängt sich auf oder gibt error = 5 aus Allgemeine Java-Themen 4
T Programm hängt sich auf Allgemeine Java-Themen 14
J Eclipse Eclipse hängt sich ständig auf Allgemeine Java-Themen 6
P J2EE EJB Einstieg - hängt schon am XDoclet + Eclipse Allgemeine Java-Themen 5
L Java Thread [blockingqueue] hängt sich auf Allgemeine Java-Themen 13
S Element aus ArrayListe löschen --> Thread hängt sich auf Allgemeine Java-Themen 2
lacyuu Schleife hängt sich auf, wieso?? Allgemeine Java-Themen 2
S Batchdatei mit pause hängt Allgemeine Java-Themen 8
J XML: JDOM + builder.build() hängt einfach Allgemeine Java-Themen 3
H Java Mail hängt sich unregelmässig auf Allgemeine Java-Themen 8
J Merkwürdiger Fehler: Applikation hängt einfach, Quartz-bug? Allgemeine Java-Themen 6
D runtime.exec --> Prozess hängt sich auf Allgemeine Java-Themen 7
D new File() -> Java hängt sich manchmal auf Allgemeine Java-Themen 14
G Prozess beenden, wenn er hängt Allgemeine Java-Themen 9
S Runtime.getRunTime().exec("jar cvf .) hängt sich auf Allgemeine Java-Themen 3
M BufferedReader input - hängt sich auf Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben