Timing-Problem (?) Linux versus Windows

Status
Nicht offen für weitere Antworten.

rueh

Mitglied
Hallo zusammen

Ich habe einen Code geschrieben, der mir eine PDF-Datei herunterlädt und diese anschliessend mit dem Acrobat Reader des Sytems öffnet.
Den Acrobat Reader starte ich als Process p (global definiert). Dadurch habe ich die Möglichkeit, auf den Prozess zu warten, ihn zu zerstören oder seinen exit-status abzurufen.

Der unten beschriebene Code wird ausgeführt, wenn ich in einer GUI den entsprechenden Button klicke. Der Code darin wird in einem eigenen Thread ausgeführt.

Der Ablauf des Codes ist direkt darin als kommentar beschrieben, die Problemstellung darunter:


Code:
      (new Thread() {
      public void run() {

        // das PDF wurde erfolgreich heruntergeladen
        if (befundAufbereiten() == true) {
          hideWaiting();
          setUnlockForBefund(false); // sperre die graphische Oberfläche (buttons, textfelder usw.)
                    
          try {
            
            if (p != null) {
              p.destroy(); // zerstört allfällige prozesse, die vorhin geöffnet waren
            }            
            
           // je nach betriebssystem wird der acrobat reader anders aufgerufen 
           // damit wäre das PDF geöffnet
            if (os.toLowerCase().indexOf("windows") != -1) {
              p = Runtime.getRuntime().exec(new String[]{ "rundll32", "url.dll,FileProtocolHandler", tmpFile });
            }
            if (os.toLowerCase().indexOf("linux") != -1) {
              p = Runtime.getRuntime().exec("/usr/bin/acroread "+tmpFile);
            }             

            // warte solange, bis der prozess beendet wird
            p.waitFor();
                                   
            int exit = p.exitValue(); // hole den exit status
            
            if (exit == 0) { // beendung erfolgreich
              setUnlockForBefund(true);  // entsperre die graphischeh oberfläche
              deleteBefuende(); // lösche alle pdf-dateien im temporären dowload-ordner
            }
                        
          } catch (Exception e) {
            e.printStackTrace();
          }        
        } else {
          showWarning(getString("Hinweis"), getString("wysiwygFailed").replace("XXXXXX", String.valueOf(auftragNr)));
        }       
      }
    }).start();
    showWaiting(getString("oneMoment"));

Lasse ich diesen Code auf einer Linux-Maschine laufen, läuft es perfekt. Die Applikation wird zur Laufzeit von Acrobat Reader gesperrt, sodass ich nichts am Befund ändern kann, bis Acrobat wieder geschlossen ist. Auch das Löschen der temporären PDF-Dateien funktioniert einwandfrei.
Sprich Linux wartet tatsächlich auf die Methode p.waitFor() bzw p.exitValue();, bis es den weiteren Code ausführt.

Nun zum eigentlichen Problem:
Auf Windows, worauf die Applikation primär laufen muss, wird überhaupt gar nicht gewartet auf das Ende des Acrobat Prozesses. Der Code nach der p.waitFor()-Methode wird schon ausgeführt während das PDF-File noch im Acrobat Reader geöffnet ist.
Das heisst, die graphische Oberfläche wird für ein paar Millisekunden gesperrt und dann gleich wieder entsperrt. Die Methode
deleteBefuende(); wird auch gleich ausgeführt und löscht die erst geladene PDF-Datei auch gleich mit und kann somit von Acrobat Reader schon gar nicht mehr geöffnet werden. D.h. Acrobat Reader wird zwar geöffnet, aber mit einer Fehlermeldung, dass die Datei nicht vorhanden sei.

Da der Code unter Linux perfekt funktioniert, gehe ich kaum davon aus, dass der falsch ausformuliert wurde. Das Problem hat viel eher mit dem Betriebssystem zu tun, unter dem die Applikation läuft.

Warum verhält sich Windows so und nicht wie dem Code entsprechend zu erwarten ist? Habe ich irgendwas nicht beachtet ?

Ich konnte dieses Problem einzig mit einem gut durchdachten sleep (auf die zu erwartende Zeit, die man benötigt um das Dokument zu betrachten) ein bisschen umgehen. Aber sleep's einbauen ist wohl unterste Schublade in der Programmierung, sofern es nicht wirklich vernünftige Gründe für diese Überlegung gibt. Hier sind die Gründe jedoch nur notgedrungen.

