Search the FirstSpirit Knowledge Base
Hallo Community,
ich bekomme leider immer wieder eine "Not locked"-Exception beim Abschließen eines Workflows. Das ganze passiert aber nur bei einer Seitenreferenz, bei Inhalte(-Ordner) usw. klappt es.
Hier kurz die Fehlermeldung die mir FS ausspuckt:
Client Version: 4.2.454.47473
Java Version: 1.7.0_05 Oracle Corporation
FSVersion=4.2.454.47473#2499;JDK=1.7.0_05 64bit Oracle Corporation;OS=Windows 7 6.1 amd64;Date=18.02.2013 17:01:56
java.lang.IllegalStateException: node 'intra_telefonverzeichnis_1' (ID=1780377, project=1665384) not locked
at de.espirit.firstspirit.store.access.DefaultStoreElement.updateWorkflowData(DefaultStoreElement.java:654)
at de.espirit.firstspirit.server.taskmanagement.TaskImpl.doTransition(TaskImpl.java:1154)
at de.espirit.firstspirit.server.taskmanagement.TaskImpl.doAutomaticActivities(TaskImpl.java:1477)
at de.espirit.firstspirit.server.taskmanagement.TaskImpl.doTransition(TaskImpl.java:1158)
at de.espirit.firstspirit.server.taskmanagement.TaskImpl.doTransition(TaskImpl.java:1012)
at de.espirit.firstspirit.client.action.WorkflowAction.startWorkflow(WorkflowAction.java:432)
at de.espirit.firstspirit.client.action.WorkflowAction.startWorkflow(WorkflowAction.java:65)
at de.espirit.firstspirit.client.action.WorkflowAction.startWorkflow(WorkflowAction.java:74)
at de.espirit.firstspirit.client.action.WorkflowUtil.startWorkflow(WorkflowUtil.java:66)
at de.espirit.firstspirit.client.action.WorkflowMenuAction$WFStartAction.actionPerformed(WorkflowMenuAction.java:272)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at de.espirit.firstspirit.client.AWTDispatchingEventQueue.defaultDispatchEvent(AWTDispatchingEventQueue.java:130)
at de.espirit.firstspirit.client.AWTDispatchingEventQueue._dispatchEvent(AWTDispatchingEventQueue.java:115)
at de.espirit.firstspirit.client.AWTDispatchingEventQueue.dispatchEvent(AWTDispatchingEventQueue.java:108)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Ich versuche die Freigabe über ein Executable auszuführen da wir dieses in ein Modul implementiert haben. Hier der relevante Teil des Codes von dem aus die Methode aufgerufen wird in welcher dann die Exception auftritt:
this.setLock(storeElement, true);
if (this.context instanceof WorkflowScriptContext) {
try {
LOG.info("do transition to 'Final'");
((WorkflowScriptContext) this.context).doTransition("Final"); // an dieser Stelle wird die Exception geworfen
} catch (IllegalAccessException ex) {
LOG.error(ex);
}
}
Für das "locking" habe ich mir eine Methode geschrieben damit es, der Doku entsprechend, immer "richtig" gemacht wird:
private boolean setLock(final IDProvider storeElement, final boolean lock) {
boolean isRecursive = false;
final boolean wasLocked = storeElement.isLocked();
try {
if (storeElement instanceof Page) {
isRecursive = true;
}
if (!wasLocked && lock) {
// set lock only if the node is not locked already
storeElement.setLock(lock, isRecursive);
} else if (wasLocked && !lock) {
// remove lock only if node is locked
storeElement.setLock(lock, isRecursive);
}
} catch (ElementDeletedException ex) {
LOG.error(ex);
} catch (LockException ex) {
LOG.error("Node '" + storeElement.getUid() + "' already locked by '" + ex.getUserLoginName() + "'!", ex);
}
return isRecursive;
}
Ich habe schon alle möglichen Konstellationen versucht aber nichts verhinderte den Fehler. Daher mein Gesuch an Euch.
Danke und Gruß
Christian
Hallo Christian,
ich hab mir nun den von dir geposteten Code angesehen, ohne ihn auszuprobieren.
Wenn ich das richtig nachvollzogen habe, liegt der Fehler in der if-Abfrage der setLock-Methode.
Mal der Reihe nach:
this.setLock(storeElement, true);
Diese Zeile ruft die Methode auf:
private boolean setLock(final IDProvider storeElement, final boolean lock) {
Somit ist lock = true .
Es folgt:
final boolean wasLocked = storeElement.isLocked();
Ist evtl. an dieser Stelle wasLocked = true ?
Denn dann würde weder die If-Abfrage
if (!wasLocked && lock)
// Soll: wasLocked = false, lock = true
// Ist (s.o.): wasLocked = true, lock = true
// --> Abfrage nicht erfüllt
noch die else if-Abfrage
else if (wasLocked && !lock)
// Soll: wasLocked = true, lock = false
// Ist (s.o.): wasLocked = true, lock = true
// --> Abfrage nicht erfüllt
zum Erfolg führen und der setLock()-Befehl in keinem der beiden Fälle ausgeführt werden.
Wenn ich das richtig sehe, kann die else if-Abfrage auch niemals erfüllt werden, da lock ja fest mit true übergeben wird und somit nie false sein kann, oder?
LG Michaela
Hallo Michaela,
danke erstmal für Deine Antwort.
Ich rufe die Methode auch mit dem Parameter lock = false auf, z.B. wenn ich das Lock explizit lösen möchte. Sollte aber bei dem Aufruf mit lock = true und wasLocked = true sein, dann soll es ja auch kein lock setzen, da sonst die Gefahr einer "LockException" besteht. Daher auch die zusätzliche Abfrage ob das Element bereits einen Lock hat.
Mein Problem ist aber, das Element besitzt keinen Lock, ich muss es aber locken um die Workflow-Transition abschließen zu können, jedoch schmeißt es mir bei der "doTransition" den Fehler dass das Element nicht gelocked sei, obwohl ich es vorher explizit locke.
Grüße
Christian
Hallo,
auf eine interne Nachfrage erhielt ich die Antwort, dass ein Element an dieser Stelle eigentlich nicht gelockt werden müsse. Was passiert denn, wenn der Schritt an dieser Stelle weggelassen und nur der Aufruf doTransisiton ausgeführt wird?
LG Michaela
So, ich hatte jetzt wieder Zeit mich der Problematik anzunehmen. Ich habe meinen Code mal komplett refactored und alle unnötigen "locks" entfernt. Zudem habe ich das Debugging mit meiner JIDEA eingerichtet und konnte jetzt so dem Problem besser auf den Zahn fühlen. In der Tat war das locken von meiner Seite unnötig, jedoch besteht jetzt das Problem das diese "Lock-Exception" nicht mehr durch meinen Code verursacht wird sondern intern durch den FS-Code. Hier mal der Stacktrace:
ERROR 15.04.2013 11:21:04.272 (de.espirit.firstspirit.client.action.WorkflowAction): Error creating task - java.lang.IllegalStateException: node 'mb_metanavigation' (ID=1671224, project=1665384) not locked
FSVersion=4.2.454.47473#2499;JDK=1.7.0_17 32bit Oracle Corporation;OS=Windows 7 6.1 x86;Date=15.04.2013 11:21:04
java.lang.IllegalStateException: node 'mb_metanavigation' (ID=1671224, project=1665384) not locked
at de.espirit.firstspirit.store.access.DefaultStoreElement.updateWorkflowData(DefaultStoreElement.java:654)
at de.espirit.firstspirit.server.taskmanagement.TaskImpl.doTransition(TaskImpl.java:1154)
at de.espirit.firstspirit.server.taskmanagement.TaskImpl.doAutomaticActivities(TaskImpl.java:1477)
at de.espirit.firstspirit.server.taskmanagement.TaskImpl.doTransition(TaskImpl.java:1158)
at de.espirit.firstspirit.server.taskmanagement.TaskImpl.doTransition(TaskImpl.java:1012)
at de.espirit.firstspirit.client.action.WorkflowAction.startWorkflow(WorkflowAction.java:432)
at de.espirit.firstspirit.client.action.WorkflowAction.startWorkflow(WorkflowAction.java:65)
at de.espirit.firstspirit.client.action.WorkflowAction.startWorkflow(WorkflowAction.java:74)
at de.espirit.firstspirit.client.action.WorkflowUtil.startWorkflow(WorkflowUtil.java:66)
at de.espirit.firstspirit.client.action.WorkflowMenuAction$WFStartAction.actionPerformed(WorkflowMenuAction.java:272)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
Das ganze passiert aber außerhalb des Moduls. Also das Modul wurde bereits verlassen wenn dieser Fehler auftritt. Das letzte was ich ausführe ist folgender Code:
if (this.context instanceof WorkflowScriptContext) {
try {
LOG.info("do transition to 'Final' ...");
((WorkflowScriptContext) this.context).doTransition("Final");
LOG.info("finished.");
} catch (final IllegalAccessException ex) {
LOG.error(ex);
} catch (final Exception ex) {
LOG.error(ex);
}
}
Dies wird jetzt alles ohne Probleme ausgeführt (was vorher aber nicht so war, siehe eingehender Post) aber nach verlassen des Moduls wird von seitens FS noch etwas gemacht und das verursacht jetzt diesen Fehler.
Die Frage wäre jetzt einfach, hab ich noch etwas vergessen? Bug im FS? Die Doku hält sich diesbzgl. ja leider etwas zurück mit Informationen.
Viele Grüße
Christian
Message was edited by: Christian Seifert
Ich habe noch mal ein wenig in der First-Spirit API zu dem Problem recherchiert. Ohne mich jetzt im Detail mit dem FirstSpirit Workflow Prozess auszukennen, liegt hier möglicherweise dennoch ein Verständnisproblem vor.
Die API sagt folgendes zur doTransition-Methode:
doTransition
State doTransition(@NotNull
WorkflowContext context,
@NotNull
Transition transition)
throws LockException,
ElementDeletedException
Perform transition execution on this task. The task has to be locked. The task is changed during the transition, you have to save it afterwards.
Throws:
LockException
ElementDeletedException
Since:
4.0.120
Bisher ging es ja immer darum das Element zu locken. Der falsche Status scheint sich aber auf das Task-Objekt zu beziehen. Möglicherweise muss hier noch ein "lock" im Quellcode auf den generierten Task gesetzt werden. Vielleicht kann das jemand von den e-spirit Kollegen bestätigen oder dementieren.