Spring Beans accessable via IEclipseContext [message #1771158] |
Tue, 22 August 2017 10:54  |
Eclipse User |
|
|
|
Hello!
I have an e4 RCP application and want to connect to a database.
I have a spring configured datasource, a DAO bean and a service bean like:
MyService --> MyDao --> Datasource
The goal is to get the MyService injected into my e4 UI classes (Parts, Handler etc.)
What is the best way to get this done?
First idea was to make the MyService bean available in OSGi since OSGi services are available through e4 context. What I found was Spring DM but, this is not supported anymore. Next was Gemini Blueprint but seems to be not supported with Spring 4, is it?
Is there another way to declare a spring bean as an OSGi service?
Or can I define an OSGI declarative service in my e4 application and make it available as a bean in my Spring Plugin?
Or is Spring/e4 a bad tandem? How else can I connect to a database from e4 RCP by having the advantages of Spring?
Thanks in advance,
Gernot.
|
|
|
|
|
|
|
|
|
|
Re: Spring Beans accessable via IEclipseContext [message #1772168 is a reply to message #1771766] |
Wed, 06 September 2017 05:19  |
Eclipse User |
|
|
|
Hi all,
meanwhile I have a running solution for my problem statement above I maybe you are interested what it is? On the other hand I appreciate your comments on weaknesses or further improvements.
So, how does my setup look now:
General setup:
- Eclipse Neon.3 (4.6.3) as IDE and target platform
- Springframework 4.3.0
- external bundle: org.eclipse.equinox.weaving.hook-1.1.200.jar
Client (e4 RCP):
- Registered a DataClientService via IContextFunction. This services requires the DataRemoteService via @Inject
Remote bundles:
- one bundle with domain model --> annotated entities (no dependencies and no Spring)
- one Spring enabled bundle (dependencies to Springframework and domain bundle)
The Spring bundle:
- has an Activator that on bundle start():
1. creates the Spring context
2. fetches the remote services from Spring context
3. registers the remote services in OSGi context
- at bundle stop()
1. remembers the services and unregisters them
2. closes the Spring context
- implementation like this:
public class CoreActivator implements BundleActivator {
private ApplicationContext springContext;
private List<ServiceRegistration<?>> serviceRegister = new ArrayList<ServiceRegistration<?>>();
@Override
public void start(BundleContext bundleContext) throws Exception {
// Get data remote service and register to OSGi
DataRemoteService dataRemoteService = (DataRemoteService) getContext().getBean("dataRemoteService");
ServiceRegistration<DataRemoteService> registration = bundleContext.registerService(DataRemoteService.class, dataRemoteService, null);
serviceRegister.add(registration);
}
@Override
public void stop(BundleContext bundleContext) throws Exception {
// Unregister all services
serviceRegister.forEach(s -> s.unregister());
// Close spring context
if (springContext instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) springContext).close();
}
}
private synchronized ApplicationContext getContext() {
if (springContext == null) {
Thread currentThread = Thread.currentThread();
ClassLoader originalClassloader = currentThread.getContextClassLoader();
try {
currentThread.setContextClassLoader(this.getClass().getClassLoader());
springContext = new ClassPathXmlApplicationContext("spring-config.xml");
} finally {
currentThread.setContextClassLoader(originalClassloader);
}
}
return springContext;
}
}
- the spring-config.xml is in /META-INF/spring
- it configures the DataRemoteService as a simple bean and gets the entity manager injected
- additionally, you need to create 2 more files in /META-INF:
1. spring.schemas
2. spring.handlers
- in these 2 files I copied and merged all rows from the respective files that are in the /META-INF folder of each of the org.springframework.xyz_123.jar files that I added as dependency to my bundle (.aop, .core, .beans, ...)
So, whenever my UI client requires the DataClientService it is created via e4 context function. Since this service requires the DataRemoteService the spring bundle is activated, creates the Spring context and registers all remote services to OSGI. These remote services are then inject to my client service.
With this setup I was able to receive and store object from and to the database.
What is still not running now is the load time weaving...
I found a tutorial here: https://angelozerr.wordpress.com/2010/04/30/springweaver_step1
I tried it and meanwhile it runs without errors but my domain class seems not to be weaved, i.e. it is not instanceof org.eclipse.persistence.internal.weaving.PersistenceWeaved.
My entity manager factory configuration in the spring-config.xml looks like this:
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
<property name="packagesToScan" value="${jpa.entity.packages}" />
<property name="persistenceUnitName" value="myPU"/>
<property name="loadTimeWeaver">
<bean class="org.eclipse.equinox.weaving.springweaver.EquinoxAspectsLoadTimeWeaver">
<property name="weaverScope" value="APPLICATION" />
</bean>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="eclipselink.weaving" value="true"/>
</map>
</property>
</bean>
Any hint regarding load time weaving?
Please let me know what you think.
Thanks and regards,
Gernot.
|
|
|
Powered by
FUDForum. Page generated in 0.04835 seconds