Hi,

C O N G R A T U L A T I O N S …Awaited “jboss-as-7.1.0.CR1” is released recently. So here we are going to test a Simple WebService in JBoss AS7.1 CR1. In this sample we will see how to develop a Simple Apache CXF based webService with the help of Spring. Also we will see how to use a Simple Spring WebService Client to reduce the code at the client side and the utilize the beans feature provided by the Spring.

More informations about the CXF Spring Client can be found in the following link:
http://cxf.apache.org/docs/writing-a-service-with-spring.html

Highlights of Article

Point-1). In this example we are going to use “jboss-as-7.1.0.CR1” which can be downloaded from the following link: http://www.jboss.org/jbossas/downloads

Point-2). We will see how to use the cxf-servlet.xml file.

Point-3). How to use the Spring ApplicationContext and ClassPathXmlApplicationContext to initialize the jaxws based beans for Service client.

Point-4). As the client is going to use spring features to access the web service so we will need to make sure that “spring-2.5.6.jar” jar is present in the client classpath. This jar can be downloaded from the following link:
http://repo1.maven.org/maven2/org/springframework/spring/2.5.6/spring-2.5.6.jar

Developing Spring CXF WebService

Step1). Create a Directory somewhere in your filesystem like “/home/userone/CXF_Spring_Demo/” and then create “src” directory inside “/home/userone/CXF_Spring_Demo/”.

Step2). Now we will write the Web Service Endpoint Interface “Spring_CXF_Service_Intf.java” inside “/home/userone/CXF_Spring_Demo/src” as following:

package ws;
import javax.jws.WebService;

@WebService
public interface Spring_CXF_Service_Intf
  {
      public String sayHello(String name);
  }

Step4). Now we will provide the WebService Implementation class “Spring_CXF_Service.java” inside “/home/userone/CXF_Spring_Demo/src” as following:

package ws;
import javax.jws.WebService;

@WebService(endpointInterface = "ws.Spring_CXF_Service_Intf")
public class Spring_CXF_Service implements Spring_CXF_Service_Intf
  {
      public String sayHello(String name)
        {
            System.out.println("[Spring_CXF_Service] sayHello("+name+") invoked.");
            return "Hello World !!! Mr. "+name;
        }
  }

Step4). We will write the “web.xml” inside “/home/userone/CXF_Spring_Demo/src” as following (practically this file is almost empty):

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

</web-app>

Step5). We will write the “cxf-servlet.xml” inside “/home/userone/CXF_Spring_Demo/src” to define “jaxws:endpoint” and it’s implementation class details as following:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

        <!--
	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
        -->

        <!-- In My case i am putting "cxf-servlet.xml" inside WEB-INF directory -->
	<jaxws:endpoint 
	  id="cxfSpringServiceHelloWorld" 
	  implementor="client.SpringCXFService" 
	  address="/Spring_CXF_Service" />
	  
</beans>

NOTE: We need to make sure that this “cxf-servlet.xml” file is present inside the “WEB-INF” diectory of our service.

Developing Spring CXF based Client

Step6). Now we will write the WebService Client “Test_CXF_Client.java” inside “/home/userone/CXF_Spring_Demo/src” using CXF standard code as following :

package client;
import java.util.Date;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test_CXF_Client
  {
     public static void main(String ar[]) throws Exception
      {
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"client-beans.xml"});
        SpringCXFServiceIntf client = (SpringCXFServiceIntf) context.getBean("testClient");
        System.out.println("ntGot Client: "+client);         
        System.out.println("ntclient.sayHello(Middleware Magic): "+client.sayHello("Middleware Magic"));                
      }
  }

Step7). We will create the “client-beans.xml” XML file inside “/home/userone/CXF_Spring_Demo/src” directory as following. (This file name may be anything)

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

    <jaxws:client id="testClient"
                  serviceClass="client.SpringCXFServiceIntf"
                  address="http://localhost:8080/Spring_CXF_Service_Demo/Spring_CXF_Service" />
</beans>

NOTE: The file name “client-beans.xml” may be anything but we need to make sure that this file is present in the client classpath.
NOTE: client-beans.xml file should be written only when you have run the wsconsume anttask to generate Client side artifacts for your WebService, Because the classes like “client.SpringCXFServiceIntf” will be generated at client side only after generating the client side artifacts.

Step8). As our weservice client is going to use the spring features to access the web service so we will need to make sure that the following JAR is present in the client classpath and place it inside “/home/userone/CXF_Spring_Demo/src” directory. This file can be downloaded from the following link:
http://repo1.maven.org/maven2/org/springframework/spring/2.5.6/spring-2.5.6.jar

