Accueil > Apache CXF, DOSGi > Eclipse RCP/RAP and Remoting with JAX-RS, Spring Data JPA and CXF DOSGi [step1]

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

Download

To follow this article you can

Download before starting

Before starting this article, please download eclipsespring_step10.zip
which contains the domain, services, dao bundles and RCP, RAP OSGi Bundles client explained in the Eclipse RCP/RAP with Spring DM, Spring Data JPA and Remoting [step10].

To use this zip with Eclipse RCP, unzip it :

  1. import those projects in a workspace.
  2. open the TargetPlatform/eclipsespring.target file and click on Set as Target Platform. If you have problem with Target Definition, please read Problem with Install with Nebula (Incubation) P2.
  3. select TargetPlatform/launch/Simple OSGi client.launch – Mock Dao to test the launch with Mock Dao and Run it.
  4. select TargetPlatform/launch/Simple OSGi client.launch – JPA Dao to test the launch with JPA Dao and Run it.
  5. select TargetPlatform/launch/RCP Client – Mock Dao.launch to test the RCP Application with Mock Dao and Run it.
  6. select TargetPlatform/launch/RCP Client – JPA Dao.launch to test the RCP Application with JPA Dao and Run it.

Download at end

To use the eclipse_spring_dosgi_step1.zip unzip it :

  1. import those projects in a workspace.
  2. open the TargetPlatform/eclipsespring.target file and click on Set as Target Platform. If you have problem with Target Definition, please read Problem with Install with Nebula (Incubation) P2.
  3. select TargetPlatform/launch/Server Remoting – JAXRS DOSGi – JPA Dao.launch to test the Remoting UserService JAX-RS with Mock Dao and Run it.
  4. select TargetPlatform/launch/Server Remoting – JAXRS DOSGi – JPA Dao.launch to testthe Remoting UserService JAX-RS with JPA Dao and Run it.

TargetPLatform & CXF DOSGi

DOSGi releases provides zip that you can download. But if you wish JAX-RS, pay attention you must download at hand Jettison JAR that it is not included in the zip. In our case we will use Maven to download CXF DOSGi and their dependencies.

