matthiasforberg
Occasional Collector

DisplayNames setzen per Serverskript?

Jump to solution

Hallo,

ich habe die ehrenvolle Aufgabe, in einem Projekt mehrere Tausend Anzeigenamen von PageFolders umzubenennen. Das Skript steht soweit und ist auch alles wunderbar, aber da das über ein VPN läuft, dauert die Ausführung seeeeeehr lange!

Jetzt habe ich mir gedacht, es wäre eine pfiffige Idee, das ganze leicht umzubauen und in der Auftragsverwaltung als Serverskript laufen zu lassen.

Leider bricht es beim ersten Lock gleich ab und schmeißt mir die folgende Exception (siehe unten).

Kann man das nur im JavaClient machen? Oder was ist die Ursache? Kann man das umgehen? Vielleicht als Admin ausführen?

Danke und Grüße

Matthias

...übrigens e = context.userService.getStore(Store.Type.PAGESTORE,true,false);

und hier die Exception:

ERROR 23.11.2013 23:33:45.629 {seID=5659875} (de.espirit.firstspirit.server.scheduler.ScriptTaskExecutor): error during script execution : de.espirit.firstspirit.access.script.ExecutionException: Method Invocation e.setLock at line 33

de.espirit.firstspirit.access.script.ExecutionException: Method Invocation e.setLock at line 33

    at de.espirit.firstspirit.server.script.BeanshellScriptEngine$BeanshellExecutable.execute(BeanshellScriptEngine.java:120)

    at de.espirit.firstspirit.common.ScriptUtil.execute(ScriptUtil.java:88)

    at de.espirit.firstspirit.server.scheduler.ScriptTaskExecutor.run(ScriptTaskExecutor.java:119)

    at de.espirit.firstspirit.server.scheduler.ScheduleManagerImpl$TaskCallable.executeLocal(ScheduleManagerImpl.java:2021)

    at de.espirit.firstspirit.server.scheduler.ScheduleManagerImpl$TaskCallable.executeLocal(ScheduleManagerImpl.java:2001)

    at de.espirit.firstspirit.server.scheduler.ScheduleManagerImpl$TaskCallable.call(ScheduleManagerImpl.java:1929)

    at de.espirit.firstspirit.server.ExecutionManagerImpl$ExtendedCallable.call(ExecutionManagerImpl.java:520)

    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)

    at java.util.concurrent.FutureTask.run(FutureTask.java:138)

    at de.espirit.common.util.BoundedExecutorService$RunnableWrapper.run(BoundedExecutorService.java:419)

    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)

    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)

    at java.util.concurrent.FutureTask.run(FutureTask.java:138)

    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)

    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)

    at java.lang.Thread.run(Thread.java:680)

    at de.espirit.common.util.SuspendableThread.run(SuspendableThread.java:36)

Caused by: java.lang.SecurityException: changes not allowed for current connection

    at de.espirit.firstspirit.server.scheduler.RestrictedTaskSecurityManager.checkAccess(RestrictedTaskSecurityManager.java:28)

    at de.espirit.firstspirit.store.access.AbstractStoreElement.checkAccess(AbstractStoreElement.java:1596)

    at de.espirit.firstspirit.store.access.DefaultStoreElement.setLock(DefaultStoreElement.java:440)

    at de.espirit.firstspirit.store.access.DefaultStoreElement.setLock(DefaultStoreElement.java:432)

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

    at java.lang.reflect.Method.invoke(Method.java:597)

    at bsh.Reflect.invokeMethod(Unknown Source)

    at bsh.Reflect.invokeObjectMethod(Unknown Source)

    at bsh.Name.invokeMethod(Unknown Source)

    at bsh.BSHMethodInvocation.eval(Unknown Source)

    at bsh.BSHPrimaryExpression.eval(Unknown Source)

    at bsh.BSHPrimaryExpression.eval(Unknown Source)

    at bsh.BSHIfStatement.eval(Unknown Source)

    at bsh.BSHBlock.evalBlock(Unknown Source)

    at bsh.BSHBlock.eval(Unknown Source)

    at bsh.BshMethod.invokeImpl(Unknown Source)

    at bsh.BshMethod.invoke(Unknown Source)

    at bsh.BshMethod.invoke(Unknown Source)

    at bsh.Name.invokeLocalMethod(Unknown Source)

    at bsh.Name.invokeMethod(Unknown Source)

    at bsh.BSHMethodInvocation.eval(Unknown Source)

    at bsh.BSHPrimaryExpression.eval(Unknown Source)

    at bsh.BSHPrimaryExpression.eval(Unknown Source)

    at bsh.BSHBlock.evalBlock(Unknown Source)

    at bsh.BSHBlock.eval(Unknown Source)

    at bsh.BshMethod.invokeImpl(Unknown Source)

    at bsh.BshMethod.invoke(Unknown Source)

    at bsh.BshMethod.invoke(Unknown Source)

    at bsh.This.invokeMethod(Unknown Source)

    at bsh.This.invokeMethod(Unknown Source)

    at de.espirit.firstspirit.server.script.BeanshellScriptEngine$BeanshellExecutable.execute(BeanshellScriptEngine.java:111)

    ... 16 more

