OSGi and JAX-RS (with CXF DOSGi): Websphere/RAD Workbook

Architectural Discussion and Design Overview 



Development Platform and Tools: 
- Windows 7-64
- Rational Application Developer v9 (beta) 
- Linux/CentOS v6.3 OS
- Websphere Application Server v8.5
- Database: DB2 v9.7 sp7


Reference:

Apache ARIES Blueprint tutorial
http://aries.apache.org/documentation/tutorials/blueprinthelloworldtutorial.html 

Blueprint Services by Guillaume Nodet (slideshare)
http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=blueprintservices-090622184559-phpapp01&stripped_title=osgi-blueprint-services-1622424 



Resources:

Architectural Discussion and Design Overview 



OSGi and JAX-RS (with CXF DOSGi) on Websphere Application Server v8.5



1) Create OSGi Bundle Project

1) File (top menu) -> new
2) Filter wizard on osgi
3) OSGi Bundle Project
4) Next



(continued)

5) name project "cxf_osgi_example_01"
6) uncheck "add bundle to application" (we'll create a app-bundle project later)
7) next


(continued)

leave defaults
-> Next



(continued)

8) leave symbolic name "cxf_osgi_example_01"
9) make sure to set the version at "1.0.0" (this is important!) 
10) finish




CXF bundle project created



2) Import JPA Bundle

NOTE: The JPA was exported on the previous work-book [link]

NOTE: Also need to add dependency for "javax.ws.rs (2.0.0)" AND THIS STEP IS NOT ILLUSTRATED... so don't forget to add it.



1) from the cxf_osgi_example_01 project
2) double-click (edit) the MANIFEST.MF file
3) select the Dependencies tab
4) Click "add" imported packages

5) Select both the model and "model.controller" packages

5a) Also add in "javax.ws.rs (2.0.0)"

6) OK

NOTE: We'll be adding a number of other packages later for CXF - prior to deployment




Packages imported into cxf_osgi_example_01 bundle project
"model" and 

"model.controller"

and "javax.ws.rs (2.0.0)" - though I missed this bit in the illustration





3) Data Objects: JPA Entity Color (aka "business data objects", "java data objects")

JPA entity: Color (Color.java)
We already created the main object for this example when we generated the JPA "entity" [see link]
All we do now is add some JAXB annotations... as needed (see appendix at end of file for latest changes)

Added some JAXB annotation to Color to help with XML and JSON generation
- This was required for dojo's datasource (javascript) integration into BPM services. 
-- see below: @XmlElement(name = "name")
-------------------
package model;

import java.io.Serializable;
import javax.persistence.*;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;


/**
 * The persistent class for the COLORS database table.
 *
 */
@Entity
@Table(name= "COLORS")
@NamedQuery(name = "getColor" , query = "SELECT c FROM Color c ORDER BY c.colorCode")
@XmlRootElement(name="color" ) // JAXB will through the "No message body writer" error without this annotation! 
public class Color implements Serializable {
     private static final long serialVersionUID = 1L;

     @Id
     @Column(name="COLOR_CODE")
     private String colorCode;

     @Column(name="COLOR_NAME")
     private String colorName;

     public Color() {
     }

     public Color(String colorCode, String colorName) {
            this. colorCode = colorCode;
            this. colorName = colorName;
     }

     public String getColorCode() {
            return this. colorCode;
     }

     public void setColorCode(String colorCode) {
            this. colorCode = colorCode;
     }

     // dojo wasn't able to map identity "name" to "colorName" -> had to switch at source...
     @XmlElement(name = "name")
     public String getColorName() {
            return this. colorName;
     }

     public void setColorName(String colorName) {
            this. colorName = colorName;
     }

}




4) Data Objects: JPA Entity List 

JPA entity list
We'll need to create the list object so that we have better control over both JSON and XML generation from JAXB

Create a simple package to help avoid confusion between all the other RAD projects!
- package name: cxf_example 





ColorList
-------------------------

package cxf_example;

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import model.Color;


@XmlRootElement(name="colorlist" )
public class ColorList {

     private List<Color> colorlist = new ArrayList<Color>();
     
     // @XmlElement(name = "colors") <<< Needed to change this to "items" to meet reqs: ItemFileReadStore
     @XmlElement(name = "items")
     public List<Color> getColorList() {
            return colorlist;
     }
     
