# Spring Remoting Architektur



## Gast2 (25. Okt 2010)

Hallo,

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.

Der Service benötigt das DAO. 
Bsp:

```
public class BaseServiceImpl{

@Autowired
private BaseDao baseDao;

}
```

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?

In der Doku hab ich nichts gefunden... Chapter17.Remoting and web services using Spring


----------



## Noctarius (25. Okt 2010)

Ein API-Projekt (Bundle) in welchem nur die Interfaces definiert sind. Dies kannst du in beiden Projekten einbinden.


----------



## Gast2 (25. Okt 2010)

Ah daran hab ich gar nicht gedacht, dass man implementierung und interface normal in 2 bundles aufteilen soll...
Mal ausprobieren ^^


----------



## Noctarius (25. Okt 2010)

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


----------



## Gast2 (25. Okt 2010)

Noctarius hat gesagt.:


> 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



Soweit hab ich noch nicht gedacht, solche Sachen habe ich (noch) nicht vor. Bin ja erst bei den Grundlagen 

Was genau ist Blueprint?Dass  spring xml dateien selbständig einliest und alles injeziert?


----------



## Noctarius (25. Okt 2010)

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.


----------



## Gast2 (25. Okt 2010)

Ah gut mal den Begriff gehört zu haben...


----------



## Noctarius (25. Okt 2010)

Hab bisher aber auch immer SpringDM genutzt, da unsere bisherigen Systeme schon darauf aufsetzen


----------



## Gast2 (25. Okt 2010)

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 ...


----------



## Gast2 (26. Okt 2010)

Okay ich mach dafür keinen neuen Thread auf:
Ich verstehe ein Problem nicht beim remoting nicht

Ich bekomme folgende Exception:

```
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(Unknown Source)
	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(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	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...

Also auf dem Server:

Service

```
@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public <T extends DBObject> List<T> findAll(DBObject eClass,Class<T> entityClass) {
		return baseDao.findAll(eClass.eClass(),entityClass);;
	}
```

DAO

```
public <T extends DBObject> List<T> findAll(EClass entityClass, Class<T> returnClass){
                // create query...


		List<T> list = query.getResultList();
		logger.info(list.toString());
		return new ArrayList<T>(list);
	}
```

Client:


```
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...


----------



## KSG9|sebastian (27. Okt 2010)

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 musst jede Collection intiailisieren...


----------



## Gast2 (27. Okt 2010)

KSG9|sebastian hat gesagt.:


> 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.


Ja ich will ja eben dem Problem aus dem weg gehen und eine "normale" ArrayList zurückgeben.

Und ich hab das eclipselink.weaving auf false gesetzt



KSG9|sebastian hat gesagt.:


> Du musst jede Collection intiailisieren...



Was meinst du mit intiailisieren?


----------



## Noctarius (27. Okt 2010)

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).


----------



## Gast2 (27. Okt 2010)

Noctarius hat gesagt.:


> 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).



Wo in der orm.xml oder in der persistence.xml?

Weil in der orm.xml werden die einzelene Attribute Eager geladen
Bsp.
[XML]
 <basic fetch="EAGER" name="preis" optional="true"/>
[/XML]

Das mit dem Datenverkehr ist mir bewusst, aber hab noch nirgends ein gescheiten Blog/Tutorial gefunden wie man LazyLoading mit einem RichClient macht.


----------



## Noctarius (27. Okt 2010)

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.


----------



## Gast2 (27. Okt 2010)

Okay gut zu wissen dass es mit Spring nicht geht.

Aber ich dachte wenn ich das weaving ausgeschalten habe dass eh nicht lazy geladen wird...


----------



## Noctarius (27. Okt 2010)

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).


----------



## Gast2 (27. Okt 2010)

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]

Edit: BTW meinst du das hier Apache ActiveMQ -- Spring Support


----------



## Gast2 (27. Okt 2010)

Vor allem check ich halt gar net warum wie er auf die teneo Liste kommt ... weil da es doch ne ArrayList ist...


----------



## Noctarius (27. Okt 2010)

Aus getResultList kommt eine andere Listenimplementierung als ArrayList, vermutlich die Teneo


----------



## Gast2 (27. Okt 2010)

Noctarius hat gesagt.:


> Aus getResultList kommt eine andere Listenimplementierung als ArrayList, vermutlich die Teneo



Hab ich auch gedachte kommt ein Vector raus aber ich speicher den ja extra nochmal in einen extra ArrayList deshalb versteh ich es ja nicht...


----------



## Noctarius (27. Okt 2010)

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.


----------



## Gast2 (28. Okt 2010)

Noctarius hat gesagt.:


> 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.



Ja aber ich hab das weaving ja ausgestellt, oder machen die Properties nichts?

Falls es nicht ausgestellt wäre wie kann ich so ein Problem angehen? Ich hab keine Idee wie ich das nun lösen kann?


----------



## Noctarius (28. Okt 2010)

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.


----------



## Gast2 (28. Okt 2010)

Noctarius hat gesagt.:


> 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.



An welcher Einstellung seh ich was ich benutze?


----------



## Noctarius (28. Okt 2010)

Du musst doch wissen, ob du beim Kompilieren (also im Ant- oder Maven-Descriptor) static weaving aktiviert hast.


----------



## Gast2 (28. Okt 2010)

Ä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.


----------



## Noctarius (28. Okt 2010)

Hmm ka wie die Target-Platform das macht.


----------



## Gast2 (28. Okt 2010)

mal im eclipse forum nachfragen vielleicht haben die eine idee...


----------



## Gelöschtes Mitglied 5909 (30. Okt 2010)

Du kannst einfach prüfen, ob die Klasse geweaved wurde:


```
if (object instanceof PersistenceWeaved) {
 // weaved
}
```

und zwar

org.eclipse.persistence.internal.weaving.PersistenceWeaved



> 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.



das stimmt aber so nich. Ich hab bei meinem Spring DM Projekt ein ähnliches Problem gehabt und weaving ausgestellt. 

Und ich bekomme keine Manipulierten Entities. 

[xml]
	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="dataSourceRef"></property>
		<property name="persistenceUnitName" value="org.java.forum.sample.entity"></property>
		<property name="jpaDialect">
			<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect"></bean>
		</property>
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"></bean>	
		</property>
		<property name="jpaProperties">
			<bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
				<property name="properties">
					<props>
						<prop key="eclipselink.weaving">false</prop>
					</props>
				</property>
			</bean>
		</property>
	</bean>
[/xml]

und 

[xml]
			<property name="eclipselink.weaving" value="false"/>
[/xml]

und FetchType.Eager

@SirWayne:

Ich hab dir doch mein Beispiel Projekt gegeben, da ist es auch deaktiviert.

Ich würde aber mal den debugger anschmeißen und schaun wie die Entities aussehen


----------



## Noctarius (30. Okt 2010)

Oh Tatsache, das kannte ich bisher noch gar nicht 

Hab mal ein wenig dazu gegoogled (schreibt man das so? ) Optimizing JPA Performance: An EclipseLink, Hibernate, and OpenJPA Comparison | Javalobby


----------



## Gast2 (30. Okt 2010)

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.


----------



## Gast2 (11. Nov 2010)

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?


----------

