XFIRE+EJB+POJO

Full Maven Project.

This article brings together Spring and XFire configuration examples to show how to expose simple POJO into SOAP service with EJB façade in between.

Lets take a simple example of number add and subtract service.

Here is component diagram of what we are trying to achieve.


To accomplish the above setup we’ll follow these simple steps.

Create NumberService interface and implementation.


public interface NumberService{

 public int add(int n1, int n2);

 public int substract(int n1, int n2);
}

public class NumberServiceImpl implements NumberService{

 public int add(int n1, int n2){
  return n1 + n2;
 }

 public int substract(int n1, int n2){
  return n1 - n2;
 }
}

Create app-context.xml (you can name this file anything you want).

Since we are using Spring Framework it just makes sense to define the NumberServiceImpl in spring context file to be later injected into NumberServiceSessionBean. This will allow us to decouple
NumberServiceSessionBean from NumberServiceImpl. Here is the full context file called app-context.











Make sure this file is in classpath for EJB to load.

Create NumberServiceSessionBean


import java.rmi.RemoteException;
import javax.ejb.CreateException;

import org.springframework.ejb.support.AbstractStatelessSessionBean;

public class NumberServiceSessionBean extends AbstractStatelessSessionBean{
 private NumberService numberService = null;

 protected void onEjbCreate() throws CreateException{
  numberService = (NumberService)getBeanFactory().getBean("numberService");
 }

 public int add(int n1, int n2) throws RemoteException {
  return numberService.add(n1, n2);
 }

 public int substract(int n1, int n2) throws RemoteException {
  return numberService.substract(n1, n2);
 }
}

Here are few things worth to mention.

  • It extends Spring helper AbstractStatelessSessionBean class which will load spring context behind the scene and expose it through
    BeanFactory getBeanFactory() method.
    Some might ask how it knows which context file to load? Well in order to tell the AbstractStatelessSessionBean the location of context file we need to define it in EJB deployment (called ejb-jar.xml ) file like this.

    
    
    ejb/BeanFactoryPath java.lang.String
  • Each NumberServiceSessionBean instance will load context file separately and will have its own instance of NumberServiceImpl.
  • It does not directly implement NumberService but implements the exact methods. The reason behind this is two-part. First it is the infamous issues of the need to declare RemoteException in NumberService. Second one will be explainined later when we expose it as proxy to Xfire servlet.

Create XFire web component.
For XFire to be able to receive SOAP calls we need to configure it as Servlet.

What we are going to do is again leverage Spring Framework by reusing its org.springframework.web.servlet.DispatcherServlet and expose XFire to it as Spring MVC controller.

The good news is that XFire already provides implementation of this controller in “org.codehaus.xfire.spring.remoting.XFireExporter” class.

To have complete web application we need to create web.xml and Spring nameservice-context.xml file that will contain Controller and EJB proxy definitions.
Put both under WEB-INF directory.

web.xml








nameservice

org.springframework.web.servlet.DispatcherServlet

1



nameservice 
/*




Once deployed and loaded in Servlet container DispatcherServlet will assume there is Spring context file under WEB-INF directory with name {servlet-name}-servlet.xml
which is in our case nameservice-servlet.xml.

nameservice-servlet.xml














NameServiceSessionHome



weblogic.jndi.WLInitialContextFactory



false





false


NameService





rpc


encoded










 



NameService
















Finally to test your WebService invoke http://localhost:7001/nameservice?wsdl which will generate the WSDL.

Included with the war project is JUnit test that uses Spring and XFireClientFactoryBean to remotely call XFire service using Spring and XFire proxies. For more detailed tutorial
on XFireClientFactoryBean check http://xfire.codehaus.org/Spring+Remoting.

The unit test requires “commons http client” libraries, so make sure to include them as dependencies in your war as is done in attached maven projects.

Full maven project can be downloaded from HERE.

Build Instructions

  • This project is based on Maven2. Currently standard Maven2 remote repositories dont have xfire-all-1.2.2.jar. You might need to manually get it from here and put into your local repository under xfirexfire-all1.2 directory.
  • If you are going to deploy it to Weblogic it wont work unless resolve QName issue as shown here.

9 comments to XFIRE+EJB+POJO

  • Radu

    Tsolak,

    Thanks a lot for your guide and diagram – it does help make things clear a bit.

    I hope you don’t mind a few quesstions from a newbie to xfire/spring:

    – Does one have to use rpc/encoded or can one use
    doc/literal with the above scenario?

  • tsolakp

    Yes multiple styles/encodes are supported. For style you can use the following values “document|rpc|message|wrapped” and “literal|encoded” for use property.

    Here is the link to full reference.

  • Radu

    Tsolak,

    I did successfully deployed to weblogic 8.1.4. I modified the ejb pom (see below). But my problem is that I can not get wsdl to be displayed at http://localhost:7001/numberservice-ear-1.0.0/numberservice?wsdl
    (my ear name is numberservice-ear-1.0.0.ear)

    ejb pom.xml
    ————–

    4.0.0
    numberservice-ejb
    ejb
    1.0.0
    EJB Facade for NumberService
    EJB Facade for NumberService.

    samples
    samples
    1.0.0

    maven-antrun-plugin

    package

    ************** RUNNING WEBLOGIC EJBC ****************

    run

    ant
    ant-antlr
    1.6.5

    commons-logging
    commons-logging
    1.0.4
    jar

    org.springframework
    spring-core
    1.2.8
    jar

    org.springframework
    spring-aop
    1.2.8
    jar

    org.springframework
    spring-beans
    1.2.8
    jar

    org.springframework
    spring-context
    1.2.8
    jar

    org.springframework
    spring-remoting
    1.2.8
    jar

    javax.ejb
    ejb
    2.1
    provided

    ${pom.groupId}
    1.0.0
    numberservice-jar
    jar

  • tsolakp
    • Updated main pom to include files from “config” and “resources” directories into jar.
    • Updated war pom to included “commons http client” and upgraded to xfire-all-1.2.2.jar libraries to make JUnit work.
  • Mike Miller

    I found this blog/article on the Articles list in the XFire documentation. I need to expose an EJB’s method as a Web Service BUT we do not use Spring. Our application is a server with Swing clients started thru WebStart.

    How would I modify what you have documented here in order to expose my EJB as a web service from XFire?

  • tsolakp

    You can bypass Spring config file and manually create spring beans, proxies and servlet.

    Or hopefully this article might help you:

    http://xfire.codehaus.org/Invokers

  • Is there a chance this article can be re-written but using the CXF stack?

  • tsolakp

    I probably can. Might be in a few weeks.

  • Here is how to do with CXF.

    […] Full maven project can be downloaded from HERE. This is a follow up article to XFIRE+EJB+POJO. Here I show how to expose POJO using CXF project instead of XFire. Setting up WebServices with CXF is very easy and consists of two steps: […]

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>