     public void setColorList(List<Color> list) {
            this. colorlist = list;
     }
     
}




5) CXF Service Interface and Implementation

It's much easier to first get the infrastructure going with a discrete test. The "test" interface is a simple  "get" that takes a parm'. 
- I'll list out the mistakes I made (... to help pass on the knowledge)


CXF Service Interface: ColorService.java
- Showing the first test method "getColor"
NOTE: check appendix at end of this file for final listing

ColorService.java
----------------------------

package cxf_example;

import javax.ws.rs.GET;
import javax.ws.rs.PathParam;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import model.Color;
import model.controller.ColorManager;


@Path( "colorservice")
public interface ColorService {
     
     public void setColorManager(ColorManager colorManager);
     
     @GET
     @Path("getcolor/{colorcode}")
     //@Produces({"application/xml"}) <<< this service produces both XML and JSON (I tested both)
     @Produces({"application/json"})
     public Color getColor( @PathParam( "colorcode") String colorcode);

}


CXF Service Implementation: ColorServiceImpl.java
NOTE: check appendix at end of this file for final listing

ColorServiceImpl.java
-------------------------------------

package cxf_example;

import model.Color;
import model.controller.ColorManager;

public class ColorServiceImpl implements ColorService {
     
     // This "wires" the CXF Service Implementation into the color entity manager
     //   Value is set by blueprint (via setter)
     private ColorManager colorManager = null;

     @Override
      // NOTICE that this implementation doesn't use the same annotations as the interface?
      //     This is an important distinction!!! Using the annotations, such as @Path and @PathParam
      //     caused CXF to fail at correctly routing requests - lead to "no implementation" error
     public Color getColor(String colorcode) { 
           
           System. out.println( "ColorServiceImpl.getColor: colorcode =  "+colorcode);
           Color color = this. colorManager.findColorByColorCode(colorcode);
           
            return color;
     }
     
     
     // ------------------ 
     // setters and getters
     // ------------------
     public ColorManager getColorManager() {
            return colorManager;
     }

     public void setColorManager(ColorManager colorManager) {
            this. colorManager = colorManager;
     }

}



6) CXF Service Blueprint


Create the blueprint file

1) right-click cxf_osgi_example_01
2) filter on "blue"
3) select "blueprint file"
4) next




(continued)

4) accept default location
5) accept default name: blueprint.xml
6) next



(continued)

check-mark the following items:
jpa support
transaction support
resource reference support

-> Finish


Blueprint created



ColorServiceImplBean
- Creating a blueprint "bean" so that we can "wire" it, via its "colorManager" property.  

1) select blueprint file within cxf_osgi_example_01 project
2) select top-level "blueprint" in blueprint editor
3) click add
4) select "bean"
5) OK



(continued)

6) click "browse" for bean class
7) filter on "cxf_example."
8) select ColorServiceImple class from the "cxf_example" package
9) Verify that we're pointing at the correct project: cxf_osgi_example_01
10) OK



(continued)

Accept recommended names
-> OK


(continued)

ColorServiceImpleBean created



In blueprint, create a Reference to ColorManager service

1) Edit the blueprint for cxf_osgi_example_01 project 
2) select Blueprint in blueprint editor
3) click add
4) click Reference
5) click OK




(continued)

6) click browse for Reference Interface
7) filter on "model.controller." package
8) Select ColorManager interface
9) Make sure you pick an interface from the correct project: jpa_osgi_example_01
10) OK



(continued)

11) Browse for Bean Reference
12) Select ColorServiceImplBean
13) OK



(continued)

accept values
-> OK


Create a Property for ColorServiceImpleBean

1) Select ColorServiceImplBlean
2) Select Property
3) OK



(continued)

4) Select the new property colorManager
5) manually type in the class property name from ColorServiceImpl: colorManager
6) Browse Reference, select ColorServiceImplBeanReference



Clean-up Blueprint: Delete "component-name" value from "ColorServiceImpleBleanReference"


Blueprint source with reference map of Java classes 


Add Reference Listener (see previous workbook on jpa_osgi_example_01 and test)






5) Download and Import Required Components and Libraries


We'll need the following:
- cxf-dosgi-ri-singlebundle-distribution-1.4.0
- jettison-1.3.3

Downloads

