dominik_koenig
Returning Observer

ContentCreator: Service aus Workflow starten

Jump to solution

Hallo,

ich versuche gerade einen selbst entwickelten Service aus einem Workflow heraus zu starten.

Im Prinzip funktioniert das ja so

synchronizationService = context.getConnection().getService("ServiceName");

Das funktioniert auch super, wenn ich das aus dem SiteArchitect heraus starte.

Leider geht das aber nicht, wenn ich versuche den Workflow aus dem ConentCreator zu starten, da er dann den Service nicht findet.

Es ist aber nicht so, dass er gar nicht von meinem Service weiß, da ich eine java.lang.ClassNotFoundException mit dem genauen Package Namen bekomme.

Ich wollte den 1. Ansatz aus diesem Post ausprobieren: UX-Bridge aus Webedit/Content Creator Workflow-Skript aufrufen habe das aber leider nicht zum laufen bekommen, weil ich nicht weiß, wie ich aus einem Script heraus einen Teil einer WebApp starten soll.

Zumindest mit dieser Modulbeschreibung schmeißt mir das Script immer einfach einen Fehler (Ohne Fehlermeldung), wenn ich eine Klasse aus der WebApp aufrufen will.

...

<web-app>

     <name>ExampleWebApp</name>

     <class>my.package.ExampleWebApp</class>

     <web-xml>web.xml</web-xml>

     <resources>

          <resource>lib/@FILENAME@.jar</resource>

     </resources>

</web-app>

...

0 Kudos
1 Solution

Accepted Solutions
pavone
I'm new here

Hallo Dominik,

meine Vermutung ist, dass die Service-Klasse innerhalb der WebApp nicht bekannt ist, weil sie nicht als Resource angegeben wurde.

Wir haben ganz gute Erfahrungen damit gemacht, Services folgendermaßen zu implementieren:

  1. Wir definieren ein fachliches Interface für den Service, welches in einem separaten JAR abgelegt wird, welches serverweit bekannt gemacht wird (scope "server").
  2. Die Implementierung des Services liegt in einer anderen JAR, die lediglich modulweit bekannt ist (scope "module").
  3. Beide JARs werden auch in der WebApp hinzugefügt.

Die module.xml sieht also in etwa so aus:

<web-app scopes="global,project">

  <name>[...]</name>

  <web-xml>web/web.xml</web-xml>

  <web-resources>

    <resource>lib/global.jar</resource>

    <resource>lib/local.jar</resource>

  </web-resources>

</web-app>

<service>

  <name>[...]</name>

  <class>[...].MyServiceImpl</class>

</service>

<resources>

  <resource scope="server">lib/global.jar</resource>

  <resource scope="module">lib/local.jar</resource>

</resource>

Zum Finden des Services verwenden wir grundsätzlich nicht den Namen des Services, sondern das Interface:

servicesBroker.getService(MyService.class);

Vielleicht hilft dir die Information ja weiter.

Viele Grüße

Tim

View solution in original post

0 Kudos
6 Replies
bIT_sosswald
Returning Responder

Hallo Dominik,

die erste Frage wäre: Was genau willst du mit deinem Service machen?

Je nachdem was du machen willst ist eine Service_Komponente oder aber evtl. auch ein Client-Service die richtige Option.

Eine WebApp, klingt als Komponente für einen klassischen Service auf den ersten Blick nicht unbedingt als der besten Ort für einen Service.

Ich definiere meine Services immer wie folgt in der module.xml:

<service>

<name>bIT - import service</name>

<description>Service to import products

into FirstSpirit.</description>

<class>de.bit.firstspirit.xx.ProductImporterFSServiceImpl</class>

<resources>

<resource name="bITResources" scope="module">lib/${project.artifactId}-${project.version}-jar-with-dependencies.jar</resource>

</resources>

</service>

Zusätzlich definiere ich Executables, wie folgt:

<public>