Download CXF DOSGi

  • delete the TargetPlatform/lib folder.
  • Modify the pom.xml to download CXF DOSGi JARs, and their dependencies (see « Remoting with DOSGi CXF » comments) like this :
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<groupId>fr.opensagres.samples</groupId>
    	<artifactId>fr.opensagres.samples.targetplatform</artifactId>
    	<packaging>pom</packaging>
    	<version>0.0.1-SNAPSHOT</version>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-dependency-plugin</artifactId>
    				<version>2.1</version>
    				<executions>
    					<execution>
    						<id>copy-dependencies</id>
    						<phase>process-resources</phase>
    						<goals>
    							<goal>copy-dependencies</goal>
    						</goals>
    						<configuration>
    							<outputDirectory>lib</outputDirectory>
    							<overWriteReleases>true</overWriteReleases>
    							<overWriteSnapshots>true</overWriteSnapshots>
    							<overWriteIfNewer>true</overWriteIfNewer>
    						</configuration>
    					</execution>
    				</executions>
    			</plugin>
    		</plugins>
    	</build>
    
    	<properties>
    		<spring.dm.version>1.2.1</spring.dm.version>
    		<slf4j.version>1.6.1</slf4j.version>
    		<org.aopalliance>1.0.0</org.aopalliance>
    		<spring.data.jpa>1.0.3.RELEASE</spring.data.jpa>
    		<annotation.version>1.0.1</annotation.version>
    		<jpa.version>1.1</jpa.version>
    		<eclipselink>2.3.0</eclipselink>
    		<commons.dbcp>1.2.2.osgi</commons.dbcp>
    		<database.derby>10.5.1000001.764942</database.derby>
    		<cxf.version>2.5.2</cxf.version>
    		<cxf.dosgi.version>1.3.1</cxf.dosgi.version>
    		<servicemix.specs.version>1.9.0</servicemix.specs.version>		
    	</properties>
    
    	<repositories>
    
    		<repository>
    			<id>spring-maven-milestone</id>
    			<name>Springframework Maven Repository</name>
    			<url>http://maven.springframework.org/milestone</url>
    		</repository>
    
    		<repository>
    			<id>com.springsource.repository.bundles.external</id>
    			<name>SpringSource Enterprise Bundle Repository - External Bundle Releases</name>
    			<url>http://repository.springsource.com/maven/bundles/external</url>
    		</repository>
    
    		<repository>
    			<id>EclipseLink Repo</id>
    			<url>http://download.eclipse.org/rt/eclipselink/maven.repo</url>
    		</repository>
    
    	</repositories>
    
    	<dependencies>
    
    		<!-- Spring DM -->
    		<dependency>
    			<groupId>org.springframework.osgi</groupId>
    			<artifactId>spring-osgi-extender</artifactId>
    			<version>${spring.dm.version}</version>
    			<exclusions>
    				<exclusion>
    					<groupId>org.springframework</groupId>
    					<artifactId>*</artifactId>
    				</exclusion>
    			</exclusions>
    		</dependency>
    
    		<!-- API logger: Commons Logging required by Spring DM -->
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>com.springsource.slf4j.org.apache.commons.logging</artifactId>
    			<version>${slf4j.version}</version>
    			<scope>provided</scope>
    		</dependency>
    
    		<!-- Implementation logger: log4j -->
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>com.springsource.slf4j.log4j</artifactId>
    			<version>${slf4j.version}</version>
    			<scope>provided</scope>
    		</dependency>
    
    		<!-- OSGi AOP Alliance (need do that since we have exclude org.springframework) -->
    		<dependency>
    			<groupId>org.aopalliance</groupId>
    			<artifactId>com.springsource.org.aopalliance</artifactId>
    			<version>${org.aopalliance}</version>
    		</dependency>
    
    		<!-- Spring Data JPA -->
    		<dependency>
    			<groupId>org.springframework.data</groupId>
    			<artifactId>spring-data-jpa</artifactId>
    			<version>${spring.data.jpa}</version>
    		</dependency>
    
    		<!-- API : javax.annotation -->
    		<dependency>
    			<groupId>org.apache.geronimo.specs</groupId>
    			<artifactId>geronimo-annotation_1.1_spec</artifactId>
    			<version>${annotation.version}</version>
    		</dependency>
    		
    		<!-- API JPA: annotation -->
    		<dependency>
    			<groupId>org.apache.geronimo.specs</groupId>
    			<artifactId>geronimo-jpa_2.0_spec</artifactId>
    			<version>${jpa.version}</version>
    		</dependency>
    
    		<!-- Implementation JPA: EclipseLink -->
    		<dependency>
    			<groupId>org.eclipse.persistence</groupId>
    			<artifactId>org.eclipse.persistence.jpa</artifactId>
    			<version>${eclipselink}</version>
    		</dependency>
    
    		<!-- Database Connection Pool -->
    		<dependency>
    			<groupId>org.apache.commons</groupId>
    			<artifactId>com.springsource.org.apache.commons.dbcp</artifactId>
    			<version>${commons.dbcp}</version>
    		</dependency>
    
    		<!-- Database Derby -->
    		<dependency>
    			<groupId>org.apache.derby</groupId>
    			<artifactId>com.springsource.org.apache.derby</artifactId>
    			<version>${database.derby}</version>
    		</dependency>
    
    		<!-- Remoting with DOSGi CXF -->
    		
    		<dependency>
    			<groupId>org.apache.cxf</groupId>
    			<artifactId>cxf-bundle-minimal</artifactId>
    			<version>${cxf.version}</version>
    			<exclusions>
    				<exclusion>
    					<groupId>org.springframework</groupId>
    					<artifactId>*</artifactId>
    				</exclusion>
    			</exclusions>
    		</dependency>
    
    		<dependency>
    			<groupId>org.apache.cxf.dosgi</groupId>
    			<artifactId>cxf-dosgi-ri-discovery-local</artifactId>
    			<version>${cxf.dosgi.version}</version>
    			<exclusions>
    				<exclusion>
    					<groupId>org.springframework</groupId>
    					<artifactId>*</artifactId>
    				</exclusion>
    			</exclusions>
    		</dependency>
    
    		<dependency>
    			<groupId>org.apache.cxf.dosgi</groupId>
    			<artifactId>cxf-dosgi-ri-dsw-cxf</artifactId>
    			<version>${cxf.dosgi.version}</version>
    			<exclusions>
    				<exclusion>
    					<groupId>org.springframework</groupId>
    					<artifactId>*</artifactId>
    				</exclusion>
    			</exclusions>
    		</dependency>
    
    		<dependency>
    			<groupId>org.apache.cxf.dosgi</groupId>
    			<artifactId>cxf-dosgi-ri-topology-manager</artifactId>
    			<version>${cxf.dosgi.version}</version>
    			<exclusions>
    				<exclusion>
    					<groupId>org.springframework</groupId>
    					<artifactId>*</artifactId>
    				</exclusion>
    			</exclusions>
    		</dependency>
    
    		<dependency>
    			<groupId>org.apache.servicemix.bundles</groupId>
    			<artifactId>org.apache.servicemix.bundles.xmlresolver</artifactId>
    			<version>1.2_5</version>
    		</dependency>
    
    		<dependency>
    			<groupId>org.apache.servicemix.bundles</groupId>
    			<artifactId>org.apache.servicemix.bundles.opensaml</artifactId>
    			<version>2.5.1_2</version>
    		</dependency>
    
    		<dependency>
    			<groupId>org.apache.servicemix.bundles</groupId>
    			<artifactId>org.apache.servicemix.bundles.wsdl4j-1.6.1</artifactId>
    			<version>4.0-m1</version>
    		</dependency>
    
    		<dependency>
    			<groupId>org.apache.servicemix.specs</groupId>
    			<artifactId>org.apache.servicemix.specs.saaj-api-1.3</artifactId>
    			<version>${servicemix.specs.version}</version>
    		</dependency>
    
    		<dependency>
    			<groupId>org.apache.servicemix.specs</groupId>
    			<artifactId>org.apache.servicemix.specs.jaxb-api-2.2</artifactId>
    			<version>${servicemix.specs.version}</version>
    		</dependency>
    
    		<dependency>
    			<groupId>org.apache.servicemix.specs</groupId>
    			<artifactId>org.apache.servicemix.specs.jsr311-api-1.1.1</artifactId>
    			<version>${servicemix.specs.version}</version>
    		</dependency>
    		
    	</dependencies>
    
    </project>
    
  • Open a dos/sh command, go to the folder TargetPlaform and launch mvn like this (or use M2Eclipse) :
    mvn process-resources
  • this command download CXF DOSGi JARs and their dependencies and copy it to the TargetPlatform/lib folder. Once maven has finished, refresh TargetPlatform project, lib folder must appears:

