Unvorhersehbares Verhalten - benutze ich die falsche Bedingungsprüfung oder brauche ich Threads?

jan_B

Mitglied
Guten Morgen!

ich verzweifle an meinem Code und hoffe, dass hier einige erfahrene Programmierer mitlesen, die bei der Schilderung meines Problems ein Grinsen ins Gesicht bekommen und meinen Knoten im Kopf lösen ;)

Ich habe eine PHP-Webseite in Entwicklung, die in der Folge einer Userhandlung zunächst ein Word-Dokument, bestehend aus 119 Feldern, durch einen MySQL-Abruf befüllt.
Dieses docx wird anschließend zu einem PDF geformt und in einem gesonderten Userverzeichniss abgelegt, damit der User das fertige "Produkt" online sieht.

So weit so gut. Ich habe mich dazu entschieden Java zu nutzen, um das Word zu befüllen, das PDF zu erstellen, die Datenbankabrufe durchzuführen und die fertige PDF in den speziellen Ordner des Webservers zu platzieren.

Das ganze Procedere läuft derzeit so ab:
1
das PHP-Skript schreibt die AuftragsID und den Pfad des "verschlüsselten" Userverzeichnisses in eine txt-Datei. (der Pfad variiertmit jeder neuen auftragsID)
2
Auf einem Windowsrechner läuft in einer Endlosschleife eine Java, dass auf solch eine txt-Datei wartet und verarbeitet.
3
die txt wird in ein gesondertes Verzeichnis verschoben, am Dateinamen inkrementiert und dann ausgelesen.
4
Anhand der AuftragsID wird ein Datenbankabruf gestartet und die Werte für die 119 Felder ausgelesen und in einem Array bereitgehalten.
5
per WordprocessingML wird nun ein docx-Template mit den Werten befüllt und mit der AuftragsID im Dateinamen gespeichert.
Anschließend wird ein batch (ja, ein Batch) erstellt, dass MS-Word aufruft und ein Makro startet.
6
Als Ergebnis erhält man ein fertiges PDF.
7
Nun läuft eine while-Schleife, die so lange läuft, wie keine(!) pdf existiert.
8
Sobald eine pdf gefunden, wird diese in das mitgeteilte Verzeichnis aus 1 gespeichert.

Schlussworte & Bitte
Das Java läuft sauber durch. Aber es hakt immer wieder an der Stelle, worin das pdf erstellt und dieses verschoben werden soll (6-7)
Sprich: wenn ich alle Programmabschnitte per Hand, sequentiel, durchfühe macht jedes brav sas, was es soll. Sobald das Java mit der Endlosschleife startet (2) kommt es zu unvorhersehbarem Verhalten.
Es ist seit einer Woche mein tägliches Ritual das Java morgens zu testen. An einem Tag läuft es sauber, an einem anderen Tag herrscht Chaos.
Dann produziert das Ding nur Datenmüll.

Ich sehe das Problem darin, dass mein Java zigtausend mal schneller in den Schleifen ist, als die Dateioperationen durchgeführt sind. Ich komme zu dem Schluss das ich mit den Schleifen so ein Verhalten hervorrufe und habe mich nun mit Threads und RaceConditions beschäftigt.
Ist mein geschilderter Sachverhalt ein klassisches Beispiel für den Einsatz von Threads?
Denke ich mit meinen vielen Schleifen und If-Conditions zu "analog"/"prozedural" ?
Ich verzweifle da echt... im Grunde muss ein Codeabschnitt stets abwarten, dass ein vorheriger Abschnitt ein Ergebnis produziert hat... was ist an meinem Denken so falsch?
 

mrBrown

Super-Moderator
Mitarbeiter
Das klingt zumindest umständlich...

Was mir da in den Sinn kommt, wäre ein FileWatcher für das warten auf die initiale txt, und dann sequentieller Ablauf für den Rest. Warum sollte man gesondert auf die PDF warten? Wenn die Prozesse durch sind, ist die PDF ja da, da kann man besser auf die Prozesse warten
 

jan_B