<name>bIT- import executable</name>

<description>Executable class to start a productImport.</description>

<class>de.bit.firstspirit.xx.executables.Executable</class>

</public>

Das Executable rufe ich dann wie folgt aus einem Skript auf:

#!executable-class

de.bit.firstspirit.xx.executables.Executable

Innerhalb meines Executables hole ich mir dann den Service und starte ihn:

/**

* Initializes the executable with data out of the given parameters.

*

* @param params Parameters that are used to initializes the executable.

*/

void init(final Map<String, Object> params) {

this.paramMap = params;

this.context = (ScheduleContext) params.get(FS_SCRIPT_CONTEXT);

this.servicesBroker = this.context

.requestSpecialist(ServicesBroker.TYPE);

}

...

@Override public Object execute(final Map<String, Object> params) {

this.init(params);

final ProductImporterFSService service = this.servicesBroker

.getService(ProductImporterFSService.class);

service.import();

}

return null;

}

Evtl. hilft dir der Ansatz ja weiter...

Grüße

Sandro

0 Kudos

Hallo Sandro,

vielen Dank für deine Antwort, ich habe mal versucht das so umzusetzen, aber leider besteht der Fehler mit der Methode weiterhin.

Der ServicesBroker findet die Service Klasse nicht ServiceNotFoundException

Wieder funktioniert es, wenn ich den Workflow aus dem SiteArchitect aufzurufen, aber leider nicht über den ContentCreator

Auch nach Server neustart, hab ich das selbe Problem.

Beste Grüße

Dominik

0 Kudos
pavone
I'm new here

Hallo Dominik,

meine Vermutung ist, dass die Service-Klasse innerhalb der WebApp nicht bekannt ist, weil sie nicht als Resource angegeben wurde.

Wir haben ganz gute Erfahrungen damit gemacht, Services folgendermaßen zu implementieren:

  1. Wir definieren ein fachliches Interface für den Service, welches in einem separaten JAR abgelegt wird, welches serverweit bekannt gemacht wird (scope "server").
  2. Die Implementierung des Services liegt in einer anderen JAR, die lediglich modulweit bekannt ist (scope "module").
  3. Beide JARs werden auch in der WebApp hinzugefügt.

Die module.xml sieht also in etwa so aus:

<web-app scopes="global,project">

  <name>[...]</name>

  <web-xml>web/web.xml</web-xml>

  <web-resources>

    <resource>lib/global.jar</resource>

    <resource>lib/local.jar</resource>

  </web-resources>

</web-app>

<service>

  <name>[...]</name>

  <class>[...].MyServiceImpl</class>

</service>

<resources>

  <resource scope="server">lib/global.jar</resource>

  <resource scope="module">lib/local.jar</resource>

</resource>

Zum Finden des Services verwenden wir grundsätzlich nicht den Namen des Services, sondern das Interface:

servicesBroker.getService(MyService.class);

Vielleicht hilft dir die Information ja weiter.

Viele Grüße

Tim

0 Kudos

Hallo Tim,

das hat geholfen!

Mein Problem war, dass ich in der web-app <resources> anstatt <web-resources> definiert hab.

Die Resource mit scope="server" ist nicht mal nötig.

Beste Grüße,

Dominik

0 Kudos
MichaelaReydt
Community Manager

Hallo Dominik,

ist das Posting weiterhin offen? Benötigst du noch weitere Hilfe oder hat dir Tims Antwort geholfen? In diesem Fall wäre es super, wenn du seine "richtige Antwort" entsprechend markierst.

Oh, da hat sich etwas überschnitten. Mein Fehler. Smiley Happy

Viele Grüße

Michaela

0 Kudos

Nur noch mal zur Klarstellung, wegen einer Nachfrage in einem anderem Beitrag: Die Web-Komponente muss noch der Web-Applikation über den ServerManager hinzugefügt werden.

LG, Peter

Peter
0 Kudos