- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Modul kann nicht auf eigene Klassen zugreifen (scope=module)
Hallo zusammen,
ich habe ein Modul als globale Library. Das Modul stellt Klassen zur Verfรผgung, die ich in BeanShellSkripten nutzen mรถchte.
Diese Klassen sind in dem Modul in eine *-public.jar hinterlegt mit dem scope "server". Zusรคtzlich gibt es fรผr alle weiteren Klassen des Moduls eine *-private.jar mit dem scope "module". Diese enthรคlt bspw. externe Bibliotheken.
Die Skripte mรถchte ich vom JavaClient und vom WebClient aus aufrufen.
Jedoch werden die Klassen aus dem private.jar nicht gefunden vom Modul.
So sieht etwa meine module.xml aus:
<!DOCTYPE module SYSTEM "../../server/module.dtd">
<module>
<name>HLP Modul</name>
<version>1.0</version>
<description>HLP Modul</description>
<vendor>HLP Informationsmanagement GmbH</vendor>
<class>de.hlp.fsmodule.install.CommonsModule</class>
<components>
<library>
<name>HLP Modul SkriptLib</name>
<resources>
<resource>lib/modul-public.jar</resource>
<resource scope="module">lib/modul-private.jar</resource>
</resources>
</library>
</components>
</module>
In meinem BeanshellScript erzeuge ich eine neue Instanz einer Klasse aus dem public.jar, bspw. einen WebServiceClient:
WsClient client = WsClientFactory.getClient(settings.getSetting("ps_webservice_runtime").getValue());
Die Klassen WsClient und WsClientFactory liegen beide in der public-jar des Moduls. Sie nutzen dann weitere Bibliotheken, u.a. Jersey. Dort bekomme ich entsprechend folgende Fehlermeldung:
Target exception: java.lang.NoClassDefFoundError: com/sun/jersey/api/client/filter/ClientFilter
Diese Klasse ist im private.jar aber vorhanden. Verstehe ich hier die Funktionsweise der Scopes falsch? Eigtl. sollte doch die Klasse WsClient aus dem jar mit scope "server" auf die Klassen aus dem jar mit dem scope "module" zugreifen kรถnnen, oder?
Danke und Gruร
Felix
FS 5.0.606
Editiert: XML formatiert
- Labels:
-
Developers
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Die Hierachie ist anders herum, Scope "modul" kann auf Klassen aus Scope "server" zugreifen, nicht umgekehrt.
Klassen die in Skripten oder aus anderen Modulen bzw. Scopes benรถtigt werden, mรผssen im Scope "server" definiert werden.
Bei einem Service sollte nur die Schnittstelle im Scope "server" definiert werden, Implementierungsklassen sollten im Scope "modul" liegen.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hallo Peter,
vermutlich habe ich mich ein wenig umstรคndlich ausgedrรผckt. Genau so wie du es geschrieben hast mache ich es auch. Die Klassen die ich im Beanshell-Skript nutze liegen im public.jar mit dem scope "server", alle weiteren Klassen die dann diese Klassen nutzen liegen im private.jar. In meinem Beispiel war das:
Beanshell Skript:
WsClient client = WsClientFactory.getClient(settings.getSetting("ps_webservice_runtime").getValue());
WsClient und WsClientFactory liegen im public.jar
Die WsClient - Klasse kรถnnte bspw. vereinfacht so aussehen:
package de.hlp.firstspirit.ws;
import de.hlp.test.HalloWelt;
public class WsClient {
private HalloWelt hw = null;
public WsClient() {
hw = new HalloWelt();
}
}
HalloWelt liegt dann im private.jar, dass eine resource mit dem scope "module" ist.
Da die public.jar und die private.jar beides Ressourcen der gleichen Komponente des gleichen Moduls sind sollte WsClient doch auf HalloWelt zugreifen kรถnnen (und umgekehrt natรผrlich nicht), oder?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Wie ich schrieb, die Klassen aus einem "global" definiertem Scope kรถnnen nicht auf Klassen aus dem Scope "modul" zugreifen, auch nicht wenn sie aus dem gleichem Modul kommen.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ah, sorry. Ich sollte die Antworten mal besser lesen. D.h. ich brรคuchte entsprechend wieder ein Executable als Einstiegspunkt?
Dann werde ich nochmal kurz das ursprรผngliche Problem formulieren weshalb ich รผberhaupt auf dieses Thema gekommen bin. Wir verwenden in zwei Modulen die gleiche Library (javax.ws). Bisher hatten wir in Modul 1 nur eine Library mit einer *.jar, die alle Klassen enthรคlt (inkl. javax.ws):
<library>
<name>Modul1 Lib</name>
<resources>
<!-- enthรคlt eigene Klassen und die dazu benรถtigten Bibliotheken, wie z.B. javax.ws -->
<resource>lib/modul1-jar-with-dependencies.jar</resource>
</resources>
</library>
Das Modul 2 besteht aus einer Library und einer Web-App in der zwei jars enthalten:
<components><web-app scopes="project"><name>Modul 2 WebApp</name><version>1.0</version><description>Modul 2 WebApp</description><class>de.hlp.allstar.firstspirit.Modul2App</class><web-xml>web.xml</web-xml><web-resources><resource scope="module">lib/modul2-private.jar</resource> <!-- enthรคlt die benรถtigten Bibliotheken u.a. javax.ws --><resource scope="module">lib/modul2-public.jar</resource> <!-- enthรคlt eigene Klassen --></web-resources></web-app><library><name>Modul2 Lib</name><description>Modul 2</description><resources><resource scope="module">lib/modul2-private.jar</resource> <!-- enthรคlt die benรถtigten Bibliotheken u.a. javax.ws --><resource>lib/modul2-public.jar</resource> <!-- enthรคlt eigene Klassen --></resources></library></components>
Nach deiner Erklรคrung ist mir eigtl. klar, wie das Verhalten dieser Module sein mรผsste abe rnicht klar, wieso es sich bei uns wie folgt verhรคlt:
Wir haben ein Skript, dass an 3 Stellen ausgefรผhrt wird und eine Klasse erzeugt die in Modul 1 liegt. Diese Klasse nutzt im Hintergrund Klassen von javax.ws.
Das Skript wird im JavaClient รผber einen Button gestartet und funktioniert.
Das Skript wird im WebClient auf einer Seite per JavaScript รผber WE_API.Common.execute ausgefรผhrt und funktioniert.
Das Skript wird im WebClient in einem Formular zur Anlage eines Datensatzes per Button gestartet und schmeiรt eine ClassLoader-Exception:
Target exception: java.lang.LinkageError: ClassCastException: attempting to
castjar:file:/C:/FirstSpirit5/work/jetty-fs5webedit_269745/webinf/WEB-INF/lib/modul2-private.jar!/javax/ws/rs/ext/RuntimeDelegate.class
to
jar:file:/C:/FirstSpirit5/work/ModuleManager/Modul1_79f4545d/lib/modul1-jar-with-dependencies.jar!/javax/ws/rs/ext/RuntimeDelegate.class
(Habe die Pfade und Namen mal etwas zusammengekรผrzt).
Das JavaClient und WebClient sich unterscheiden ist fรผr mich klar, da im WebClient das Modul2 in der WebApp installiert ist.
Aber wieso gibt es hier ein unterschiedliches Verhalten zwischen WebClient per JS und WebClient per Formular?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hast du die Mรถglichkeit, das mit einer aktuellen FirstSpirit 5.1 Version zu testen? Oder alternativ in einem Tomcat statt mit dem internem Jetty?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Peter,
habe hier jetzt verschiedene Stรคnde.
Auf dem 5.1er System ist es ebenfalls, wie oben beschrieben.
Nun habe ich noch lokal bei mir eine Kopie des Ganzen auf einem 5.0.606er System installiert und hier funktionieren beide WebClient - Variante nicht! Wie wรคre denn das richtige Verhalten? Ich kann das dann nochmal probieren mit einem Tomcat nachzuvollziehen. Ich nehme ja mal an, dass Problem kommt daher, dass die Libs der WebApp natรผrlich unter WEB-INF/libliegen und der WebServer ja nicht "weiร", dass die den scope "module" haben und somit nicht von auรen zugreifbar sind, oder?
Ich teste aber nochmal mit dem Tomcat.
Gruร
Felix
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hallo Felix,
ich habe mir nochmal Gedanken zu dem ClassLoader-Error gemacht. Grundsรคtzlich sind im Modul-Kontext FAT-Jars eine schlechte Idee, was man auch an dem Error sehen kann (Error != Exception).
FirstSpirit bzw. Java hat hier per ClassLoader keine Chance zu erkennen, dass sich auf dem Class-Path eine doppelte Definition befindet. Dein Modul 1 ist รถffentlich und somit auch im Kontext des Modul 2 lesbar. Je nachdem wie die Klassen auflรถst werden bzw. wie im Verlauf des Programmablaufs die Klassen auflรถst werden, kommt es zum Konflikt. Dabei "weiร" Java nur, dass der sog. Full-Qualified-Name der Klasse identisch ist. Theoretisch kรถnnten das inhaltlich vรถllig verschiedene Klassen sein. Aus diesem Grund wird ein Error und keine Exception geworfen.
Mรถgliche Lรถsungen:
1. Fremdbibliotheken nach Mรถglichkeit nur Modul-Lokal belassen (Dabei wenn mรถglich den Originalnamen verwenden, wie dieser z.B. via Maven vergeben wird). Zusรคtzlich sollte man an den Resource-Tags das Attribut Version setzen (siehe Kaptiel 2.5.1.1 des Modulentwicklerhandbuchs).
2. Wenn man schon eine Fremdbibliothek als Library-Modul in FirstSpirit verwendet, dann darf man in seinen anderen Modulen die gleichen Packages und Java-Klassen nicht mehr mitliefern, vor allem nicht in FAT-Jars. Man sollte dann auch eine Modul-Abhรคngigkeit eintragen (siehe Kapitel 3.8 des Modulentwicklerhandbuchs), damit der Fall abgefangen wird, dass das Libraray-Modul vor den anderen Modulen deinstalliert wird.
Ich hoffe ich konnte Dir weiterhelfen.
Grรผรe
Marian Zaplatynski
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Marian,
danke fรผr die Antwort und die Tipps.
Dann werden wir wohl bei uns im Produkt jetzt einiges umstellen mรผssen ๐
Gruร
Felix