Mitglied
Guten Morgen Dukel,
vielen Dank für Deine Rückfrage.
Ich habe mit phpword experimentiert - allerdings lief mir das nicht zuverlässig genug. Zudem hatte ich Bedenken, dass bei einer Vielzahl an gleichzeitigen Zugriffen auf diese Funktionalität der Speed der Webseite leiden würde.
Hinzu kommt, dass es mir bisher nicht gelungen ist eine vernünftige Klasse zu finden (sowohl Für PHP, als auch für Java), die mir ein einwandfreies PDF erstellt.
Das Wordokument enthält viele Tabellen mit mehreren Spalten und Zeilen.
Die Ergebnisse sahen so fürchterlich aus, dass ich zähneknirchend den Weg über ein Wordmakro gewählt habe, da MSWord in der Tat ein perfektes PDF erstellt, dass meinen "Ansprüchen" genügt.
 

jan_B

Mitglied
Hallo mrBrown,

danke für deine Antwort.
In der Tat ist das echt ein bisl umständlich und ich denke daher rühren auch diese unbestimmten Ergebnisse dieses Prozesses.
Ich (er)warte auf das PDF, weil im Anschluss daran das PDF in das User VZ geladen werden muss. Ich würde ja einen Timer einbauen, denn ich bin weiterhin überzeugt, dass die Festplattenzugriffe und die docx/pdf-Erstellung deutlich langsamer sind als das Java. Aber mir ist ehrlich gesagt nicht wohl dabei dem Java zu sagen, dass es nach der Erstellung des docx max. 30 Sekunden warten soll, bis es fortfährt. Selbiges müsste auch nach der Erstellung des pdf erfolgen.
Dann läuft das sicherlich sauber durch, aber ich emfpinde das als "Pfuscherei" und wie Du schon richtig erkannt hast, ist der bisherige Weg ja auch nicht gerade elegant.
 

mrBrown

Super-Moderator
Mitarbeiter
Ich (er)warte auf das PDF, weil im Anschluss daran das PDF in das User VZ geladen werden muss. Ich würde ja einen Timer einbauen, denn ich bin weiterhin überzeugt, dass die Festplattenzugriffe und die docx/pdf-Erstellung deutlich langsamer sind als das Java. Aber mir ist ehrlich gesagt nicht wohl dabei dem Java zu sagen, dass es nach der Erstellung des docx max. 30 Sekunden warten soll, bis es fortfährt. Selbiges müsste auch nach der Erstellung des pdf erfolgen.
Warum wartest du nicht in Java drauf, dass die Erstellung beendet wurde? Du startest den Prozess doch auch aus Java?
 

jan_B