Building, Deploying and Testing

Step9). As everything is done so we will write a ant build script in order to build/deploy/run and test the WebService and Basic Authentication, So create a file “build.xml” inside “/home/userone/CXF_Spring_Demo/” as following:

<project name="JBoss_Service" default="post-deploy">
<property name="jboss.home" value="/home/userone/jboss-as-7.1.0.CR1" />
<property name="jboss.module.dir" value="${jboss.home}/modules" />
<property name="basedir" value="." />
<property name="war.tmp.name" value="Spring_CXF_Service_Demo" />
<property name="war.name" value="Spring_CXF_Service_Demo.war" />
<property name="src.dir" value="src" />
<property name="client.src.dir" value="${basedir}/clientSrc" />
<property name="output.dir" value="build" />
<property name="client.dir" value="${basedir}/clientStuff" />
<property name="client.jar.name" value="Spring_CXF_Client.jar" />
 
   <path id="jboss.classpath">
     <fileset dir="${jboss.module.dir}">
        <include name="**/*.jar"/>
     </fileset>  
   </path>

   <path id="client.classpath">
     <fileset dir="${jboss.module.dir}">
        <include name="**/*.jar"/>
     </fileset>  
     <fileset dir="${src.dir}">
        <include name="**/spring-2.5.6.jar"/>
        <!-- This Jar is needed at client side and can be downloaded from the following link -->
        <!-- http://repo1.maven.org/maven2/org/springframework/spring/2.5.6/spring-2.5.6.jar    -->
     </fileset>  
     <fileset dir="${client.dir}">
        <include name="*.jar"/>
     </fileset>  
   </path>

   <taskdef name="wsprovide" classname="org.jboss.ws.tools.ant.WSProvideTask">
       <classpath refid="jboss.classpath"/>
   </taskdef>

   <taskdef name="wsconsume" classname="org.jboss.ws.tools.ant.WSConsumeTask">
       <classpath refid="jboss.classpath"/>
   </taskdef>

        <target name="init">
           <delete dir="${output.dir}" />
           <mkdir dir="${output.dir}" />
           <mkdir dir="${output.dir}/${war.tmp.name}/META-INF"/>
           <mkdir dir="${output.dir}/${war.tmp.name}/WEB-INF/classes"/>
           <delete dir="${client.dir}" />
           <mkdir dir="${client.dir}"/>
        </target>
	 
    <target name="build" depends="init">
       <javac srcdir="${src.dir}" destdir="${output.dir}/${war.tmp.name}/WEB-INF/classes"  includes="*.java" excludes="Test_CXF_Client.java" classpathref="jboss.classpath"/>
        <copy todir="${output.dir}/${war.tmp.name}/WEB-INF">
	  <fileset dir="${basedir}/src">
	      <include name="web.xml"/>
	      <include name="cxf-servlet.xml"/>
	  </fileset>
	</copy>   
       <wsprovide
        	fork="false"
        	keep="true"
        	destdir="${output.dir}"
        	resourcedestdir="${output.dir}/${war.tmp.name}/WEB-INF/wsdl"
        	sourcedestdir="${output.dir}"
        	genwsdl="true" 
        	verbose="true"
        	sei="ws.Spring_CXF_Service">
            	<classpath>
                	  <pathelement path="${output.dir}/${war.tmp.name}/WEB-INF/classes"/>
            	</classpath>
      </wsprovide>
      <jar jarfile="${output.dir}/${war.name}" basedir="${output.dir}/${war.tmp.name}" compress="true" />  
      <delete dir="${output.dir}/${war.tmp.name}" />
    </target>

        <target name="deploy" depends="build">
            <echo message="*******************  Deploying   *********************" />  
            <echo message="********** ${war.name} to ${jboss.home}/standalone/deployments **********" />  
            <copy todir="${jboss.home}/standalone/deployments/">
                <fileset dir="${output.dir}/">
                  <include name="${war.name}"/> 
                </fileset>
            </copy>
            <echo message="*******************  Deployed Successfully   *********************" />  
        </target>
  
        <target name="post-deploy" depends="deploy">
            <echo message="*******************  NOTE  *********************" />
            <echo message="***** You should be able to access your WSDL using Browser now *****" />
            <echo message="                http://localhost:8080/Spring_CXF_Service_Demo/Spring_CXF_Service?wsdl          " />
        </target>  

        <target name="client">
             <delete dir="${client.dir}" />
             <wsconsume
                      fork="true"
                      keep="true"
                      destdir="${client.dir}"
                      sourcedestdir="${client.dir}"
                      package="client"
                      wsdlLocation="http://localhost:8080/Spring_CXF_Service_Demo/Spring_CXF_Service?wsdl"
                      wsdl="http://localhost:8080/Spring_CXF_Service_Demo/Spring_CXF_Service?wsdl">
            </wsconsume>
            <jar jarfile="${client.dir}/${client.jar.name}" basedir="${client.dir}" compress="true" />  
            <zip destfile="${client.dir}/${client.jar.name}" 
                 update="true"> 
                 <fileset dir="${src.dir}"> 
                       <include name="client-beans.xml" /> 
                 </fileset> 
            </zip> 
       </target>

        <target name="run" depends="client">
            <javac srcdir="${src.dir}" destdir="${client.dir}"  includes="Test_CXF_Client.java" classpathref="client.classpath"/>
            <java classname="client.Test_CXF_Client"  >
	        <classpath>
	            <pathelement location="${client.dir}"/>
	            <path refid="client.classpath"/>
	        </classpath>
                <arg value="http://localhost:8080/Spring_CXF_Service_Demo"/>
            </java>
        </target>  