Ich bin dankbar um jeden Hinweis.


P.S. Es ist echt tragisch, wie oft der Code einwandfrei unter Linux ausgeführt werden kann, während es unter Windows überhaupt nicht funktioniert...Ich habe manchmal echt das Gefühl, dass es bei Windows auf Parameter wie die Wetterlage und Windrichtung ankommt, ob etwas läuft oder nicht.. [ironie off]
 

Ebenius

Top Contributor
Hol Dir mal von dem Prozess die PID. Und dann vergleich die mit der PID des Acrobat Readers, wenn der offen ist. Ich nehme einfach an, der Reader startet über einen Launcher, der dann die Anwendung aufruft (fork) und sich selbst beendet. Dann kehrt Dein waitFor() zurück.

Richtig?
 

rueh

Mitglied
Die Java-Applikation bzw Acrobat Reader laufen unter verschiedenen PIDs, jedoch läuft Acrobat Reader als Kindprozess vom Java-Prozess. Zumindest unter Linux.
Unter Windows laufen beide Prozesse unter separaten PIDs, nur kann ich hier nicht feststellen, ob diese PIDs voneinander abhängig sind.

Weiss nicht so recht, was ich daraus folgern kann.


ch nehme einfach an, der Reader startet über einen Launcher, der dann die Anwendung aufruft (fork) und sich selbst beendet. Dann kehrt Dein waitFor() zurück.

Öhm, das kann ich jetzt nicht so direkt bestätigen, da ich den Code hinter der Process-Geschichte nicht kenne, bzw verstehe ich nicht ganz, was du mit einem Launcher meinst. Ich denke aber, dass es schon so läuft, wie du meinst.
 

HoaX

Top Contributor
Die Prozesshirarchie ist egal. Das Problem wird sein, dass das Programm, das du unter Windows startest wohl selbst nur wiederum einen weiteren Prozess (den eigentlichen Reader) startet und sich dann beendet wärend dieser weitere Prozess weiter läuft. Darum macht dien Programm auch weiter, denn das gestartete Programm läuft nichtmehr.

Prüfe welche PID dir Java für den gestarteten Prozess liefert und vergleiche diese mit der PID aus dem Taskmanager für den Reader.
 

rueh

Mitglied
Die PIDs habe ich unter Windows schon überprüft. Einerseits habe ich die Java-PID der VirtualMachine, andererseits eine neue PID für den Reader.

Also nachdem ich das PDF geöffnet habe, läuft das JavaProgramm natürlich weiter parallel zum Reader.
Soweit ich deine Aussage verstehe, geht es darum, dass das JavaProgramm die Kontrolle über den Reader-Prozess verliert, sobald dieser gestartet ist. Anders ausgedrückt, sobald der Reader gestartet ist, ist er aus Sicht des JavaProgramms auch gleich wieder beendet, da er "abgekoppelt" wurde. Habe ich das korrekt verstanden?

Ich frage mich dennoch, warum? Ich nehme an, von der Prozess-Verwaltungs-Technik werden sich Windows und Linux nur in unwichtigen Punkten unterscheiden, denn Prozess-Verwaltung ist etwas, das gewisse Voraussetzungen erfüllen muss, um Interoperabilität zu gewährleisten.

Und wie könnte ich für Windows dieses Problem umgehen?

Ich habe versucht, die 'Aufräumarbeiten' ausserhalb des Threads zu platzieren. Also die Methoden zum Sperren der GUI bzw. zum Löschen der temporären Dateien.
Die Eigenschaft eines Threads ist es ja, dass Code ausserhalb dieses Threads erst ausgeführt wird, sobald der Thread beendet bzw. der Code innerhalb des Thread ausgeführt wurde.
Leider trifft dies nicht zu.. Selbst wenn ich die Aufräumarbeiten ausserhalb des Threads platziere, werden diese ausgeführt, bevor ich den Reader schliesse. Windows scheint sich einen Dreck darum zu kümmern..
 

HoaX

Top Contributor
naja, so ganz verstanden zu haben scheinst dus nicht, aber im groben und ganzen kann man das so stehn lassen.

