XFire

Home
Bug/Issue Reporting
Download
FAQ
Get Involved
License
News
Stack Comparison
Support
User's Guide
XFire Team

M5

Javadocs
Reports

M6-SNAPSHOT

Javadocs
Reports

Developers

Developer Space
CVS
Building
Architecture
Interesting Projects
Release Process

A great feature of XFire is the integration with the Plexus container.

Exposing Components as Services

To have XFire expose your component as a service is fairly easy. If XFire sees that the <serviceClass/> defined in your configuration is an XFire component, it will use that component by doing a lookup() instead of trying to instantiate that object directly via the constructor.

Configuring Services via Plexus

Instead of a services.xml file, you can use Plexus configurations to configure your components. The following example will show a small "Hello World" application that exposes a service using XFire and Plexus and is built using Maven2, so you should install M2 before you start, because it will take the load of dependency handling from you.

Overview

For the Hello World project you need following directory layout:

 
helloworld/
|-- helloworld-application
|   |-- pom.xml
|   `-- src
|       |-- main
|       |   |-- java
|       |   |   `-- org
|       |   |       `-- codehaus
|       |   |           `-- xfire
|       |   |               `-- helloworld
|       |   |                   |-- DefaultHelloWorldService.java
|       |   |                   `-- HelloWorldService.java
|       |   `-- resources
|       |       `-- META-INF
|       |           `-- plexus
|       |               `-- components.xml
|       `-- test
|           `-- java
|-- helloworld-web
|   |-- pom.xml
|   `-- src
|       `-- main
|           `-- webapp
|               `-- WEB-INF
|                   |-- plexus.properties
|                   |-- plexus.xml
|                   `-- web.xml
`-- pom.xml

As you see, the project is split up into two subprojects, helloworld-application which includes the service implementation and configuration and helloworld-web, which is only the web-application. Let's start with the different project descriptors.

Project descriptors

The root project is made up of two modules.

helloworld/pom.xml
<project>
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.codehaus.xfire</groupId>
	<version>1.0</version>
	<artifactId>helloworld</artifactId>
	<packaging>pom</packaging>
	<modules>
    <module>helloworld-application</module>
    <module>helloworld-web</module>
  </modules>
</project>

The web-app's project object model looks like this:

helloworld/helloworld-application/pom.xml
<project>
	<modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.codehaus.xfire</groupId>
		<version>1.0</version>
		<artifactId>helloworld</artifactId>
  </parent>
	<artifactId>helloworld-application</artifactId>
	<packaging>jar</packaging>
  <dependencies>
          <dependency>
                  <groupId>org.codehaus.xfire</groupId>
                  <artifactId>xfire-plexus</artifactId>
                  <version>1.0-SNAPSHOT</version>
          </dependency>
          <dependency>
                  <groupId>plexus</groupId>
                  <artifactId>plexus-container-default</artifactId>
                  <version>1.0-alpha-5-SNAPSHOT</version>
          </dependency>
          <dependency>
                  <groupId>plexus</groupId>
                  <artifactId>plexus-servlet</artifactId>
                  <version>1.0-beta-3-SNAPSHOT</version>
          </dependency>
  </dependencies>
</project>

This subproject extends the parent project and depends on the xfire-plexus module. Normally you wouldn't need to specify the other dependencies, as Maven2 can handle transitive dependencies, but using newer versions of plexus-container-default and plexus-servlet generally leads to better results for me.

The web-application module depends on the application module and extends the parent project:

helloworld/helloworld-web/pom.xml
<project>
	<modelVersion>4.0.0</modelVersion>
	<parent>
    <groupId>org.codehaus.xfire</groupId>
		<version>1.0</version>
		<artifactId>helloworld</artifactId>
  </parent>
	<artifactId>helloworld-web</artifactId>
	<packaging>war</packaging>
	<dependencies>
		<dependency>
			<groupId>org.codehaus.xfire</groupId>
			<artifactId>helloworld-application</artifactId>
			<version>1.0</version>
		</dependency>
	</dependencies>
	<build>
    <finalName>helloworld</finalName>
  </build>