cxf-dosgi-ri-singlebundle-distribution-1.4.0
Index > Distributed OSGi > DOSGi Releases
http://cxf.apache.org/dosgi-releases.html
download release 1.4.0 or better (I'm using 1.4.0)

jettison
http://jettison.codehaus.org/Download 
1.3.3 is the current release


Import and Create Bundles

cxf-dosgi-ri-singlebundle-distribution
NOTE: I created a demo-only eclipse workspace since I've already done the imports and have dependencies on other projects

1) click File (top-level menu)
2) filter on "plug-in"
3) select "plug-ins and Fragments"
4) Next



(continued)


Select the directory where I have both cxf-dosgi and jettison jars
-> Next

(continue)

5) Select the cxf-dosgi and jettison components
6) add



(continued)


7) Finish




dosgi and jettison imported
NOTE: Showing these two imports in their own workspace for illustration purposes only. I already have these two projects available for reference in the same workspace as the above cxf project





6) Create, Configure, and "Test" Deploy CXF OSGi Application Project


Create OSGi Application Project

from top-level File-menu
1) filter on OSGi
2) select OSGi Application Project
3) Next

(continue)

project name: cxf_osgi_example_01_app
-> Next


(continue)

Select the OSGi bundles for the application
- cxf-dosgi
- cxf_osgi_example
- jettison
- jpa_osgi_Example

-> Finish



OSGi Application Manifest
Showing contained Bundles


Test Deploy CXF Application
- looking for validation errors and insuring that the bundle starts up w/o error

The listeners for onRegister and referenceBind reporting in w/o error! 
- Ready to configure DSOGI-CXF  (publish a ReST service)




6) Configure Service and Properties for CXF ReST 



Create a Service from the ColorService interface

1) Edit blueprint.xml within the cxf_osgi_example_01 project
2) select top-level "Blueprint
3) Add
4) Select Service
5) OK



(continue)

6) Browser Service Interface
7) filter on "cxf_example." package
8) select ColorService interface
9) make sure we picked the correct interface from project: cxf_osgi_example_01
-> OK


(continue)

10) Browse Bean Reference
11) select ColorServiceImplBean
12) OK


(continue)

Accept recommended ID value
-> OK

(continue)

ColorServiceImplBeanService Service Created



(continued: adding properties)

13) Select ColorServiceImplBeanService
14) click Add
15) Select service Properties
16) OK


(continue)

Switching to source editing at this stage because it's just more efficient...

service-properties
<entry key = "service.exported.interfaces" value= "*" /> : This means that we're exporting (as ReST services) all interfaces
<entry key = "service.exported.configs" value= "org.apache.cxf.rs" /> : Using JAX-RS (see DOSGI documentation)
<entry key = "service.exported.intents" value= "HTTP" /> : Honestly not sure what this does... just following another's example
<entry key = "org.apache.cxf.rs.address" value= "http://centos9:9201/cxf" /> : Telling CXF our protocol, port, and root context

blueprint.xml
-------------------
<?xml version="1.0" encoding= "UTF-8"?>
<blueprint xmlns= "http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:bpjpa= "http://aries.apache.org/xmlns/jpa/v1.0.0" xmlns:bptx= "http://aries.apache.org/xmlns/transactions/v1.0.0" xmlns:bpresref="http://www.ibm.com/appserver/schemas/8.0/blueprint/resourcereference" >
     <bean id ="ColorServiceImplBean" class= "cxf_example.ColorServiceImpl">
            <property name ="colorManager" ref= "ColorServiceImplBeanReference"/>
     </bean >
     <reference id ="ColorServiceImplBeanReference" interface= "model.controller.ColorManager">
            <reference-listener ref= "ColorServiceImplBeanReference" bind-method ="referenceBind" unbind-method="referenceUnBind" />
     </reference >
     <service id ="ColorServiceImplBeanService" ref= "ColorServiceImplBean" interface ="cxf_example.ColorService">
            <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.address" value= "http://centos9:9201/cxf"/>
            </service-properties >
     </service >
</blueprint>


Test-Deploy our updated application to see if CXF starts-up correctly
- CXF will report in the SystemOut.log

CXF starts-UP! 
publish address reports back as http://centos9/9201/cxf
- our first service is at: "getcolor/{colorcode}" 
The complete URL: http://centos9/9201/cxf/colorservice/getcolor/{colorcode}
EXAMPLE: http://centos9:9201/cxf/colorservice/getcolor/BLUE




