Emil Genov bio photo

Emil Genov

Software developer living in Barcelona

LinkedIn Github Stackoverflow

 NOT WORKING
This still does not work, look at Codehaus issue, when this is resolved is worth trying again

 

Project structure and contents

Template project is attached to this page, feel free to use it and update it.

As all Java WS are deployed as WAR file, at some point your project must create one. Here some guidelines how to have a one that works:

  • In WEB-INF/web.xml file, XFireSpring servlet is instantiated. For it's parameter contextConfigLocation, we specify spring config file that will be discussed in next step. Mappings are usual one, this file is same as the one used for working of Spring with XFire:
    <?xml version="1.0" encoding="ISO-8859-1"?>

    <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

    <display-name>XFire</display-name>

    <context-param>
    <param-name>contextConfigLocation</param-name> (1)
    <param-value>classpath:xfire-servlet.xml</param-value>
    </context-param>

    <servlet>
    <servlet-name>XFireServlet</servlet-name> (2)
    <display-name>XFire Servlet</display-name>
    <servlet-class>
    org.codehaus.xfire.spring.XFireSpringServlet
    </servlet-class>
    </servlet>

    <servlet-mapping>
    <servlet-name>XFireServlet</servlet-name> (3)
    <url-pattern>/servlet/XFireServlet/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
    <servlet-name>XFireServlet</servlet-name>
    <url-pattern>/services/*</url-pattern>
    </servlet-mapping>

    <listener>
    <listener-class>
    org.springframework.web.context.ContextLoaderListener (4)
    </listener-class>
    </listener>

    </web-app>


    • (1) Defines that file xfire-servlet.xml, will be automatically available to Spring. Will define this in next section.
    • (2) Define XFireServlet
    • (3) Map it to XXX/services/... path, where XXX will be WAR name
    • (4) Add context listener, so Spring will auto-load xfire-servlet.xml file, see Spring documentation for more detail


  • Create Spring file (I have named it xfire-servlet.xml) for configuring XFire services. Put it in classpath.
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>

    <bean id="webAnnotations"
    class="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations" /> (1)
    <bean id="handlerMapping"
    class="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping"> (2)
    <property name="typeMappingRegistry">
    <ref bean="typeMappingRegistry" />
    </property>
    <property name="xfire">
    <ref bean="xfire" />
    </property>
    <property name="webAnnotations">
    <ref bean="webAnnotations" />
    </property>
    </bean>

    <bean
    class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="urlMap">
    <map>
    <entry key="/">
    <ref bean="handlerMapping" />
    </entry>
    </map>
    </property>
    </bean>

    <bean id="typeMappingRegistry"
    class="org.codehaus.xfire.jaxb2.JaxbTypeRegistry" (3)
    init-method="createDefaultMappings" singleton="true">
    </bean>


    <import resource="classpath:org/codehaus/xfire/spring/xfire.xml" /> (4)
    <import resource="classpath:webservices.xml" /> (5)
    </beans>


    • (1) Defines usage JSR 181 Anotations
    • (2) Defines same for mapping
    • (3) Defines usage of JAXB2. This is very important. Without it XFire will use AEGIS binding, which gives unpleasant effects of creating non-existent namespaces for schema element with unbounded type in WSDL
    • (4) Includes xfire.xml spring configuration file residing in xfire-all.jar
    • (5) Includes our own spring configuration file which defines all beans that will be exposed as service. The same will be done for every bean instantiated by Spring, that is JSR 181 anotated, so this file is not strictly needed, but is good to group all WS implementation beans instantiations in same configuration file. This is discussed in next paragraph.


  • Create spring config file (webservice.xml) for instantiation of service implementations and exporters:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
    <bean id="XfireContractFirst" class="org.example.xfirecontractfirst.XfireContractFirstImpl" /> (1)
    </beans>

    (1) This is instantiation of WS implementation class, which must have JSR-181 Annotations in it.


  • In lib folder You should have following jars:

    • xfire-all-1.2.2.jar
    • xfire-jsr181-api-1.0-M1.jar
    • activation.jar
    • commons-logging-1.0.4.jar
    • mailapi_1_3_1.jar
    • jdom-1.0.jar
    • stax-api-1.0.1.jar
    • wsdl4j-1.5.1.jar
    • wstx-lgpl-3.0.2.jar
    • log4j-1.2.8.jar
    • spring.jar

  • Make sure that server runs Java 5, because of use of annotations
  • For creating WAR this ant code fragment could be used:
    <war warfile="webservice.war" webxml="webcontent/web.xml">
    <zipfileset dir="lib" prefix="WEB-INF/lib" />
    <zipfileset dir="bin" prefix="WEB-INF/classes"/>
    </war>

 


Adding a new WS


Once you have all this plumbing code set in place, adding a new WS is just a song:


  • Just create interface and implentation of service
  • Annotate them with JSR-181 annotations
  • And add a line in webservices.xml file

It's simple as that

 

Example project


All this can be seen in attached example ws project. Just unpack it, add needed libs (see for list up) from current (version >= 1.2.4) XFire distribution, and run ant which will create WS implementation classes from WSDL, compile them and generates WAR file. Deploy this file to Application server and test deployed WS.