</project>

Here we don't need to specify any dependencies, as Maven2 already knows them from the helloworld-application module.

The Web Services and their configuration

The first step is to define an interface for the Hello World service. This interface offers only one method for now:

helloworld/helloworld-application/src/main/java/org/codehaus/xfire/helloworld/HelloWorldService.java
package org.codehaus.xfire.helloworld;

public interface HelloWorldService {
  String ROLE = HelloWorldService.class.getName();
  
  String helloWorld();
}

The role string in the interface is used later by plexus in order to access the component. An implementation of HelloWorldService is neccessary for execution of the webservice.

helloworld/helloworld-application/src/main/java/org/codehaus/xfire/helloworld/DefaultHelloWorldService.java
package org.codehaus.xfire.helloworld;

public class DefaultHelloWorldService implements HelloWorldService {
  public String helloWorld() {
    return "Hello World";
  }
}

In the configuration section we define the mapping of service interface and service implementation as well

helloworld/helloworld-application/src/main/resources/META-INF/plexus/components.xml
<?xml version="1.0" encoding="UTF-8"?>
<component-set>
	<components>
		<component>
			<role>org.codehaus.xfire.helloworld.HelloWorldService</role>
			<implementation>org.codehaus.xfire.helloworld.DefaultHelloWorldService</implementation>
		</component>
		<component>
			<role>org.codehaus.xfire.plexus.config.ConfigurationService</role>
			<implementation>org.codehaus.xfire.plexus.config.DefaultConfigurationService</implementation>
			<configuration>
				<services>
					<service>
						<name>HelloWorld</name>
						<namespace>http://xfire.codehaus.org/helloworld</namespace>
						<serviceClass>org.codehaus.xfire.helloworld.HelloWorldService</serviceClass>
					</service>
				</services>
			</configuration>
			<requirements>
				<requirement>
					<role>org.codehaus.xfire.plexus.config.Configurator</role>
					<role-hint>annotation</role-hint>
				</requirement>
			</requirements>
		</component>
	</components>
</component-set>

The second component definition is used for defining which components to expose as web services. In the configuration element you specify a service element for every service to expose. A service needs a name, a namespace-URI and a serviceClass. If this class is the role of a component defined elsewhere, plexus will chose the right implementation once the service is requested.

The web application

This module need a web.xml file first which loads the PlexusServlet and defines the XFire-Servlet. You can later on access your service at http://localhost:8080/helloworld/services/Hello

helloworld/helloworld-web/src/main/webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>Hello World Service</display-name>
	<listener>
		<listener-class>org.codehaus.plexus.servlet.PlexusServletContextListener</listener-class>
	</listener>
	<servlet>
		<servlet-name>XFire</servlet-name>
		<display-name>XFire Servlet</display-name>
		<servlet-class>
        org.codehaus.xfire.plexus.PlexusXFireServlet
	</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>XFire</servlet-name>
		<url-pattern>/servlet/XFireServlet/*</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>XFire</servlet-name>
		<url-pattern>/services/*</url-pattern>
	</servlet-mapping>
</web-app>

Finally, the plexus.xml defines which components should be loaded at web-application startup. This is neccessary for loading the components.xml and the enclosed service definitions.

helloworld/helloworld-web/src/main/webapp/WEB-INF/plexus.xml
<?xml version="1.0" encoding="UTF-8"?>
<plexus>
	<load-on-start>
		<component>
			<role>org.codehaus.xfire.plexus.config.ConfigurationService</role>
		</component>
	</load-on-start>
</plexus>

Building and Running

You can build the whole application by running m2 install in the root directory. After deploying helloworld/helloworld-web/target/helloworld.war to your servlet container, you can access the web service at http://localhost:8080/helloworld/services/Hello or get an WSDL service description at http://localhost:8080/helloworld/services/Hello?wsdl.