Archive
Eclipse RCP/RAP and Remoting with JAX-RS, Spring Data JPA and CXF DOSGi [step2]
In [step1] we have downloaded CXF DOSGi « Multi Bundle Distribution » and created the fr.opensagres.remoting.exporter.dosgi.jaxrs bundle
to export on server side the UserService#findAll() with JAX-RS:
@Path("/user")
public interface UserService {
@GET
@Path("/findAll")
@Produces(MediaType.APPLICATION_JSON)
Collection<User> findAll();
...
}
In this article we will create the importer bundle fr.opensagres.remoting.importer.dosgi.jaxrs which will create a JAX-RS Client with Spring bean :
<jaxrs:client id="jaxrsUserService" address="http://127.0.0.1:9000/fr/opensagres/services/UserService" serviceClass="fr.opensagres.services.UserService" inheritHeaders="true"> </jaxrs:client>
and will register this JAX-RS Client in the OSGi register services as UserService :
<osgi:service ref="jaxrsUserService" interface="fr.opensagres.services.UserService" />
For recall, the Simple Client bundle fr.opensagres.simpleclient consumes a UserService in the Thread FindAllUsersThread from the OSGi registry services and display User list every 5 seconds. In our case the UserService instance will be the JAX-RS Client retrieved from the OSGi registry services :
<osgi:reference id="userService" interface="fr.opensagres.services.UserService" cardinality="0..1" timeout="1000" />
This JAX-RS Client UserService will be setted in the FindAllUsersThread with Dependency Injection :
<bean id="FindAllUsersThread" class="fr.opensagres.simpleclient.FindAllUsersThread" init-method="start" destroy-method="interrupt"> <property name="userService" ref="userService"></property> </bean>
This FindAllUsersThread (client side) consumes the UserService#findAll() every 5 seconds to display user list on the console :
// 1) findAll
users = userService.findAll();
displayUsers("findAll", users);
Eclipse RCP/RAP and Remoting with JAX-RS, Spring Data JPA and CXF DOSGi [step1]
The Eclipse RCP/RAP with Spring DM, Spring Data JPA and Remoting [step11] article explains that we wish to manage remoting for UserService :
package fr.opensagres.services;
import java.util.Collection;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import fr.opensagres.domain.User;
public interface UserService {
Collection<User> findAll();
Page<User> findAll(Pageable pageable);
Collection<User> findByFirstNameLikeAndLastNameLike(String firstName,
String lastName);
Page<User> findByFirstNameLikeAndLastNameLike(String firstName,
String lastName, Pageable pageable);
User saveUser(User user);
}
- the server side will export the UserService which retrieves User from Database with JPA.
- the client side, RCP Application, RAP Application and OSGi Bundle Activator will import the UserService to consume the exported UserService.
In this article I will explain how to manage remoting with CXF DOSGi with JAX-RS. DOSGi Releases provides 2 distributions:
- Multi Bundle Distribution: This distribution is a zip file containing the Distributed OSGi bundles, as well as all their dependencies.
- Single Bundle Distribution: This is a convenience distribution of a single bundle that embeds all the dependencies.
In our case we will use « Multi Bundle Distribution » which is more complex to use it than « Single Bundle Distribution », but we need to do that because we have already Spring DM.
When I have used CXF DOSGi to manage remoting with our UserService, I have met several problems :
- « Multi Bundle Distribution » is very hard to use, because you need install a lot of bundles and set the Auto-Start to true for some bundles.
- Using JAX-RS was not simply with the UserService because it uses Spring Data Page and Pageable interfaces (and not Pojo).
I will explain that in the Eclipse RCP/RAP and Remoting with JAX-RS, Spring Data JPA and CXF DOSGi articles. In this article we will export the UserService#findAll() with JAX-RS:
package fr.opensagres.services;
import java.util.Collection;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import fr.opensagres.domain.User;
@Path("/user")
public interface UserService {
@GET
@Path("/findAll")
@Produces(MediaType.APPLICATION_JSON)
Collection<User> findAll();
...
}
On other words, we will
- Install CXF DOSGi by downloading the well JARS bundles.
- Use JAX-RS annotation for UserService and JAXB annotation for User domain.
- Create the exporter services bundle (server side) to export the UserService with JAX-RS.
Eclipse RCP/RAP with Spring DM, Spring Data JPA and Remoting [step11]
In [step10] we have created RAP Application from the RCP Application. At this step we have several Client Layer :
- OSGi Bundle Activator (simpleclient)
- RCP Application
- RAP Application
which consumes Service Layer : UserService (from Mock Dao, JPA Dao) to retrieve list of User :
package fr.opensagres.services;
import java.util.Collection;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import fr.opensagres.domain.User;
public interface UserService {
Collection<User> findAll();
Page<User> findAll(Pageable pageable);
Collection<User> findByFirstNameLikeAndLastNameLike(String firstName,
String lastName);
Page<User> findByFirstNameLikeAndLastNameLike(String firstName,
String lastName, Pageable pageable);
User saveUser(User user);
}
Here, The Client and Service Layer are in the same OSGi container. Now we wish manage Client/Server architecture to have :
- Client Layer in an OSGi container
- Service Layer in an other OSGi container
the Client Layer will consume Service Layer with remoting mean.
Eclipse RCP/RAP with Spring DM, Spring Data JPA and Remoting [step10]
In [step9] we have displayed the User List with pagination by using Nebula Pagination Control and Spring Data JPA. As Nebula Pagination Control supports RAP, it’s possible with few modifications of the fr.opensagres.richclient to support WEB mode too with Eclipse RAP:
At the end of this article we will have an Application which supports:
- Desktop context with Eclipse RCP:
- WEB context with Eclipse RAP :
The sources of the fr.opensagres.richclient Plug-In will be the same: it’s called Single-Sourcing.
Eclipse RCP/RAP with Spring DM, Spring Data JPA and Remoting [step9]
In [step8] we have developed a Rich Client with RCP Application to display User list in a SWT Table by consuming the UserService by using Spring DM by using the SpringExtensionFactory from Martin Lippert.
In this article we will display the User List with pagination by using Nebula Pagination Control.

