pr0nst1r
13-04-2007, 20:40
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:
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(expectedFileHandleSuccess Output))
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:
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 - www.sysinternals.com
No matching handles found.
no other processes accesses file!
Greift irgendein Prozess auf die Datei zu sieht die Ausgabe so aus:
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 - www.sysinternals.com
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:
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(expectedFileHandleSuccess Output)) {
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:
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:
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....
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:
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(expectedFileHandleSuccess Output))
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:
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 - www.sysinternals.com
No matching handles found.
no other processes accesses file!
Greift irgendein Prozess auf die Datei zu sieht die Ausgabe so aus:
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 - www.sysinternals.com
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:
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(expectedFileHandleSuccess Output)) {
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:
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:
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....