7) Initial Service CXF Test



Test URL: (tested using Chrome browser - because it magically  handles a JSON response)
http://centos9:9201/cxf/colorservice/getcolor/BLUE


Working Response (JSON):

{"color":{"colorCode":"BLUE","name":"BLUE"}}


Common Errors/Fixes

No message body writer
00000219 JAXRSOutInter W   No message body writer has been found for response class Color.
- Make sure you have the correct annotations for JAXB. Forgetting the @XmlRootElement in Color entity class was my mistake... 

- Make sure you've added "jettison" to the "contained bundles" for your application deployment:


Bad URL
0000025a JAXRSUtils    W   No operation matching request path "/cxf/colorservice/getcolor" is found

- Correct: http://centos9:9201/cxf/colorservice/getcolor/BLUE 
- Incorrect: http://centos9:9201/cxf/colorservice/getcolor?colorcode=blue




8) Adding a Create (post) method that Accepts JSON and XML Object as Input

One of the most important features is the ability to pass in JSON objects via the ReST API. This allows us to simply construct and send, in javascript, JSON objects WITHOUT the hassles of formatting for HTTP. 


ColorService interface (showing changed or new method only - see appendix for full listing)
NOTE: I set the interface to consume and produce both JSON and XML (it's that easy...). No change required for implementation.  
-------------------------------
     @GET
     @Path("getcolor/{colorcode}")
     @Produces({"application/json", "application/xml"}) // produces both XML and JSON
     public Color getColor( @PathParam( "colorcode") String colorcode);

     
     @POST
     @Path("/createcolor")
     @Consumes({"application/json", "application/xml"}) // consumes both XML and JSON
     public String createColor(Color color);


ColorServiceImpl implemenatation (showing changed or new method only - see appendix for full listing)
------------------
     // DO NOT forget to add "content-Type: application/json " or "content-Type: application/XML" to the post header!
     @Override
     public String createColor(Color color) {
           
           String postStatus = "SUCCESS";
           
            // report that service is able to consume POST payload
           System. out.println( "ColorServiceImpl.createColor received color: "+
                       "colorCode="+color.getColorCode()+ ", colorName="+color.getColorName());
           
            // send to model
            try {
                 this. colorManager.createColor(color);
           } catch (Exception e) {
                e.printStackTrace();
                postStatus = "FAIL"; // NOT building a proper "response" object... yet
           }
                      
            return postStatus;
     }


Testing with HTTPRequester (FireFox add-on)

1) Set URL: http://centos9:9201/cxf/colorservice/createcolor
2) Set Content type to json
3) paste in payload (showing json example)
4) click the POST button



If everything works as it should... status should return: "SUCCESS"

Showing the new record in the database table: 
NOTE: the commented out "delete" statement was used to clean up previous tests





9) Adding Delete method

See appendix for full code listing. This was too much like the the "get" request to warrant full illustration




10) Adding Get All method (get list)

See appendix for full code listing. This was too much like the the "get" request to warrant full illustration




11) soapUI: Test getcolor Service


Tested with soapUI version 4.5.2
download: http://sourceforge.net/projects/soapui/files/ 


Create the soapUI ReST Project

1) top-level menu -> File -> new soapUI project
2) Project name: ReST_test_03 (and that's it... )
3) OK




Add Rest Service to ReST_test_03 project

1) right-click project ReST_test_03 -> select New Rest Service
2) service name: colorservice
3) Service Endpoint: http://centos9:9201 (NOTE: using only host:port to endpoint to avoid duplication of path into rest methods)
4) OK




Add REST Service to colorservice project
1) right-click colorservice
2) click "new rewsource"



(continue)

3) Resource name: getcolor
4) resource path: /cxf/colorservice/getcolor/{colorcode}  (NOTE: the "{colorcode}" is used as the template under "style")
5) name matches template: colorcode
6) set style: TEMPLATE
7) OK



(continue)

8) Method name: getcolor (yes... naming the method same as above "rest resource")
9) HTTP Method: GET
10) uncheck "create request"
11) OK


(continued)

ReST Service created with one method




Create a Test

Right-click "getcolor" method -> select New Request



(continue)