</project>

NOTE: The only change in the above file you need to do is to change the “jboss.home” directory path in the second line of the above script is to point to your own JBoss AS7 directory home directory.

Step10). Now before running your ANT script to build and deploy the above webapplication you should have the ANT as well as JAVA set in the $PATH variable of the Shell / command prompt as following:

For Unix Based OS:
export PATH=/home/userone/jdk1.6.0_21/bin:/home/userone/org.apache.ant_1.6.5/bin:$PATH

For Windows Based OS:
set PATH=C:/jdk1.6.0_21/bin;C:/org.apache.ant_1.6.5/bin;%PATH%

Step11). Run the command “ant” or “ant post-deploy” which will internally build the WebService and deploy it inside the JBoss AS7 standalone profile.

[userone@localhost CXFTimeoutClientDemo]$ ant
Buildfile: /home/userone/CXF_Spring_Demo/build.xml

init:
   [delete] Deleting directory /home/userone/CXF_Spring_Demo/build
    [mkdir] Created dir: /home/userone/CXF_Spring_Demo/build
    [mkdir] Created dir: /home/userone/CXF_Spring_Demo/build/Spring_CXF_Service_Demo/META-INF
    [mkdir] Created dir: /home/userone/CXF_Spring_Demo/build/Spring_CXF_Service_Demo/WEB-INF/classes
   [delete] Deleting directory /home/userone/CXF_Spring_Demo/clientStuff
    [mkdir] Created dir: /home/userone/CXF_Spring_Demo/clientStuff

build:
    [javac] Compiling 2 source files to /home/userone/CXF_Spring_Demo/build/Spring_CXF_Service_Demo/WEB-INF/classes
     [copy] Copying 2 files to /home/userone/CXF_Spring_Demo/build/Spring_CXF_Service_Demo/WEB-INF
[wsprovide] Generating from endpoint: ws.Spring_CXF_Service
[wsprovide] log4j:WARN No appenders could be found for logger (org.apache.cxf.common.logging.LogUtils).
[wsprovide] log4j:WARN Please initialize the log4j system properly.
[wsprovide] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
[wsprovide] java2ws -s /home/userone/CXF_Spring_Demo/build -classdir /home/userone/CXF_Spring_Demo/build -d /home/userone/CXF_Spring_Demo/build/Spring_CXF_Service_Demo/WEB-INF/wsdl -verbose -wsdl -cp ::::::: -wrapperbean -createxsdimports ws.Spring_CXF_Service
[wsprovide] java2ws - Apache CXF 2.4.4
[wsprovide] 
      [jar] Building jar: /home/userone/CXF_Spring_Demo/build/Spring_CXF_Service_Demo.war
   [delete] Deleting directory /home/userone/CXF_Spring_Demo/build/Spring_CXF_Service_Demo

deploy:
     [echo] *******************  Deploying   *********************
     [echo] ********** Spring_CXF_Service_Demo.war to /home/userone/jboss-as-7.1.0.CR1/standalone/deployments **********
     [copy] Copying 1 file to /home/userone/jboss-as-7.1.0.CR1/standalone/deployments
     [echo] *******************  Deployed Successfully   *********************