Target Definition

At this step we need to refresh the Target Platform. To do that :

  1. close the editor of TargetPlatform/eclispespring.target.
  2. reopen the editor of TargetPlatform/eclispespring.target. PDE will resolve the target platform and bundles that you have downloaded must appears in the Target Paltform.
  3. Activate the Target Platform with Set as Target Platform link.

Use JAXB annotation in the Domain bundle

At first we need to annotate the fr.opensagres.domain.User Pojo of the bundle fr.opensagres.domain with JAXB annotation.

User

User class must be annoted with JAXB @XmlRootElement like this :

package fr.opensagres.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@Entity(name = "T_USER")
public class User {

	@Id
	@GeneratedValue(generator = "GEN_USER")
	@SequenceGenerator(name = "GEN_USER", sequenceName = "SEQ_USER")
	private Long id;

	@Column
	private String firstName;

	@Column
	private String lastName;

	public Long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

}

MANIFEST.MF

To use JAXB annotations, javax.xml.bind.annotation package must be imported (as optionnal to have none dependencies to JAXB if we need not (ex: for Fat Client without remoting)). Modify the MANIFEST.MF of the bundle fr.opensagres.domain like this:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Domain
Bundle-SymbolicName: fr.opensagres.domain
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Export-Package: fr.opensagres.domain
Import-Package: javax.persistence;resolution:=optional,
 javax.xml.bind.annotation;resolution:=optional

