ich hätte mal eine Architektur Frage!
Also kleines Beispiel :
Auf dem Server die Bundle für das remoting,service,DAO
Und auf dem Client: UI und der service.
Die beiden service bundles sind die gleichen.
Aber ich will ja jetzt auf dem Client nicht die ganzen DAO Bundle und dessen abhängigen Bundles mitausliefern. Wie ist sowas am besten gelöst? Muss ich noch ne extra Schicht anlegen?
Hat zusätzlich den Vorteil, dass du mit SpringDM (vermutlich auch bei den Blueprints) zur Laufzeit die Implementierung tauschen kannst, ohne dass das andere Bundle abgeschaltet werden muss, es werden im Hintergrund nur die Referenzen getauscht
Hat zusätzlich den Vorteil, dass du mit SpringDM (vermutlich auch bei den Blueprints) zur Laufzeit die Implementierung tauschen kannst, ohne dass das andere Bundle abgeschaltet werden muss, es werden im Hintergrund nur die Referenzen getauscht
SpringDM arbeitet Spring-AppContext XML Dateien ab, Blueprints ist die OSGi Spezifikation die dieses Konzept aufgreift und in OSGi 4.2 standardisiert aber nicht voll kompatibel zu den AppContext Files ist.
Ja wenns gut funktioniert würde ich es auch nicht austauschen ...
Also kann ja net viel dazu sagen hab bis jetzt nur SpringDm eingesetzt und klappt ganz gut.
Aber bin auch mal gespannt wie Eclipse E4 die deklarativen Services mit DI umsetzt. Wenn das das Client Framework schon alles mitbringt find ich es auch nicht schlecht.
EDIT: hat super geklappt die Trennung zwischen Interface und Impl Bundles. Nur noch Serializable Probleme mit EMF dann würde es glaub langsam funktionieren ...
Okay ich mach dafür keinen neuen Thread auf:
Ich verstehe ein Problem nicht beim remoting nicht
Ich bekomme folgende Exception:
Java:
org.springframework.remoting.RemoteAccessException:Could not deserialize result from HTTP invoker remote service [[url]http://localhost:8080/web/remoting/BaseService];[/url] nested exception is java.lang.ClassNotFoundException: org.eclipse.emf.teneo.eclipselink.elist.IndirectEList not found from bundle [emf-rcp]
at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.convertHttpInvokerAccessException(HttpInvokerClientInterceptor.java:208)
at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.invoke(HttpInvokerClientInterceptor.java:145)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy5.findAll(UnknownSource)
at handler.View$4.widgetSelected(View.java:151)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:234)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4066)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3657)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2640)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2438)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:671)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:664)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at emfrcp.Application.start(Application.java:20)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)
at sun.reflect.NativeMethodAccessorImpl.invoke(UnknownSource)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(UnknownSource)
at java.lang.reflect.Method.invoke(UnknownSource)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574)
at org.eclipse.equinox.launcher.Main.run(Main.java:1407)
at org.eclipse.equinox.launcher.Main.main(Main.java:1383)
Mein Client besitzt diese Klasse auch nicht das is korrekt: Aber ich verstehe nicht warum er diese überhaupt benötigt...
public<TextendsDBObject>List<T>findAll(EClass entityClass,Class<T> returnClass){// create query...List<T> list = query.getResultList();
logger.info(list.toString());returnnewArrayList<T>(list);}
Client:
Java:
List<DBObject> list = service.findAll(dbObject,DBObject.class);
Ich gebe doch eine normale ArrayList zurück warum will er diese auf die
org.eclipse.emf.teneo.eclipselink.elist.IndirectEList mappen? Versteh ich nicht...
Das liegt daran das Eclipselink (wie auch Hibernate) für Collections eine eigene Implementierung mitbringt. Hintergrund ist lazy-loading: Erst beim Zugriff auf die Collection werden die Elemente aus der Datenbank geladen.
Gibst du nun das "Eclipselink"-Set zum Client kann es dort nicht mehr deserialisiert werden. Und selbst wenn kommt es zu ner Exception das die Session schon geschlossen wurde.
Das liegt daran das Eclipselink (wie auch Hibernate) für Collections eine eigene Implementierung mitbringt. Hintergrund ist lazy-loading: Erst beim Zugriff auf die Collection werden die Elemente aus der Datenbank geladen.
Gibst du nun das "Eclipselink"-Set zum Client kann es dort nicht mehr deserialisiert werden. Und selbst wenn kommt es zu ner Exception das die Session schon geschlossen wurde.
Du kannst das Prefetching auf Eager einstellen, dann werden diese nicht mehr per Lazy-Loading nachgeladen sondern direkt mit (erzeugt halt oft unnötig Datenverkehr).
Du kannst das Prefetching auf Eager einstellen, dann werden diese nicht mehr per Lazy-Loading nachgeladen sondern direkt mit (erzeugt halt oft unnötig Datenverkehr).
LazyLoading mit RichClient wirst du nur über Interfaces und "virtuelle Instanzen" schaffen, z.B. mit SIMON. Das bedeutet der Server hat das echt Objekt und auf Clientseite wird jeder Aufruf gegen das Interface abgefangen und an den Server übermittelt, dort ausgeführt und das Ergebnis wandert zurück. Das geht aber eben nicht mit SpringRemote Implementierungen welche das Objekt selber versuchen zu serialisieren.
Das könnte schon sein, dass es mit Spring geht, immerhin ist SpringRemote ja nicht an eine Transfer-Implementierung gebunden. Ich hatte mal angefangen eine SpringRemote Implementierung für SIMON zu bauen, diese müsste ich nur mal an den aktuellen Stand anpassen (nehme ich mal an ).
Eventuell gibt es aber auch andere funktionierende Implementierungen für SpringRemote. Musst du einfach mal ein wenig schauen (ich glaube ActiveMQ macht das auch mit virtuellen Instanzen).
Ja für den Anfang würde es mir mal reichen wenn es mit dem SpringHTTInvoker klappen würde ...
also in der persistence.xml habe ich mit den folgenden Einstellungen versucht: Immer noch gleiches Problem.
[XML]
<property name="eclipselink.weaving" value="false"/>
<property name="eclipselink.weaving.eager" value="true"/>
<property name="eclipselink.cache.shared.default" value="false"/>
[/XML]
Vermutlich wird aber irgendwo intern eine andere Liste genutzt (die du nicht siehst). Bytecode-Enhancement fügt ja eben zusätzlichen Bytecode ein, das sogenannte Weaving.
Vermutlich wird aber irgendwo intern eine andere Liste genutzt (die du nicht siehst). Bytecode-Enhancement fügt ja eben zusätzlichen Bytecode ein, das sogenannte Weaving.
Es geht aber ohne Weaving nicht. Entweder nutzt du Runtime-Weaving mit einem speziellen Classloader (dann werden die Klassen beim Laden des Bytecodes erweitert) oder du hast das Static-Weaving an, dann werden sie direkt nach dem Kompilieren erweitert und der erweiterte Bytecode wieder in der Klasse gespeichert.
Es geht aber ohne Weaving nicht. Entweder nutzt du Runtime-Weaving mit einem speziellen Classloader (dann werden die Klassen beim Laden des Bytecodes erweitert) oder du hast das Static-Weaving an, dann werden sie direkt nach dem Kompilieren erweitert und der erweiterte Bytecode wieder in der Klasse gespeichert.
Ähm ich benutz beides nicht. Darum frag ich mich ja wo das passieren soll, weiß nicht ob EclipseLink selbst mach wenn er das DAO Bundle ausführt.
Ich starte einfach die launch Datei in Eclipse welchen Osgi container hochfährt und den jetty startet.
Dann hab ich zum Testen ein billiges Servlet welchen den Service aufruft und der das DAO.
Dann hab ich einen RCP zum Testen mit einer View der den gleichen Service aufruft nur wie gesagt die Liste nicht deseralisieren kann.
Es geht aber ohne Weaving nicht. Entweder nutzt du Runtime-Weaving mit einem speziellen Classloader (dann werden die Klassen beim Laden des Bytecodes erweitert) oder du hast das Static-Weaving an, dann werden sie direkt nach dem Kompilieren erweitert und der erweiterte Bytecode wieder in der Klasse gespeichert.
Ja wie gesagt weaving ist bei mir aus. Okay die Objekte in der Liste hab ich noch nicht angeschaut was da für Objekte drin sind.
Aber danke für den Tipp das könnte das Problem sein weil in den Objekten eine Liste drin sind vielleicht ist diese ja falsch. Aber ich verzichte nun eh auf Teneo und probier Texo aus sieht viel besser auf Server Seite aus.
Okay vielleicht hat hier einer mehr Erfahrung wie ich .
Ich hab auf der Server Seite generierte Pojos (Texo) und auf der Client Seite EMF-Models.
Ich benutzer wie oben erwähnt grad den Spring HTTPInvoker. Ich hab bis jetzt ein Interface für die rmote calls. Jetzt möchte ich anstatt die EMF Models zu serialisierenm die Serialisation mit xml machen?
Hat jemand eine Idee/Tutorial oder Erfahrung wie man sowas macht?