das ist kein unterschied von windows und linux, sondern ein unterschied im adobe reader. abhilfe gibts da keine, außer der reader bietet das als aufrufoption an.
 

Ebenius

Top Contributor
Das mit dem Warten auf den Prozess ist ohnehin nicht so sehr geschickt. Der selbe Acrobat Reader Prozess kann ja mehrere Dokumente anzeigen.

Probier doch mal einen anderen Ansatz: Du könntest, nachdem der waitFor()-Aufruf zurückgekehrt ist, ein paar Sekunden warten und dann einen FileChannel auf die Datei aufmachen und lock() aufrufen. Wenn Du den Lock bekommst müsste der Acroread das Dokument wieder geschlossen haben. Ich hab das nicht probiert, aber vielleicht funktioniert's ja. Würde mich selber interessieren.
 
G

Gast2

Gast
Moin,

Du behandelst Windows anders als Linux

Code:
p = Runtime.getRuntime().exec(new String[]{ "rundll32", "url.dll,FileProtocolHandler", tmpFile });
Du rufst hier eine Funktion einer DLL auf ... diese Funktion wird als Process ausgeführt und startet den Reader ... dann wird der Process beendet ... und damit sollte klar sein wieso die GUI unter Windows nicht blockiert ... das kannst Du überprüfen indem Du den Befehl in der Console unter Windows ausführts ... die kommt sofort zurück und der Reader läuft

rueh hat gesagt.:
Und wie könnte ich für Windows dieses Problem umgehen?
in dem Du in beiden Betriebssystemen den Reader öffnest und nicht nur unter Linux ... Du wirst aber eigentlich ein Problem mit dem Pfad für den Reader haben, der steht in der Registry

hand, mogel
 

Ariol

Top Contributor
So kann man auch warten, evtl funzt das unter Windows.
Ich hab nur Linux hier...

Code:
import java.awt.Desktop;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;


public class WaitOpen
{
	public static void main(String[] args) 
	{
		Thread pdfThread = new Thread()
		{
			@Override
			public void run()
			{
				try
				{
					Process p = Runtime.getRuntime().exec("/usr/bin/acroread Pc.pdf"); 
					BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
					
					while(br.readLine()!=null){} //Auf Anwendung warten
					
					System.out.println("Anwendung zu");
				}
				catch (IOException e) {
					e.printStackTrace();
				}
			}
		};
		
		pdfThread.start();
		System.out.println("Thread gestartet");
		
	}
}
 

Ebenius

Top Contributor
Das hilft allerdings bei dem Problem nicht.

Dazu möchte ich jedoch noch eines Anmerken: Am besten zwei extra Threads starten; einen für p.getInputStream() und einen für p.getErrorStream(). Und dann p.waitFor()... So wird's normaler Weise empfohlen.

Wie gesagt: Das hat mit dem Problem hier aber nix zu tun. Process.waitFor() funktioniert. Auch unter Windows. Das Problem ist, dass der gestartete Prozess sich beendet, nachdem er einen neuen Prozess gestartet hat, der das Dokument öffnet.

Ebenius
 

eliot

Bekanntes Mitglied
Hallo,

ich würde einfach ein Desktopn.getDesktop.open(File file) ausführen
und in dem java Programm warten, bis du einen lock auf die entsprechende Datei ausführen
kannst, denn dann sollte der PDF Viewer geschlossen sein.

regards
eliot
 

HoaX

Top Contributor
außerdem würde ich unter linux nicht "acroread" aufrufen sondern "see", is quasi das equivalent zu deinem windows-aufruf. hat ja nicht jeder den adobe reader installiert ....
 

Ebenius

Top Contributor
"see" sagt mir mal nix. Mein Linux (SuSE 10.3) kennt's nicht, meine Paketmanager-Quellen auch nicht. Verrat's mir!

Soweit ich weiß, gibt es im Linux im Allgemeinen sowas gar nicht. Es gibt in verschiedenen Desktop-Environments derartige Tools; in KDE (zumindest 3.5) gibt's kfmclient/kfmexec dafür.

Wie dem auch sei: Sofern Du Java 6 nutzt, einfach Desktop.open(File) nutzen, die Datei locken und wenn Du den Lock bekommst, ist die Datei wieder geschlossen.