post-deploy:
     [echo] *******************  NOTE  *********************
     [echo] ***** You should be able to access your WSDL using Browser now *****
     [echo]                 http://localhost:8080/Spring_CXF_Service_Demo/Spring_CXF_Service?wsdl          

BUILD SUCCESSFUL
Total time: 5 seconds

Step12). As soon as the service is deployed on JBoss AS7 you will see the following kind of output in the JBoss console :

12:27:16,426 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-2) Starting deployment of "Spring_CXF_Service_Demo.war"
12:27:16,479 INFO  [org.jboss.wsf.stack.cxf.metadata.MetadataBuilder] (MSC service thread 1-4) Add Service
 id=ws.Spring_CXF_Service
 address=http://localhost:8080/Spring_CXF_Service_Demo/Spring_CXF_Service
 implementor=ws.Spring_CXF_Service
 invoker=org.jboss.wsf.stack.cxf.JBossWSInvoker
 serviceName={http://ws/}Spring_CXF_ServiceService
 portName={http://ws/}Spring_CXF_ServicePort
 wsdlLocation=null
 mtomEnabled=false
12:27:16,479 INFO  [org.jboss.ws.common.management.DefaultEndpointRegistry] (MSC service thread 1-4) register: jboss.ws:context=Spring_CXF_Service_Demo,endpoint=ws.Spring_CXF_Service
12:27:16,491 INFO  [org.apache.cxf.service.factory.ReflectionServiceFactoryBean] (MSC service thread 1-4) Creating Service {http://ws/}Spring_CXF_ServiceService from class ws.Spring_CXF_Service_Intf
12:27:16,533 INFO  [org.apache.cxf.endpoint.ServerImpl] (MSC service thread 1-4) Setting the server's publish address to be http://localhost:8080/Spring_CXF_Service_Demo/Spring_CXF_Service
12:27:16,548 INFO  [org.jboss.wsf.stack.cxf.deployment.WSDLFilePublisher] (MSC service thread 1-4) WSDL published to: file:/home/userone/jboss-as-7.1.0.CR1/standalone/data/wsdl/Spring_CXF_Service_Demo.war/Spring_CXF_ServiceService.wsdl
12:27:16,550 INFO  [org.jboss.as.webservices] (MSC service thread 1-1) JBAS015539: Starting service jboss.ws.port-component-link
12:27:16,555 INFO  [org.jboss.as.webservices] (MSC service thread 1-1) JBAS015539: Starting service jboss.ws.endpoint."Spring_CXF_Service_Demo.war"."ws.Spring_CXF_Service"
12:27:16,571 INFO  [org.jboss.web] (MSC service thread 1-7) registering web context: /Spring_CXF_Service_Demo
12:27:16,594 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 1) JBAS018565: Replaced deployment "Spring_CXF_Service_Demo.war" with deployment "Spring_CXF_Service_Demo.war"

Step13). Now run the command “ant run” in your shell prompt to run the WebService client to access the WebService operation. “ant run” command will automatically build the client side artifacts using the “wsconsume” ant task as well and then it will run the client:

[userone@localhost CXFTimeoutClientDemo]$ ant run
Buildfile: /home/userone/CXF_Spring_Demo/build.xml

client:
   [delete] Deleting directory /home/userone/CXF_Spring_Demo/clientStuff
[wsconsume] Consuming wsdl: http://localhost:8080/Spring_CXF_Service_Demo/Spring_CXF_Service?wsdl
[wsconsume] log4j:WARN No appenders could be found for logger (org.apache.cxf.common.logging.LogUtils).
[wsconsume] log4j:WARN Please initialize the log4j system properly.
[wsconsume] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
      [jar] Building jar: /home/userone/CXF_Spring_Demo/clientStuff/Spring_CXF_Client.jar
      [zip] Updating zip: /home/userone/CXF_Spring_Demo/clientStuff/Spring_CXF_Client.jar

run:
     [javac] Compiling 1 source file to /home/userone/CXF_Spring_Demo/clientStuff
      log4j:WARN No appenders could be found for logger (org.apache.cxf.common.logging.LogUtils).
      log4j:WARN Please initialize the log4j system properly.
      log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
      
      	Got Client: org.apache.cxf.jaxws.JaxWsClientProxy@6ed3199e
      
      	client.sayHello(Middleware Magic): Hello World !!! Mr. Middleware Magic

BUILD SUCCESSFUL
Total time: 9 seconds

.
.
Thanks
MiddlewareMagic Team

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.