0 Kudos
1 Solution

Accepted Solutions
mbergmann
Crownpeak employee

Hallo Matthias,

Scripte in Aufträgen nutzen per Default eine read only Connection. Sollen Änderungen durch das Script durchgeführt werden, muss mit dem Button "Eigenschaften" im Scriptdialog des Tasks eine eigene Connection konfiguriert werden. Üblicherweise nutzt man hierfür einen technischen User, der über die entsprechenden Rechte verfügt.

Viele Grüße

Michael

View solution in original post

0 Kudos
10 Replies
mbergmann
Crownpeak employee

Hallo Matthias,

Scripte in Aufträgen nutzen per Default eine read only Connection. Sollen Änderungen durch das Script durchgeführt werden, muss mit dem Button "Eigenschaften" im Scriptdialog des Tasks eine eigene Connection konfiguriert werden. Üblicherweise nutzt man hierfür einen technischen User, der über die entsprechenden Rechte verfügt.

Viele Grüße

Michael

0 Kudos

Alle Achtung!

Ich hätte nicht damit gerechnet, dass ich an einem Sonntag eine Antwort darauf bekomme. Nicht schlecht!

Guter Hinweis mit den Verbindungsdaten im Auftrag. Jetzt weiß ich endlich, wozu die Felder gut sind... Leider bringt es aber in diesem Fall keine Veränderung. Ich bekomme immer noch dieselbe Exception. Ich habe das auch auf einem eigenen Testsystem ausprobiert, mit dem Admin - der definitiv alle Rechte hat. Leider nix!

Gibt es noch einen anderen Ansatz, sich die richtige Connection zu holen? Ansonsten muss ich das doch als Client-Script laufen lassen, was dann vermutlich Stunden dauern wird.

Grüße

Matthias

Edit:

Hier noch ein Extrakt meines Codes. Vielleicht ist da ja ein Denkfehler drin?!

import de.espirit.firstspirit.access.store.StoreElementFolder;

import de.espirit.firstspirit.access.store.Store.Type;

refMap = new HashMap();

writeNames(testMode) {

  e = context.userService.getStore(Type.PAGESTORE,true,false);

  l = context.project.masterLanguage;

  all = e.getChildren(StoreElementFolder.class,true).toList();

 

  for (folder : all) {

    uid = folder.uid;

    dsp = folder.getDisplayName(l);

    rel = folder.releaseStatus;

    if(dsp.equals(uid)) {

      dsp = refMap.get(uid);

      context.logInfo(uid+" --> "+dsp);

      if(!testMode && dsp != null) {

        folder.setLock(true,false);

        folder.getLanguageInfo(l).setDisplayName(dsp);

        folder.save();

        folder.setLock(false,false);

        if(rel != 0) {

            folder.release(false);

        }

      }

    }

  }

}

// ...befüllen der HashMap

writeNames(false);

0 Kudos

Die Meldung nachdem der Umstellung des Auftrages muss aber eine andere sein. Die SecurityException wird durch die vorgschlagene Anpassung behoben.

Peter
0 Kudos