Services API

UserService

UserService interface must be annoted with JAX-RS annotations:

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();

...
}

Here the full UserService interface :

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 org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import fr.opensagres.domain.User;

@Path("/user")
public interface UserService {

	@GET
	@Path("/findAll")
	@Produces(MediaType.APPLICATION_JSON)
	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);

}

MANIFEST.MF

To use JAX-RS annotations, JAX-RS packages must be imported (as optionnal). Modify the MANIFEST.MF of the fr.opensagres.services bundle like this:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Services API
Bundle-SymbolicName: fr.opensagres.services
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Export-Package: fr.opensagres.services
Import-Package: fr.opensagres.domain,
 javax.ws.rs;resolution:=optional,
 javax.ws.rs.core;resolution:=optional,
 org.springframework.data.domain

JAX-RS Server Side

Exporter Bundle

Create OSGi bundle fr.opensagres.remoting.exporter.dosgi.jaxrs.

module-osgi-context.xml

Create the META-INF/spring/module-osgi-context.xml to export the UserService with JAX-RS like this :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgi="http://www.springframework.org/schema/osgi"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                      http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd">

	<osgi:reference id="userService" interface="fr.opensagres.services.UserService" />
	
	<osgi:service interface="fr.opensagres.services.UserService">
		<osgi:service-properties>
			<entry key="service.exported.interfaces" value="*" />
			<entry key="service.exported.configs" value="org.apache.cxf.rs" />
			<entry key="service.exported.intents" value="HTTP" />
			<entry key="org.apache.cxf.rs.databinding" value="jaxb" />
		</osgi:service-properties>
		<ref bean="userService" />
	</osgi:service>
	
</beans>

You can find the whole key properties in the Service Provider properties For Configuring RESTful JAXRS-based endpoints and consumers section.

MANIFEST.MF

Modify the MANIFEST.MF of the bundle fr.opensagres.remoting.exporter.dosgi.jaxrs like this:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: JAX-RS Exporter Services
Bundle-SymbolicName: fr.opensagres.remoting.exporter.dosgi.jaxrs
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Import-Package: fr.opensagres.domain,
 fr.opensagres.services,
 javax.ws.rs

And that’s all! At this step our UserService can be exported with JAX-RS.

JAX-RS Server Launches

Now we must create a launch to start our exporter bundle with CXF DOSGi. I find it’s the hardest task for manage remoting with CXF DOSGi.

Server Remoting – JAXRS DOSGi – Mock Dao

Here we will create a launch to export the UserService which works withe Mock Dao. To create Server Remoting – JAXRS DOSGi – Mock Dao

  • Duplicate Simple OSGi Client – Mock Dao.launch
  • Unselect fr.opensagres.simpleclient.
  • Select fr.opensagres.remoting.exporter.dosgi.jaxrs with Auto-Start to true.

Now we must select CXF DOSGi:

  • select org.apache.cxf.bundle-minimal
  • select org.codehaus.jettison.jettison
  • select cxf-dosgi-ri-dsw-cxf with Auto-Start to true.
  • select cxf-dosgi-ri-topology-manager with Auto-Start to true.

Click on Add Required Bundles button to select the dependent bundles of CXF DOSGi. I don’t know why, but some bundles are selected although we need not. So unselect:

  • msv-core
  • org.apache.ws.security.wss4j
  • stax-2api
  • woodstox-core-asl
  • xsdlib

It’s very important too to unselect javax.ws.rs.jsr311-api (JAX-RS API) and select org.apache.servicemix.specs.jsr311-api with Auto-Start to true. Indeed, this bundle contains JAX-RS annotation API and an Activator which register the CXF RuntimeDelegate when it is started. If you don’t do that, you will have this error :

Exception in thread "pool-1-thread-2" java.lang.ExceptionInInitializerError
	at org.apache.cxf.jaxrs.utils.JAXRSUtils.(JAXRSUtils.java:107)
...
Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: com.sun.ws.rs.ext.RuntimeDelegateImpl
...
Caused by: java.lang.ClassNotFoundException: com.sun.ws.rs.ext.RuntimeDelegateImpl
...

