Search the FirstSpirit Knowledge Base
Hallo zusammen,
ich habe einen Auftrag eingerichtet, mit dem ich per Skript eine Properties Datei (der Zweck ist hier unwichtig) erstellen kann. Das funktioniert auch gut in unserer Entwicklungsumgebung. Das Skript sammelt alle Informationen zusammen und erstellt per java.io.PrintWriter die Datei in einem angegebenen Generierungsverzeichnis. Die Methode dafür sieht so aus:
writeFile(fileContent){
try{
printWriter = new PrintWriter(context.getPath() + OUTPUT_FILE);
printWriter.write(fileContent.toString());
printWriter.close();
}catch (Exception ex){
context.logError("Cannot write file " + ex, ex);
}
}
Wie gesagt, auf DEV funktioniert das und die Datei wird geschrieben. In der PROD Umgebung schmeißt es jedoch eine Exception:
ERROR 21.12.2018 10:03:23.388 (de.espirit.firstspirit.impl.access.ScriptContextImpl): Cannot write file java.io.FileNotFoundException: D:\appl\FirstSpirit5\web\fs5staging\2757\across\textlimits.properties (The system cannot find the path specified)
java.io.FileNotFoundException: D:\appl\FirstSpirit5\web\fs5staging\2757\across\textlimits.properties (The system cannot find the path specified)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
at java.io.PrintWriter.<init>(PrintWriter.java:184)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at bsh.Reflect.constructObject(Reflect.java:594)
at bsh.BSHAllocationExpression.constructObject(BSHAllocationExpression.java:125)
at bsh.BSHAllocationExpression.objectAllocation(BSHAllocationExpression.java:114)
at bsh.BSHAllocationExpression.eval(BSHAllocationExpression.java:62)
at bsh.BSHPrimaryExpression.eval(BSHPrimaryExpression.java:102)
at bsh.BSHPrimaryExpression.eval(BSHPrimaryExpression.java:47)
at bsh.BSHAssignment.eval(BSHAssignment.java:77)
at bsh.BSHBlock.evalBlock(BSHBlock.java:130)
at bsh.BSHBlock.eval(BSHBlock.java:80)
at bsh.BSHBlock.eval(BSHBlock.java:46)
at bsh.BSHTryStatement.eval(BSHTryStatement.java:88)
at bsh.BSHBlock.evalBlock(BSHBlock.java:130)
at bsh.BSHBlock.eval(BSHBlock.java:80)
at bsh.BshMethod.invokeImpl(BshMethod.java:371)
at bsh.BshMethod.invoke(BshMethod.java:267)
at bsh.BshMethod.invoke(BshMethod.java:195)
at bsh.Name.invokeLocalMethod(Name.java:917)
at bsh.Name.invokeMethod(Name.java:804)
at bsh.BSHMethodInvocation.eval(BSHMethodInvocation.java:75)
at bsh.BSHPrimaryExpression.eval(BSHPrimaryExpression.java:102)
at bsh.BSHPrimaryExpression.eval(BSHPrimaryExpression.java:47)
at bsh.BSHBlock.evalBlock(BSHBlock.java:130)
at bsh.BSHBlock.eval(BSHBlock.java:80)
at bsh.BshMethod.invokeImpl(BshMethod.java:371)
at bsh.BshMethod.invoke(BshMethod.java:267)
at bsh.BshMethod.invoke(BshMethod.java:170)
at bsh.PreparsedScript.invoke(PreparsedScript.java:66)
at de.espirit.firstspirit.server.script.BeanshellScriptEngine$BeanshellExecutable.execute(BeanshellScriptEngine.java:100)
at de.espirit.firstspirit.common.ScriptUtil.execute(ScriptUtil.java:106)
at de.espirit.firstspirit.server.scheduler.ScriptTaskExecutor.run(ScriptTaskExecutor.java:133)
at de.espirit.firstspirit.server.scheduler.ScheduleManagerImpl$TaskCallable.executeLocal(ScheduleManagerImpl.java:2509)
at de.espirit.firstspirit.server.scheduler.ScheduleManagerImpl$TaskCallable.executeLocal(ScheduleManagerImpl.java:2492)
at de.espirit.firstspirit.server.scheduler.ScheduleManagerImpl$TaskCallable.call(ScheduleManagerImpl.java:2424)
at de.espirit.firstspirit.server.ExecutionManagerImpl$ExtendedCallable.call(ExecutionManagerImpl.java:590)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at de.espirit.common.util.BoundedExecutorService$RunnableWrapper.run(BoundedExecutorService.java:436)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
at de.espirit.common.util.SuspendableThread.run(SuspendableThread.java:56)
Hier muss ich eine Dummy-Generierung davor setzen, damit das Generierungsverzeichnis erzeugt wird. Das ist allerdings blöd, weil ich dann eine weitere Datei darin liegen habe, die ich eigentlich gar nicht brauche.
Da das Verhalten auf zwei Systemen offenbar unterschiedlich ist, meine Frage: wovon hängt es ab, ob ein Generierungsverzeichnis (neu) angelegt wird oder nicht? Und wie komme ich dahin, auf PROD auf die Dummy-Generierung verzichten zu können?
Danke schon mal und weihnachtliche Grüße!
Matthias
Hi Matthias,
das scheint doch im ersten Moment logisch: Wenn es keine Generierung innerhalb eines Auftrags gibt, wird auch kein Generierungsordner erstellt.
Ansonsten würde FS ja ein haufen leerer Ordner erzeugen, die niemand benötigt.
Wahrscheinlich war auf dem DEV-System irgendwann ein Generierungstask innerhalb des Auftrags, wodurch das Generierungsverzeichnis angelegt wurde. Anschließend wurde dann wahrscheinlich im laufe der Entwicklung dieser Task entfernt, wodurch der Auftrag nur noch auf DEV lauffähig war.
Um das Skript sicherstellen zu lassen, dass das von dir benötigte Verzeichnis existiert, kannst du folgenden Java-Funktion nutzen:
java.nio.file.Files.createDirectories(context.getPath());
Bitte beachte, dass du den Ordner selber verwalten musst.
FS besitzt ja die "leere Generierungsverzeichnis" innerhalb des Generierungstask, die du jetzt selber abbilden müsstest.
Damit keine historischen Artefakte in diesem Ordner liegen bleiben, solltest du ggf. den Ordner am Anfang des Skriptes nocheinmal leeren.
Gruß,
Christopher
Hallo nochmal,
kleines Update: inzwischen kann ich das Skript auch ohne die Dummy-Generierung starten. Ich verstehe bloß nicht, warum das so ist. Die Erklärung könnte natürlich sein, dass das Generierungsverzeichnis einmal durch eine Generierung angelegt worden sein muss. Aber dann hätte es auch nach dem ersten Durchlauf mit Dummy funktionieren müssen, wenn ich den Dummy deaktiviere. Hatte ich ausprobiert, ging nicht. Gibt es noch irgendwelche Erklärungen dafür, warum es auf einem System auf Anhieb klappte, auf einem anderen aber nicht (beide laufen auf derselben Version 2018-07, ein Update steht bevor).
Grüße
Matthias
Hi Matthias,
das scheint doch im ersten Moment logisch: Wenn es keine Generierung innerhalb eines Auftrags gibt, wird auch kein Generierungsordner erstellt.
Ansonsten würde FS ja ein haufen leerer Ordner erzeugen, die niemand benötigt.
Wahrscheinlich war auf dem DEV-System irgendwann ein Generierungstask innerhalb des Auftrags, wodurch das Generierungsverzeichnis angelegt wurde. Anschließend wurde dann wahrscheinlich im laufe der Entwicklung dieser Task entfernt, wodurch der Auftrag nur noch auf DEV lauffähig war.
Um das Skript sicherstellen zu lassen, dass das von dir benötigte Verzeichnis existiert, kannst du folgenden Java-Funktion nutzen:
java.nio.file.Files.createDirectories(context.getPath());
Bitte beachte, dass du den Ordner selber verwalten musst.
FS besitzt ja die "leere Generierungsverzeichnis" innerhalb des Generierungstask, die du jetzt selber abbilden müsstest.
Damit keine historischen Artefakte in diesem Ordner liegen bleiben, solltest du ggf. den Ordner am Anfang des Skriptes nocheinmal leeren.
Gruß,
Christopher
Danke Christopher,
die eine Zeile Java ist sicher nützlich und ich werde sie wohl noch einbauen. Damit ist es vermutlich sicher. Leeren brauche ich es erstmal nicht, weil sowieso nur eine einzige Datei erzeugt wird. Aber auch den Tipp behalte ich im Hinterkopf.
Allerdings muss ich Deinem ersten Satz etwas widersprechen, denn so logisch finde ich es gar nicht, dass das Verzeichnis nur bei einer Generierung erzeugt wird, denn es wird ja nicht bei der Generierung angegeben, sondern für den ganzen Task. Also wenn ich schon extra eins angebe, dann erwarte ich eigentlich auch, dass es angelegt wird - egal ob ich generiere oder nicht. Scheint aber wohl nicht so zu sein, wie ich jetzt weiß...
Viele Grüße
Matthias