Consuming SOAP Web Service with JAX-WS in CQ5.6.1

This tutorial is aimed to present a solution of consuming a SOAP Web Service with the native Java API (JAX-WS) within CQ5.

As an outcome, we will create a separate bundle that exports an OSGI Service which can be further invoked from CQ Components. There are other Web Service frameworks such as Apache CXF for integrating Clients, but they are out of the scope of this tutorial.

You will need Apache Maven 3.0.3 and JDK 1.7 in order to follow the steps:

  1. Change sling.properties file
  2. Add OSGi dependencies
  3. Generate Web Service Stubs
  4. Implement OSGi Service
  5. Invoke the Service

Change SLING.PROPERTIES file

Before starting the implementation, add the following line in the sling.properties file located in the crx-quickstart folder, and then restart the server:

sling.bootdelegation.com.sun=com.sun.*

If this is omitted, it is very likely that you will encounter the following exception in the further steps of this tutorial:

Caused by: java.lang.ClassNotFoundException: com.sun.xml.internal.ws.spi.ProviderImplat org.apache.sling.commons.classloader.impl.ClassLoaderFacade.loadClass(ClassLoaderFacade.java:127)at java.lang.ClassLoader.loadClass(Unknown Source)at javax.xml.ws.spi.FactoryFinder.safeLoadClass(Unknown Source)… 107 more

Add OSGI dependencies

In your project structure, create a separate bundle and create the packages where your OSGi Service code and generated Java proxy classes (stubs) will be placed.

A very detailed overview of creating a bundle containing the generated Java proxy classes, such as its overall structure, can be found in this Blog

For the needs of the Service integration, add the following dependencies to the pom.xml file of the bundle:

      <!-- OSGi Dependencies -->
<dependency>
    <groupId>org.osgi</groupId>
    <artifactId>org.osgi.compendium</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>org.apache.felix</groupId>
    <artifactId>org.apache.felix.scr.annotations</artifactId>
    <version>1.9.6</version>
</dependency>
<dependency>
    <groupId>javax.xml.ws</groupId>
    <artifactId>jaxws-api</artifactId>
    <version>2.2.8</version>
</dependency>
    

Generate web service stubs

For this tutorial, we will use the TempConvert Web Service, with WSDL found here. In order to generate the Web Service Stubs, wsimport command should be executed from Terminal:

wsimport –keep –d {directory-path}/generated http://www.w3schools.com/webservices/tempconvert.asmx?wsdl

The following classes are generated:

The TempConvert.java is the Web Service Client, and the TempConvertSoap.java is the proxy. These classes belong to the org.tempuri package.

Are you looking for Adobe Experience Manager developpers?

Implement OSGI service

Now, we can start implementing our OSGi Service that will behave as a Client and consume data from the TempConvert Web Service. 

In our package ch.inside.blog.wsnative, let’s create the TempConvertService interface:

      public interface TempConvertService {
    public String fahrenheitToCelsius(String fahrenheit);
    public String celsiusToFahrenheit(String celsius);
}
    

The method implementation will be placed in ch.inside.blog.wsnative.impl package, the TempConvertServiceImpl class.

      @Component(immediate = true, metatype = true, label = "TempConvert Service", enabled = true)
@Service(value = TempConvertService.class)
public class TempConvertServiceImpl implements TempConvertService {

    private TempConvert tempConvertClient;

    @Activate
    protected void activate(final ComponentContext context){
        this.tempConvertClient = new TempConvert();
    }

    @Override
    public String  fahrenheitToCelsius(String fahrenheit){
	String result = "";	
        if (this.tempConvertClient != null){
            TempConvertSoap proxy = this.tempConvertClient.getTempConvertSoap();
            if (proxy != null){
	        result = proxy.fahrenheitToCelsius(fahrenheit);
	    }
        }
        return result;
    }

    @Override
    public String  celsiusToFahrenheit(String celsius){
	String result = "";	
        if (this.tempConvertClient != null){
            TempConvertSoap proxy = this.tempConvertClient.getTempConvertSoap();
            if (proxy != null){
	        result = proxy.celsiusToFahrenheit(celsius);
	    }
        }
        return result;
    }
}
    

Building the Bundle

For building the bundle, we will use the Maven bundle plugin, where we can specify which packages will be exported or imported.

Our package configuration for the Maven bundle plugin is the following:

      <Export-Package>
    ch.inside.blog.wsnative.*;version=${project.version}
</Export-Package>
<Import-Package>
    !org.tempuri,
    *
</Import-Package>
<Private-Package>
    javax.jws.*
</Private-Package>
    

Invoke the OSGI service

Now it is time to test what has been done so far and consume the TempConvert Web Service.

Make sure that after deploying the bundle, the TempConvertService is active (http://localhost:4502/system/console/components).

The OSGi Service can be directly invoked from our CQ Components. In the JSP file of the CQ Component, add the following code:

      <sling:defineObjects/>
<%@ page import="ch.inside.blog.wsnative.TempConvertService" %>

<%
    TempConvertService service = sling.getService(ch.inside.blog.wsnative.TempConvertService.class);
%>
<br>
The service says: "<%= service.fahrenheitToCelsius("85") %>"
    

Finally, we can consume Web Services in CQ5 as simple as this. 

Looking for more great ressources?

Subscribe to our newsletter and we will send you the next article about Adobe Experience Manager.