Leider nein. Ich bekomme immer noch dieselbe "java.lang.SecurityException: changes not allowed for current connection"

Das einzige, was sich geändert hat, sind diese Einträge:

INFO  25.11.2013 14:44:35.815 {seID=843359} (de.espirit.firstspirit.server.sessionmanagement.SessionManagerImpl): new session (ID=3681609862860288097, user=Admin, userID=1, type=DUMMY) created

INFO  25.11.2013 14:44:35.816 {seID=843359} (de.espirit.firstspirit.server.scheduler.ScriptTaskExecutor): skript connection created: 3681609862860288097, user=Admin

INFO  25.11.2013 14:44:35.816 {seID=843359} (de.espirit.firstspirit.server.sessionmanagement.SessionManagerImpl): new session (ID=2062703538509913757, user=Admin, userID=1, type=DUMMY) created

...

INFO  25.11.2013 14:44:36.026 {seID=843359} (de.espirit.firstspirit.server.sessionmanagement.SessionManagerImpl): Session terminated (ID=2062703538509913757, user=Admin(dummy)), number of sessions now 80

INFO  25.11.2013 14:44:36.026 {seID=843359} (de.espirit.firstspirit.server.sessionmanagement.SessionManagerImpl): Invalid session id 2062703538509913757

INFO  25.11.2013 14:44:36.026 {seID=843359} (de.espirit.firstspirit.server.sessionmanagement.SessionManagerImpl): close dummy session (ID=3681609862860288097, user=Admin)

INFO  25.11.2013 14:44:36.026 {seID=843359} (de.espirit.firstspirit.server.sessionmanagement.SessionManagerImpl): Invalid session id 3681609862860288097

Und es sind definitiv die Berechtigungen zum Ändern im Pagestore vorhanden. Mein Try/Catch schmeißt mir aber bei JEDEM Knoten den Fehler. Scheint also doch noch irgendwas zu fehlen?!

Es handelt sich übrigens noch um die Server-Version 4.2.468, falls das irgendwie relevant ist.

0 Kudos

Wenn der Typ des Skriptes wirklich korrekt ist, dann ist das wohl ein Fall für den Helpdesk.

Es handelt sich übrigens noch um die Server-Version 4.2.468, falls das irgendwie relevant ist.

Der kann dazu dann kompetent Auskunft geben.

Peter
0 Kudos

Hallo Matthias,

du muss die connection im code auch benutzen, das sehe ich in dem Beispiel nicht. Machst du das?

UserService und Project müssen über das connection Objekt und nicht über das context Objekt geholt werden.

Viele Grüße


Tobias

Hallo Tobias,

vielen Dank, das klingt allerdings logisch! Ich dachte, es wird direkt die Connection verwendet, aber jetzt wo du's sagst, habe ich das wohl nicht berücksichtigt. Ich fürchte, ich muss mich aber weiter blamieren, ich weiß nämlich nicht, wie man sich die Connection aus den Eigenschaften holt. Mit context.getConnection() offenbar nicht, denn ich habe die zwei Zeilen umgebaut und es hat nichts gebracht:

  p = context.connection.getProjectById(pid);

  e = p.userService.getStore(Type.PAGESTORE,true,false);

Muss ich die Verbindung irgendwie über getProperty holen oder so? Wie mache ich das ganz ohne "context"?

Grüße

Matthias

EDIT:

OK, ich ziehe die Frage zurück - wer lesen kann, ist klar im Vorteil. Laut Admin-Handbuch, geht es direkt über connection...

Das probier ich jetzt nochmal aus.

0 Kudos
matthiasforberg
Occasional Collector

Juhu,

danke Euch, jetzt hat es endlich geklappt. Ich habe mir die Verbindung im Skript so geholt:

pid = 12345;

p = connection.getProjectById(pid);

e = p.userService.getStore(Type.PAGESTORE,true,false);

l = p.masterLanguage;

Und so geht es jetzt.

Grüße

Matthias

0 Kudos

genau wenn du bsh nutzt ist das connection objekt nutzbar. Im Executable musste es dir aus der map holen.

Ex-/Import save und kopierbr wir es so: project = connection.getProjectById(context.getProject().getId());

Viele Grüße


Tobias