Server Remoting – JAXRS DOSGi – JPA Dao

You can create the Server Remoting – JAXRS DOSGi – JPA Dao by duplicating the Simple OSGi Client – JPA Dao.launch and select CXF DOSgi and bundles dependencies like explained below.

Consume service with WEB Browser

Now we can test our Server Remoting – JAXRS DOSGi – Mock Dao launch. Run the launch, and you will see in the OSGi console the following trace:

INFO: TopologyManager: export sucessful Endpoints:[Endpoint Desctiption for ServiceReference {fr.opensagres.services.UserService}={org.springframework.osgi.bean.name=userService, Bundle-SymbolicName=fr.opensagres.remoting.exporter.dosgi.jaxrs, Bundle-Version=1.0.0.qualifier, service.exported.interfaces=*, service.exported.configs=org.apache.cxf.rs, service.exported.intents=HTTP, org.apache.cxf.rs.databinding=jaxb, service.id=59}
*** EndpointDescription: **** 
Bundle-SymbolicName  => fr.opensagres.remoting.exporter.dosgi.jaxrs
Bundle-Version  => 1.0.0.qualifier
endpoint.framework.uuid  => 30646f44-79a6-0011-1a30-96432707e7ca
endpoint.id  => http://127.0.0.1:9000/fr/opensagres/services/UserService
endpoint.package.version.fr.opensagres.services  => 0.0.0
endpoint.service.id  => 59
objectClass  => [Ljava.lang.String;@1a59490
org.apache.cxf.rs.address  => http://127.0.0.1:9000/fr/opensagres/services/UserService
org.apache.cxf.rs.databinding  => jaxb
org.springframework.osgi.bean.name  => userService
service.imported  => true
service.imported.configs  => [Ljava.lang.String;@1bca1c3
service.intents  => [Ljava.lang.String;@12022b7
]

This log is very interesting because you can see for instance the base URL http://127.0.0.1:9000/fr/opensagres/services/UserService of the services.

If you open a WEB Browser and you go at http://127.0.0.1:9000/fr/opensagres/services/UserService/user/findAll , you will see JSON content :

{"user":[{"firstName":"Angelo","lastName":"Zerr"},{"firstName":"Pascal","lastName":"Leclercq"},{"firstName":"Amine","lastName":"Bousta"},{"firstName":"Mickael","lastName":"Baron"},{"firstName":"Jawher","lastName":"Moussa"},{"firstName":"Arnaud","lastName":"Cogoluegnes"},{"firstName":"Lars","lastName":"Vogel"},{"firstName":"Olivier","lastName":"Gierke"},{"firstName":"Tom","lastName":"Schindl"},{"firstName":"Wim","lastName":"Jongman"}]}

NOTE: if the User domain has not @XMlRootElement, you will have this error :

111063 [qtp18800663-38] WARN  org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor  - No message body writer has been found for response class Values.

WADL

It’s possible to see the WADL (which describes the services (like WSDL for SOAP)) of the service with this URL http://127.0.0.1:9000/fr/opensagres/services/UserService/user?_wadl


<application xmlns="http://wadl.dev.java.net/2009/02"
	xmlns:xs="http://www.w3.org/2001/XMLSchema">
	<grammars></grammars>
	<resources base="http://127.0.0.1:9000/fr/opensagres/services/UserService">
		<resource path="/user">
			<resource path="/findAll">
				<method name="GET">
					<response>
						<representation mediaType="application/json" />
					</response>
				</method>
			</resource>
		</resource>
	</resources>
</application>

Logging

A feature that I love with CXF, it’s possible to add Logs Interceptor (In/Out) to logs content received and sent. Add LoggingInInterceptor and LoggingOutInterceptor like this :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgi="http://www.springframework.org/schema/osgi"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                      http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd">

	<osgi:reference id="userService" interface="fr.opensagres.services.UserService" />
	
	<osgi:service interface="fr.opensagres.services.UserService">
		<osgi:service-properties>
			<entry key="service.exported.interfaces" value="*" />
			<entry key="service.exported.configs" value="org.apache.cxf.rs" />
			<entry key="service.exported.intents" value="HTTP" />
			<entry key="org.apache.cxf.rs.databinding" value="jaxb" />
			<!-- Logs -->
			<entry key="org.apache.cxf.rs.in.interceptors" value="org.apache.cxf.interceptor.LoggingInInterceptor" />			
			<entry key="org.apache.cxf.rs.out.interceptors" value="org.apache.cxf.interceptor.LoggingOutInterceptor" />				
		</osgi:service-properties>
		<ref bean="userService" />
	</osgi:service>
	
</beans>

Modify the MANIFEST.MF like this to use the LoggingInInterceptor/LoggingOutInterceptor :

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: JAX-RS Exporter Services
Bundle-SymbolicName: fr.opensagres.remoting.exporter.dosgi.jaxrs
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Import-Package: fr.opensagres.domain,
 fr.opensagres.services,
 javax.ws.rs,
 org.apache.cxf.interceptor,
 org.apache.cxf.jaxrs.provider

If you restart the launch and you go at http://127.0.0.1:9000/fr/opensagres/services/UserService/user/findAll, you will see in the OSGi console the following logs for Inbound :

13782 [qtp9742914-44] INFO  org.apache.cxf.interceptor.LoggingInInterceptor  - Inbound Message
----------------------------
ID: 1
Address: http://127.0.0.1:9000/fr/opensagres/services/UserService/user/findAll
Http-Method: GET
Content-Type: 
Headers: {Accept=[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8], Accept-Charset=[ISO-8859-1,utf-8;q=0.7,*;q=0.3], accept-encoding=[gzip,deflate,sdch], Accept-Language=[fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4], connection=[keep-alive], Content-Type=[null], Host=[192.168.1.11:9000], User-Agent=[Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.52 Safari/536.5]}

and you will see in the OSGi console the following logs for Output :

--------------------------------------
13954 [qtp9742914-44] INFO  org.apache.cxf.interceptor.LoggingOutInterceptor  - Outbound Message
---------------------------
ID: 1
Response-Code: 200
Content-Type: application/json
Headers: {Date=[Mon, 28 May 2012 16:05:09 GMT]}
Payload: {"user":[{"firstName":"Angelo","lastName":"Zerr"},{"firstName":"Pascal","lastName":"Leclercq"},{"firstName":"Amine","lastName":"Bousta"},{"firstName":"Mickael","lastName":"Baron"},{"firstName":"Jawher","lastName":"Moussa"},{"firstName":"Arnaud","lastName":"Cogoluegnes"},{"firstName":"Lars","lastName":"Vogel"},{"firstName":"Olivier","lastName":"Gierke"},{"firstName":"Tom","lastName":"Schindl"},{"firstName":"Wim","lastName":"Jongman"}]}
--------------------------------------

Conclusion

In this article we have implemented remoting with CXF DOSGi on server side by using JAX-RS. In the next article [step2], we will implement remoting with CXF DOSGi on client side.

Catégories :Apache CXF, DOSGi
  1. Mai 29, 2012 à 6:30

    nice post

  2. sroula
    juin 20, 2013 à 11:28

    Hallo Angelo,

    I found your post very informative and it seems that you have a good undestanding of the DOSGi topic.
    I’ am a student and I currently work on a project regarding, RCP, web services and dosgi. What we want to achieve is to create and run java projects remotely. This should be done from an Android device and with the use of Web Services.
    Our approach is to create an Eclipse bundle (a menu extension) that will include the CXF Dosgi (single bundle) which will create and publish the required services.
    However we have problems when we try to include the DOSGi in an Eclipse Bundle. Allthough the Server starts and the Web Service is published (supposedly), there is no wsdl file available.
    I would like to ask if such an approach is possible, namely to include the DOSGI in a Eclipse Bundle used as Extension point.

    thanks!!

    • juin 20, 2013 à 12:31

      Hi sroula,

      It’s very difficult to help you, because I have never used JAX-WS with DOSGi (just used JAX-RS).
      I suggest you to post on the CXF forum.

      Good luck!

      Regards Angelo

  1. Mai 31, 2012 à 9:22
  2. juin 18, 2012 à 7:31

Laisser un commentaire