Request name: test_01
check "open Request:
-> OK



Set parameter for test_01 request
1) coulbe click "value" and enter "BLUE" (and hit return!... very important to set this value)



1a) Note that the parameter changed to "BLUE"
The full path switched to: "/cxf/colorservice/getcolor/BLUE" via usage of the template parameter




Set Header
1) Select "header" at bottom-left of request
2) click the "add header"
3) type in "Accept"
4) OK


(continue)

5) set value: "application/json" (don't forget to set this value by hitting return key!)



Submit ReST Request
1) click the green arrow (top-left of test) - a response should come back within milliseconds 
2) click the JSON tab to see JSON output (NOTE: soapUI translates responses to XML regardless of ReST service output)






11) soapUI: Test createcolor Service


Create a new Resource to test createcolor



Create REST Method
Set HTP Method to POST
-> OK



Ad a new request for (above) createcolor method



Edit Request and Submit
1) set media type to: application/xml (NOTE: looks like soapUI can't send JSON)
2) past in our test xml
<color>
     <colorCode>TESTCODE</colorCode>
     <name>TESTNAME</name>
</color>

3) Submit

Response should come back as: "<![CDATA[SUCCESS]]>" (you'll have to scroll the response to see)


ETC... (soapUI is self-explanatory from this point)






APPENDIX 


PROJECT: jpa_osgi_example_01   
NOTE: showing Color.java (entity only - the one changed to fix XML/JSON generation)
-------------------------
Color.java
-------------------------
package model;

import java.io.Serializable;
import javax.persistence.*;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;


/**
 * The persistent class for the COLORS database table.
 *
 */
@Entity
@Table(name= "COLORS")
@NamedQuery (name = "getColor" , query = "SELECT c FROM Color c ORDER BY c.colorCode")
@XmlRootElement (name="color" )
public class Color implements Serializable {
      private static final long serialVersionUID = 1L;

      @Id
      @Column(name= "COLOR_CODE")
      private String colorCode;

      @Column(name= "COLOR_NAME")
      private String colorName;

      public Color() {
     }

      public Color(String colorCode, String colorName) {
            this. colorCode = colorCode;
            this. colorName = colorName;
     }

      public String getColorCode() {
            return this. colorCode;
     }

      public void setColorCode(String colorCode) {
            this. colorCode = colorCode;
     }

      // dojo wasn't able to map identity "name" to "colorName" -> had to switch at source...
      @XmlElement(name = "name")
      public String getColorName() {
            return this. colorName;
     }

      public void setColorName(String colorName) {
            this. colorName = colorName;
     }

}

 

 



PROJECT: cxf_osgi_example_01      

-------------------------
ColorList.java
-------------------------
package cxf_example;

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import model.Color;


@XmlRootElement(name="colorlist" )
public class ColorList {

     private List<Color> colorlist = new ArrayList<Color>();
     
     // @XmlElement(name = "colors") <<< Needed to change this to "items" to meet reqs: ItemFileReadStore
     @XmlElement(name = "items")
     public List<Color> getColorList() {
            return colorlist;
     }
     
     public void setColorList(List<Color> list) {
            this. colorlist = list;
     }
     
}


-------------------------
ColorService.java
-------------------------
package cxf_example;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.DELETE;
import javax.ws.rs.Consumes;
import javax.ws.rs.PathParam;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import model.Color;
import model.controller.ColorManager;


@Path( "colorservice")
public interface ColorService {
     
     public void setColorManager(ColorManager colorManager);
     
     @GET
     @Path("getcolor/{colorcode}")
     @Produces({"application/json", "application/xml"})
     public Color getColor( @PathParam( "colorcode") String colorcode);
     
     @GET
     @Path("getallcolors")
     @Produces({"application/json", "application/xml"})
     public ColorList getAllColors();

     @POST
     @Path("createcolor")
     @Consumes({"application/json", "application/xml"})
     public String createColor(Color color);
     
     @DELETE
     @Path("deletecolor/{colorcode}")
     public String deleteColor( @PathParam( "colorcode") String colorcode);
     
}


-----------------------------
ColorServiceImpl.java
-----------------------------
package cxf_example;

import java.util.List;

import model.Color;
import model.controller.ColorManager;

public class ColorServiceImpl implements ColorService {
     
     // This "wires" the CXF Service Implementation into the color entity manager
     //   Value is set by blueprint (via setter)
     private ColorManager colorManager = null;

     @Override
     public Color getColor(String colorcode) {
           
           System. out.println( "ColorServiceImpl.getColor: colorcode =  "+colorcode);
           Color color = this. colorManager.findColorByColorCode(colorcode);
           
            return color;
     }
     
     // DO NOT forget to add "content-Type: application/json " to the post header!
     @Override
     public String createColor(Color color) {
           
           String postStatus = "SUCCESS";
           
            // report that service is able to consume POST payload
           System. out.println( "*** ColorServiceImpl.createColor received color: "+
                       "colorCode="+color.getColorCode()+ ", colorName="+color.getColorName());
           
            // send to model
            try {
                 this. colorManager.createColor(color);
           } catch (Exception e) {
                e.printStackTrace();
                postStatus = "FAIL"; // NOT building a proper "response" object... yet
           }
                      
            return postStatus;
     }
     
     @Override
     public ColorList getAllColors() {
           
           List<Color> list = colorManager.getColor();
           ColorList colorList = new ColorList();
           colorList.setColorList(list);
           
            return colorList;
     }

     @Override
     public String deleteColor(String colorcode) {
           String postStatus = "SUCCESS";
           
           System. out.println( "*** ColorServiceImpl.deleteColor received colorcode: "+ colorcode);
           
            // send delete request to model
            //   NOTE: the delete JPA implementation has an odd requirement for a complete
            //         color entity... not sure why. I simply created one with the colorCode
            //         to meet the requirement (and... yes. I might fix this later)
           Color deleteColor = new Color(colorcode, "");
            try {
                 this. colorManager.deleteColor(deleteColor);
           } catch (Exception e) {
                e.printStackTrace();
                postStatus = "FAIL"; // NOT building a proper "response" object... yet
           }
                      
            return postStatus;
     }    
     
     
     
     // ------------------ 
     // setters and getters
     // ------------------
     public ColorManager getColorManager() {
            return colorManager;
     }

     public void setColorManager(ColorManager colorManager) {
            this. colorManager = colorManager;
     }

}


-----------------------------
MANIFEST.MF
-----------------------------
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: cxf_osgi_example_01
Bundle-SymbolicName: cxf_osgi_example_01
Bundle-Version: 1.0.0
Bundle-RequiredExecutionEnvironment : JavaSE-1.6
Import-Package: javax.ws.rs;version ="2.0.0",
 model,
 model.controller
Bundle-Blueprint: OSGI-INF/blueprint/*.xml
  
-----------------------------
blueprint.xml
-----------------------------
<?xml version="1.0" encoding= "UTF-8"?>
<blueprint xmlns= "http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:bpjpa= "http://aries.apache.org/xmlns/jpa/v1.0.0" xmlns:bptx= "http://aries.apache.org/xmlns/transactions/v1.0.0" xmlns:bpresref="http://www.ibm.com/appserver/schemas/8.0/blueprint/resourcereference" >
     <bean id ="ColorServiceImplBean" class= "cxf_example.ColorServiceImpl">
            <property name ="colorManager" ref= "ColorServiceImplBeanReference"/>
     </bean >
     <reference id ="ColorServiceImplBeanReference" interface= "model.controller.ColorManager">
            <reference-listener ref= "ColorServiceImplBeanReference" bind-method ="referenceBind" unbind-method="referenceUnBind" />
     </reference >
     <service id ="ColorServiceImplBeanService" ref= "ColorServiceImplBean" interface ="cxf_example.ColorService">
            <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.address" value= "http://centos9:9201/cxf"/>
            </service-properties >
     </service >
</blueprint>



PROJECT: cxf_osgi_example_01_app

-----------------------------
MANIFEST.MF
-----------------------------
Application-Name: cxf_osgi_example_01_app
Application-SymbolicName : cxf_osgi_example_01_app
Application-ManifestVersion : 1.0
Application-Version: 1.0.0.qualifier
Application-Content: cxf-dosgi-ri-singlebundle-distribution;version ="1.4
 .0",
  cxf_osgi_example_01;version="1.0.0",
  jettison-1.3.3;version="1.0.0",
  jpa_osgi_example_01;version="1.0.0"
Manifest-Version: 1.0