The sort of column will be done by the UserService by using Spring Data Sort Structure:

Eclipse RCP/RAP with Spring DM, Spring Data JPA and Remoting [step8]
In [step7] we have seen how to use Spring Data JPA to add custom methods to the Dao to manage criteria and pagination.
In this article we will implement a Rich Client with RCP Application to display User list in a SWT Table :

We will see how to we can consume the UserService by using Spring DM by using the SpringExtensionFactory from Martin Lippert.
Eclipse RCP/RAP with Spring DM, Spring Data JPA and Remoting [step7]
In [step6] we have implemented the API Dao UserDao with JPA by using Spring Data JPA :
- the API Dao fr.opensagres.dao.UserDao extends the Spring Data org.springframework.data.repository.PagingAndSortingRepository.
- the JPA User Dao implementation is created on runtime by Spring Data JPA by declaring a jpa:repository:
<!-- Spring Data JPA--> <jpa:repositories base-package="fr.opensagres.dao"> <jpa:repository id="userDao" /> </jpa:repositories>
At this step the UserDao provides the CRUD methods and pagination methods for User entity like :
- Iterable findAll(): to find all entity.
- T save(T model): to save an entity.
- Page findAll(Pageable pageable): to find all entity with pagination.
With Spring Data JPA, it’s possible to add your own method to manage search entities by criteria : to do that the method name of the UserDao must just follow some convention name (see Query creation for more information). In this article we will add the 2 following methods to the UserDao :
- findByFirstNameLikeAndLastNameLike to retrieve a list of User by first name (like) and last name (like):
List<User> findByFirstNameLikeAndLastNameLike(String firstName, String lastName);
- findByFirstNameLikeAndLastNameLike to retrieve a list of User by first name (like) and last name (like) with pagination:
Page<User> findByFirstNameLikeAndLastNameLike(String firstName, String lastName, Pageable pageable);
Just add those 2 methods to UserDao API and Spring Data JPA will manage for you the JPA implementation!
Eclipse RCP/RAP with Spring DM, Spring Data JPA and Remoting [step6]
In [step5] we have prepared the Target Platform with:
- The JPA API.
- EclipseLink used as JPA Implementation
- Derby used as Database.
- Commons DBCP used as connection pool.
- Spring Data JPA to implement our DAO with JPA.
The API Dao fr.opensagres.dao.UserDao extends the Spring Data org.springframework.data.repository.PagingAndSortingRepository interface which is the first step to use Spring Data JPA.
In this article we will create several bundles/fragment to retrieves User list from a Database Derby with EclipseLink JPA. The JPA Dao implementation will be done with Spring Data JPA, on other words, you will do nothing (no need to code a JPAUserDao class). We will create 2 bundles and 1 fragment :
- fr.opensagres.dao.jpa the bundle implementation of UserDao with JPA by using Spring Data JPA to avoid coding the JPAUserDao class.
- fr.opensagres.dao.jpa.eclipselink the fragment which configures the JPA fr.opensagres.dao.jpa to use EclipseLink and Deby as dialect.
- fr.opensagres.data.datasource the bundle which publishes the Derby Datasource used by the fr.opensagres.dao.jpa.
Eclipse RCP/RAP with Spring DM, Spring Data JPA and Remoting [step5]
In [step4] we have created DAO layer with Mock implementation. In this article we will start to explains how to implement DAO with JPA to use Database. We will use:
- EclipseLink as JPA Implementation
- Derby as Database.
- Spring Data JPA to implement our DAO with JPA. Spring Data gives some DAO interface like org.springframework.data.repository.PagingAndSortingRepository which provides several CRUD methods like :
- Iterable findAll(): to find all entity.
- T save(T model): to save an entity.
- Page findAll(Pageable pageable): to find all entity with pagination.
The basic idea of Spring Data JPA is extends this interface in your DAO, and you not need to implements this methods with JPA query. It’s the goal of Spring Data JPA.
But it’s very long to explain how to configure and creates bundles to do that. So I decided to split the explanation into 2 articles :
- [step5]: explains how to download Spring Data JPA, use Java Spring Data Structure in our Mock and API DAO, and configure the OSGi launch.
- [step6]: explains how to create and configure bundles to use Spring Data JPA with EclipseLink and Derby.
Eclipse RCP/RAP with Spring DM, Spring Data JPA and Remoting [step4]
In [step3] we have developed a Simple Client bundle which consumes the UserService from the OSGi services registry to display a list of User in the console. So we have seen how to:
- consume service with Spring DM <osgi:reference.
- publish service with Spring DM <osgi:service.
At this step we have a service layer. Now we can add Dao layer (Some people prefer merge services/dao layer, but in our case I prefer do that to have a facade and it will help us when remoting with REST will be done) to retrieve User data from Database. To do that we will use :
- EclipseLink as JPA implementation.
- Spring Data JPA which is great help to integrate JPA with Spring.
Before doing that, I would like show you an idea that we have done in our Eclipse RCP/RAP XDocReport application. We are 2 developers and when we wanted to integrate JPA as Dao implementation we would like continue to work together on 2 tasks :
- one developer integrates Dao JPA implementation with EclipseLink and Spring Data JPA (an hard task when you don’t know very well those technologies).
- one developer continues to develop the application: business services, UI components, etc…
The idea was been to integrate DAO API (very easy task) in our services layer and uses Mock Dao. So we have :
- a Mock Dao implementation layer: which works with Java Map.
- a JPA Dao implementation layer: which works with EclipseLink and Spring Data JPA.
Mock Dao was easy to develop (you will see that in this article) and once time UserDao API was finished, we can work on our own task (one task for JPA and one task for continue the development of the application) without disturb. You can tell me, yes it’s a classic mean to use Mock object.
But the second problem was Data. To inject data (ex: in our case User data) :
- for Mock Dao, Data is managed with Java.
- for JPA Dao, Data is managed with SQL scripts…
However JPA gives you the capability to generate Database by using the JPA annotation of the Domain classes (without SQL scripts). What is about data? So we tell us, why we cannot use ours services save method to inject data? For instance in our case we could call UserService#saveUser(User user) which uses Dao (Mock or JPA) somewhere to inject our users :
- it will work for Mock Dao.
- it will work for JPA Dao.
But where can we do that? The idea is very simple. We have created a new bundle « datainjector » with a DataInjector class which consumes service to inject Data. For instance in our case we could have that :
public class DataInjector {
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
public void inject() {
userService.saveUser(new User("Angelo", "Zerr"));
...
}
}
In this article we will do that :
- add API Dao layer used in the Services Implementation.
- implement DAo with Mock (Java Map).
- inject User data in a « datainjector » bundle which will use the UserService.