Ebenius
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
krgewb Problem mit Umlauten und Eszett bei InputStream Allgemeine Java-Themen 3
Max246Sch Backtracking Problem Box Filler Allgemeine Java-Themen 6
NightVision402 VisualVM Startskript Problem Allgemeine Java-Themen 3
javaBoon86 Email Server Connection Problem Allgemeine Java-Themen 1
F Problem mit PDFBOX Library Allgemeine Java-Themen 1
A Java modul Problem Allgemeine Java-Themen 4
D Read JSON File Problem Allgemeine Java-Themen 9
urmelausdemeis Exception in thread "main" java.lang.Error: Unresolved compilation problem: Allgemeine Java-Themen 7
J Problem mit JasperReports Allgemeine Java-Themen 8
M log4j Problem mit jlink Allgemeine Java-Themen 19
8u3631984 Problem beim Mocken von Record Klassen Allgemeine Java-Themen 4
torresbig Website login Problem - Jsoup, wie bisher, klappt nicht! Allgemeine Java-Themen 31
P Selenium . getText Problem Allgemeine Java-Themen 9
A Jar zu Exe Problem Allgemeine Java-Themen 13
sserio Variablen Liste erstellt und ein Problem mit dem Index Allgemeine Java-Themen 6
S Folgendes Problem bei einem Programm Allgemeine Java-Themen 1
stormyark Problem beim Klassen erstellen Allgemeine Java-Themen 1
A Thread.sleep Problem Allgemeine Java-Themen 2
A Problem bei der Nachbarschafttest Allgemeine Java-Themen 11
Splayfer Problem: no main manifest attribute Allgemeine Java-Themen 3
G javamail Problem beim Empfangen von Nachrichten Allgemeine Java-Themen 3
Splayfer JDA Problem mit MessageCounter Allgemeine Java-Themen 0
Splayfer Problem mit BufferedWriter Allgemeine Java-Themen 3
F Streams als Alternative für dieses Problem ? Allgemeine Java-Themen 15
N Maven Problem mit Datenbanktreiber (H2 Embedded) Allgemeine Java-Themen 12
T Problem beim Umwandeln in eine Jar-Datei Allgemeine Java-Themen 3
B Einfach Elemente zweier Arraylisten kreuz und quer vergleichen, min und max Problem? Allgemeine Java-Themen 16
C ArrayList Problem Allgemeine Java-Themen 3
kev34 nim-Spiel problem Allgemeine Java-Themen 1
D Firebase retrieve data Problem, Child Element wird nicht angesprochen Allgemeine Java-Themen 0
G Welches Problem besteht bei den Typparametern? Allgemeine Java-Themen 5
temi Problem mit Aufrufreihenfolge bei Vererbung Allgemeine Java-Themen 3
Sumo_ow "ArrayIndexOutofBoundsException: 2" Array Problem Allgemeine Java-Themen 6
T PIM basierend auf netbeans via AnyDesk Problem Allgemeine Java-Themen 3
xGh0st2014 Problem mit Java Array Allgemeine Java-Themen 1
Kirby.exe Verständnis Problem bei Rucksack Problem Allgemeine Java-Themen 6
B Eclipse-Lombok-Problem Allgemeine Java-Themen 19
I Input/Output ObjectOutputStream - Problem Allgemeine Java-Themen 7
1 Multiple Choice Knapsack- Problem Allgemeine Java-Themen 2
kodela Problem mit strukturiertem Array Allgemeine Java-Themen 18
E Problem mit Gridlayout und Button Allgemeine Java-Themen 2
A Array Problem Allgemeine Java-Themen 8
bueseb84 Problem Allgemeine Java-Themen 0
S Problem mit Arrays Allgemeine Java-Themen 1
D Nullpointer Exception Problem Allgemeine Java-Themen 5
B Problem mit meinen Klassen Allgemeine Java-Themen 6
A HashMap Methode "get()"-Problem Allgemeine Java-Themen 28
J Problem beim Umstellen auf Java jdk 13 Allgemeine Java-Themen 3
J Problem bei Install java 13 Allgemeine Java-Themen 3
X Profitable Reise Problem Allgemeine Java-Themen 32
A Problem beim öffnen von Java-Installern Allgemeine Java-Themen 1
Dann07 Problem mit JavaMail API Allgemeine Java-Themen 26
J Problem beim Generischen Klassen und Interfaces Allgemeine Java-Themen 2
L Klassen Algorithmus für das folgende Problem entwickeln? Allgemeine Java-Themen 30
J Clear-Problem Allgemeine Java-Themen 10
B Problem zu einem Java Projekt Allgemeine Java-Themen 6
S JFileChooser Problem Allgemeine Java-Themen 4
M Traveling Salesman - MST Heuristik Problem Allgemeine Java-Themen 4
J Traveling Salesman Problem Allgemeine Java-Themen 14
E Java Editor Problem mit 2er Exceptions Allgemeine Java-Themen 12
C code oder Bibliotheken für 2-Center Problem Allgemeine Java-Themen 4
M Salesman Problem - Bruteforce Algorithmus Allgemeine Java-Themen 23
S Methoden Problem mit NullPointerException Allgemeine Java-Themen 9
Javafan02 Problem mit if-clause Allgemeine Java-Themen 17
J Lombok Problem mit Konstruktoren bei Verberbung Allgemeine Java-Themen 1
kodela Event Handling Problem mit der Alt-Taste Allgemeine Java-Themen 16
W Threads Problem Allgemeine Java-Themen 15
D (Verständnis-)Problem mit Unterklasse Allgemeine Java-Themen 4
S Problem mit Generic bei unmodifiableCollection Allgemeine Java-Themen 4
S jserialcomm Problem Allgemeine Java-Themen 1
Flynn Thread-Problem... Allgemeine Java-Themen 2
J Generische Interface - Problem Allgemeine Java-Themen 3
G Problem beim GUI Allgemeine Java-Themen 9
L Applet Problem "security: Trusted libraries list file not found" ? Allgemeine Java-Themen 7
A OOP Problem beim Berechnen der größten Fläche eines Ringes Allgemeine Java-Themen 19
T Problem mit externen Datenbankzugriff über SSH Tunnel Allgemeine Java-Themen 4
F Problem beim Einlesen einer Textdatei Allgemeine Java-Themen 12
S Java OpenOffice Problem mit Windows-Benutzerwechsel Allgemeine Java-Themen 19
K Threads RAM Problem Allgemeine Java-Themen 20
P Operatoren Problem mit Zähler in recursiver Schleife Allgemeine Java-Themen 2
C Int Problem Allgemeine Java-Themen 8
C J2V8 NodeJs Java Bride Problem und Frage!?!? Allgemeine Java-Themen 1
J Problem bei Hashmap Key-Abfrage Allgemeine Java-Themen 4
C Webseiten Programm problem Allgemeine Java-Themen 5
M LocalDate Problem Allgemeine Java-Themen 4
J "Problem Objektorientierung" Allgemeine Java-Themen 20
geekex Problem Meldung! Was tun?! Allgemeine Java-Themen 19
T Klassen Override Problem Allgemeine Java-Themen 7
L Unbekanntes Problem Allgemeine Java-Themen 1
FrittenFritze Problem mit einer JComboBox, Event temporär deaktivieren Allgemeine Java-Themen 11
Blender3D Java Swing Programm Windows 10 Autostart Problem Allgemeine Java-Themen 2
F HTTPS Zertifikat Problem Allgemeine Java-Themen 3
M OpenCV KNearest Problem Allgemeine Java-Themen 0
Tommy Nightmare Project Euler: Problem 22 Allgemeine Java-Themen 2
C Abstrakte Klasse, lokale Variable-Problem Allgemeine Java-Themen 1
N Vererbung Design-Problem mit vorhandenen, von der Klasse unabhängigen Methoden Allgemeine Java-Themen 12
P Eclipse Projekt anlegen macht Problem Allgemeine Java-Themen 1
RalleYTN META-INF/services Problem Allgemeine Java-Themen 3
F Java Mail Problem: Authentifizierung wird nicht immer mitgeschickt Allgemeine Java-Themen 1
I Problem beim Aufrufen, von Objektmethoden/ -variablen Allgemeine Java-Themen 6

Ähnliche Java Themen

Neue Themen


Oben