Skip to main content

JAX-WS Web Service in an OSGi bundle

Posted by ss141213 on April 8, 2010 at 1:21 AM PDT

Recently a user in GlassFish forum asked about developing JAX-WS web service in an OSGi bundle. Here is a complete sample demonstrating a JAX-WS web service invoking an OSGi service via OSGi service registry. You can download it from here. The diagram below hopefully explains the organisation of the sample:

 

As the above diagram shows, we have three components, viz:

1) osgi-service.jar: This is an OSGi bundle which provides a service to other bundles. It contains two POJOs, viz: a) an interface called sahoo.hybridapp.jaxws1.service.Watch, b) an implementation of the same interface called sahoo.hybridapp.jaxws1.service.WatchImpl.  This bundle also contains a bundle activator called sahoo.hybridapp.jaxws1.service.Activator, which is responsible for registering an instance of WatchImpl in OSGi service registry.

2) web-service.war: This is a Web Application Bundle. A Web Application Bundle is a hybrid application - it's both a Java EE archive as well as an OSGi bundle. In this case, it is a war file as well as an OSGi bundle. It's a war file, because it contains a Servlet based JAX-WS end point. It's an OSGi bundle, because we want to make use of OSGi service in the implementation of our web service. It contains a single class called sahoo.hybridapp.jaxws1.webservice.WatchWebService which is defined like this:

 

package sahoo.hybridapp.jaxws1.webservice;

import sahoo.hybridapp.jaxws1.service.Watch;
import org.osgi.framework.*;
import javax.jws.*;

@WebService
public class WatchWebService {
   @WebMethod public String currentTime() {
       Watch watch = getService(Watch.class);
       System.out.println("WatchService: OSGi service is: " + watch);
       if (watch == null) {
          return "I don't have a watch";
       } else {
          return watch.currentTime();
       }
   }

   /**
     * This method looks up service of given type in OSGi service registry and returns if found.
     * Returns null if no such service is available,
     */
   private static <T> T getService(Class<T> type) {
       BundleContext ctx = BundleReference.class.cast(WatchWebService.class.getClassLoader()).getBundle().getBundleContext();
       ServiceReference ref = ctx.getServiceReference(type.getName());
       return ref != null ? type.cast(ctx.getService(ref)) : null;
   }
}
 


The MANIFEST.MF of web-service.war looks like this:

Bundle-ClassPath                        WEB-INF/classes/                       
Bundle-ManifestVersion                  2                                      
Bundle-SymbolicName                     sahoo.hybridapp.jaxws1.web-service     
Bundle-Version                          1.0.0.SNAPSHOT                         
Import-Package                          javax.jws;version="2.0",org.osgi.framework;version="1.5",sahoo.hybridapp.jaxws1.service;version="1.0"
Web-ContextPath                         /hybridapp.jaxws1.web-service        

3) web-service-client.jar: This is a plain jar file which makes use of JAX-WS stack of Java SE environment to invoke our web service. It has a single class called sahoo.hybridapp.jaxws1.webserviceclient.Main. The rest of the classes that are part of this jar are generated by wsdl compiler as part of build.

How to build, deploy and test:

Step 1: Start GlassFish

java -jar glassfish.jar


Step 2: Build and deploy the service bundles

cd hybridapp.jaxws1/

mvn clean install

This will produce two OSGi bundles called osgi-service/target/osgi-service.jar and web-service/target/web-service.war. Deploy these two OSGi bundles to GlassFish by simply copying them to domain1/autodeploy/bundles/ dir as shown below:

cp osgi-service/target/osgi-service.jar web-service/target/web-service.war $glassfish.home/domains/domain1/autodeploy/bundles/

GlassFish will automatically detect that web-service.war is a WAB and will perform necessary deployment of EE artifacts as a result of which a web service end point will be available. You can see something like this appearing in server.log:

WS00018: Webservice Endpoint deployed
 WatchWebService  listening at address at http://localhost:8080/hybridapp.jaxws1.web-service/WatchWebServiceService
 

Step 3: Build and run the client

Once the web service is available, run

mvn -f web-service-client/pom.xml

to build web-service-client.jar. This is because the WSDL url, as specified in web-service-client/pom.xml, is not available until the web service is deployed.

To test, simple run:

java -jar web-service-client.jar

You shall see it will print the current time as obtained from the web service which in turn obtrains it from the OSGi service.

Look at the source code and maven pom.xmls to see how various maven plugins help make life easier. This sample uses a WAB to develop web service. You can develop JAX-WS service end points as EJBs as well and in that case you can deploy them as OSGi/EJB bundle in GlassFish. Enjoy developing OSGi enabled Java EE applications in GlassFish!!! As usual,  feddback most welcome.

AttachmentSize
uml.png26.7 KB
hybridapp.jaxws1_.zip78.76 KB