Mitglied
Im Grunde genommen, warte ich im Java darauf - ich schildere Dir mal, wie ich das umgesetzt habe:
1.
while (1<2) -> Endlosschleife zum Beginn des gesamten Prozesses
2.
if (file.exists(test.txt) -> abruf der initiierenden Textdatei
2.1
In der Folge wird die DB-Abfrage durchgeführt und mit dem daraus resultierenden array das docx befüllt
2.2
Mit dem Pfad der erstellten docx als Argument wird das batch erstellt, das dann das PDF auswirft
3.
while(!file.exists(xy.pdf)) -> Dauerschleife, die so lange läuft, bis eben die pdf gefunden wird
4.
if (file.exists(xy.pdf)) -> beim Auffinden der pdf, pdf verschieben
Ende 4.
Ende 3.
Ende 2.

Ich überlegte mir, dass ich return-Werte ausspucken lasse und diese dann mit den Schleifen/Bedingungen verknüpfe. Aber im Grunde stünde ich mit genau der gleichen Konstruktion wie bisher dar - nur eben bisschen sauberer. Und ich vertraue dieser Konstruktion nicht.

Liege ich falsch? Habe ich ein Brett vor dem Kopf?
 

mrBrown

Super-Moderator
Mitarbeiter
Eigentlich geht das ziemlich simple ohne viel umzubauen:

1. FileWatcher und warten auf neue txt-Datein
2. Db-Abfragen, Docx füllen
3. Externe bat starten
4. Wenn Prozess fertig, pdf verschieben

Schleifen braucht man dafür gar nichts.
 

jan_B

Mitglied
Grüß Dich mrBrown,

ich habe den Programm-Ablauf mal so umgebaut, wie von Dir empfohlen.
Es läuft sauber durch.

Es hakt jedoch zwischen den beiden Punkten 3 und 4. Java führt den Befehl mit der Batch aus und spring dann zu Punkt 4. Aber die Batch ist im Hintergrund noch nicht abgearbeitet (erstellen und eröffnen einer Instanz von MSWord, Durchführen des Makro's, als PDF speichern) und so greift das Verschieben des PDF-Outputs in Leere.

Ich stehe erneut vor den Problem, dass ich im Grunde genommen das Dateisystem auf eine PDF prüfen lassen muss, um diese dann erfolgreich zu verschieben.

Vllt ist es schlauer, wenn ich gar nicht erst alles in eine java packe, sondern zwei und die über zwei OS-Prozesse parrallel laufen lasse? Jedes prüft dann nur einen Ordner und gut ist?
 

mrBrown

Super-Moderator
Mitarbeiter
Es hakt jedoch zwischen den beiden Punkten 3 und 4. Java führt den Befehl mit der Batch aus und spring dann zu Punkt 4. Aber die Batch ist im Hintergrund noch nicht abgearbeitet (erstellen und eröffnen einer Instanz von MSWord, Durchführen des Makro's, als PDF speichern) und so greift das Verschieben des PDF-Outputs in Leere.
Ich habe keine Ahnung von Windows, aber es wird doch auch da sicher möglich sein, zu warten, bis ein Prozess fertig ist?

Vllt ist es schlauer, wenn ich gar nicht erst alles in eine java packe, sondern zwei und die über zwei OS-Prozesse parrallel laufen lasse? Jedes prüft dann nur einen Ordner und gut ist?
Ob das zwei oder ein Prozess ist, ist egal, relevant ist nur, das es unterschiedliche Threads sind.
Allerdings würde ich wie gesagt die andere Möglichkeit bevorzugen.
 

Meniskusschaden

Top Contributor
Ich habe keine Ahnung von Windows, aber es wird doch auch da sicher möglich sein, zu warten, bis ein Prozess fertig ist?
Das könnte knifflig werden, weil Word parallele Aufrufe möglicherweise auch dann in einem gemeinsamen Prozess abwickelt, wenn sie über unterschiedliche Prozesse gestartet wurden. Da mir Word nicht zur Verfügung steht, habe ich mal mit LibreOffice folgende Batch-Datei getestet:
Code:
echo Eins
"C:\Program Files\LibreOffice 5\program\swriter.exe"
echo Zwei
Wenn man sie aufruft, wird zunächst "Eins" ausgegeben und dann LibreOffice Writer gestartet. Erst sobald LibreOffice beendet wird, wird "Zwei" ausgegeben. Das wäre wohl das erwünschte Verhalten.

Falls LibreOffice zum Zeitpunkt des Aufrufs der Batch-Datei bereits geöffnet ist, verhält es sich anders. Dann wird "Eins" ausgegeben, ein weiteres LibreOffice-Dokument erstellt und sofort "Zwei" ausgegeben (bevor das Dokument wieder geschlossen wurde). Die LibreOffice-Fenster gehören dann zu derselben Prozess-ID.

Kann natürlich sein, dass der Effekt bei Word gar nicht auftritt. Möglicherweise gibt es auch einen Kommandozeilenparameter, mit dem man das Starten einer eigenen Word-Instanz erzwingen kann. Jedenfalls ist da bestimmt noch etwas Test-Aufwand nötig.
 

mrBrown

Super-Moderator
Mitarbeiter
Stimmt - aber es muss ja in Word noch irgendein Macro zum PDF speichern gestartet werden und darauf wird man ja sicher warten können, ob der Prozess weiter läuft oder nicht dürfte dafür ja egal sein.

Allerdings finde ich den Weg über Word auch etwas merkwürdig, ich würde da entweder ne passende Lib oder zB Latex für nutzen...
 

jan_B

Mitglied
Hallo mrBrown und Hallo Meniskusschaden :)
Der Umweg über Windows ist nicht freiwillig - die von mir getesteten Java-Klassen haben die Tabellenstruktur der Wordvorlage "zerstückelt", sodass ich nur diesen Weg gehen kann.

@mrBrown:
Es fehlt in der Batch eine Möglichkeit einen Rückgabewert vom Wordaufruf zu generieren. Ich hätte die Möglichkeit eine simple Textdatei aus dem Makro heraus zu erstellen, die wieder einen anderen Programmteil dazu veranlassen könnte das PDF an seinen Platz zu verschieben.
Oder ich verpasse der Batch-Datei so etwas wie eine "sleep"-Anweisung.

@Meniskusschaden
Der Batchbefehl öffnet eine eigene Instanz von Word. Die Fenster werden nicht angezeigt, sodass der gesamte Vorgang im Hintergrund läuft.
Das Batch läuft zwischenzeitlich weiter...

Ich denke so oder so komme ich um eine weitere "FileWatcher"-Prüfung nicht herum. Es ist echt bitter - da muss man einmal auf MS zurückgreifen und schon hat man den Salat.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
javamax2000 Sehr sonderbares Verhalten Allgemeine Java-Themen 6
kodela Unterschiedliches Verhalten von BufferedReader Allgemeine Java-Themen 3
N Best Practice Allgemeines Verhalten für ein Interface implementieren? Allgemeine Java-Themen 7
Thallius Merkwürdiges Verhalten von Swingworker.cancel() Allgemeine Java-Themen 2
T Merkwürdiges Thread-Verhalten Allgemeine Java-Themen 6
Tommy Nightmare Merkwürdiges Verhalten bei der Datenzuweisung Allgemeine Java-Themen 4
F JTable Pfeiltasten-Verhalten Allgemeine Java-Themen 1
Thallius Swing Merkwürdiges Verhalten beim Panel Tausch Allgemeine Java-Themen 3
W LocalDateTime Verhalten unerklärlich Allgemeine Java-Themen 1
Thallius Merkwürdiges StringBuilder verhalten (Char Encoding) Allgemeine Java-Themen 6
C Unterschiedliches Verhalten Editor und deployte Application Allgemeine Java-Themen 3
S Threads ThreadPoolExecutor eigenartiges verhalten Allgemeine Java-Themen 5
A Java Verhalten bei parallelem Aufruf derselben Methode?? Allgemeine Java-Themen 2
P Applet-Zugriffsrechte: merkwürdiges Verhalten Allgemeine Java-Themen 4
M Threads Viele Aufrufe aus Thread, komisches Verhalten Allgemeine Java-Themen 8
S getChildAt() Verhalten Allgemeine Java-Themen 4
S Frage zu Threads (Sichtbarkeit und Verhalten) Allgemeine Java-Themen 11
R Merkwürdiges Verhalten der equals Method Allgemeine Java-Themen 4
1 Collections Generics, internes Verhalten Allgemeine Java-Themen 16
S Collections Unverständliches Verhalten... Allgemeine Java-Themen 4
M Nach Programmdurchlauf werden Zeichen falsch dargestellt + Anderes Verhalten unter Windows Allgemeine Java-Themen 6
C Komisches Verhalten zwischen Set und List bei contains Allgemeine Java-Themen 6
S (Doppel)Klick-Verhalten vom Desktop unter Java imitieren. Allgemeine Java-Themen 5
A Seltsames Verhalten von JUnit-Tests im Zusammenspiel mit Ant Allgemeine Java-Themen 6
S Verhalten von System.getenv() in Ubuntu / Linux Allgemeine Java-Themen 12
hdi Verhalten bei nicht behandelten Exceptions Allgemeine Java-Themen 2
J Rätselhaftes Verhalten von Collections Allgemeine Java-Themen 5
M Unerklärliches Verhalten bei Variableninitialisierung Allgemeine Java-Themen 11
S Verhalten der Klasse TreeSet... Allgemeine Java-Themen 4
S Jar und Exe verhalten sich unterschiedlich unter Vista Allgemeine Java-Themen 8
M Seltsames Verhalten eines StringReaders Allgemeine Java-Themen 2
spacegaier HeapSpace der VM ändern -> Verhalten von JARs und EXEs Allgemeine Java-Themen 10
M merkwürdiges Verhalten von JUnit4 Allgemeine Java-Themen 2
M JList seltsames verhalten. Allgemeine Java-Themen 5
K Seltsames Verhalten von byte[] und Strings Allgemeine Java-Themen 6
S Seltsames Verhalten von split() Allgemeine Java-Themen 3
K Überschreiben von 'static'-Methoden hat anderes Verhalten? Allgemeine Java-Themen 2
A Streams: merkwürdiges Verhalten Allgemeine Java-Themen 7
A Streams - merkwürdiges Verhalten Allgemeine Java-Themen 2
O JAR Export Textdatei benutze Allgemeine Java-Themen 14
H2SO3- wo benutze ich javac -help Allgemeine Java-Themen 5

Ähnliche Java Themen

Neue Themen


Oben