In this blog I'll show you how you can create a WebService of your EJB3 objects by using anotations. I will also show you how to build and deploy the package with Maven2. Let's start with the initial situation.
I have installed JBoss 4.2.1 and Maven2. In my settings.xml of Maven2 I have set a property pointing to my JBoss installation and I have defined a JBoss/Maven2 repository.

The settings.xml file looks like this:

XML:
  1. <settings>
  2.   <localRepository>d:/maven2/repo/</localRepository>
  3.   <profiles>
  4.     <profile>
  5.       <id>default-repositories</id>
  6.       <repositories>
  7.         <repository>
  8.           <id>global</id>
  9.           <name>External Mirror of Central Repository</name>
  10.           <url>http://repo1.maven.org/maven2</url>
  11.         </repository>
  12.         <repository>
  13.           <id>repo.maven</id>
  14.           <url>http://repo1.maven.org/maven2-repoclean-java.net</url>
  15.         </repository>
  16.         <repository>
  17.           <id>jboss.maven</id>
  18.           <url>http://repository.jboss.com/maven2/</url>
  19.         </repository>
  20.       </repositories>
  21.       <pluginRepositories>
  22.         <pluginRepository>
  23.           <id>repo1org</id>
  24.           <name>External Plugin Repository</name>
  25.           <url>http://repo1.maven.org/maven2/</url>
  26.         </pluginRepository>
  27.       </pluginRepositories>
  28.     </profile>
  29.     <profile>
  30.       <id>property-overrides</id>
  31.       <properties>
  32.         <jboss.home>C:\java\jboss-4.2.1.GA</jboss.home>
  33.       </properties>
  34.     </profile>
  35.   </profiles>
  36.   <activeProfiles>
  37.     <activeProfile>property-overrides</activeProfile>
  38.     <activeProfile>default-repositories</activeProfile>
  39.   </activeProfiles>
  40. </settings>

Lateron we'll see that Maven uses the JBoss plugin and the property for the deployment of our application.

I have created a project 'my-ejb-project' with a simple EJB session bean. The bean (and it's interface) looks like this:

JAVA:
  1. package net.pascalalma.services;
  2.  
  3. import javax.ejb.Remote;
  4.  
  5. public interface EchoService {
  6.  
  7.     public String sayHello(String subject);
  8. }

and the implementation:

JAVA:
  1. package net.pascalalma.services.impl;
  2.  
  3. import javax.ejb.Stateless;
  4.  
  5. import net.pascalalma.services.EchoService;
  6.  
  7. @Stateless
  8. public class EchoServiceBean implements EchoService {
  9.  
  10.     public String sayHello(String name)
  11.     {
  12.         return "Hi " + name + "!";
  13.     }
  14. }

To build this project I have this in the project's pom.xml file:

XML:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  5.     <modelVersion>4.0.0</modelVersion>
  6.     <groupId>net.pascalalma</groupId>
  7.     <artifactId>my-ejb-project</artifactId>
  8.     <version>1.0</version>
  9.     <packaging>ejb</packaging>
  10.  
  11.     <build>
  12.         <sourceDirectory>src/main/java</sourceDirectory>
  13.         <finalName>my-ejb-project</finalName>
  14.         <plugins>
  15.             <plugin>
  16.                 <artifactId>maven-compiler-plugin</artifactId>
  17.                 <configuration>
  18.                     <source>1.5</source>
  19.                     <target>1.5</target>
  20.                 </configuration>
  21.             </plugin>
  22.             <plugin>
  23.                 <groupId>org.apache.maven.plugins</groupId>
  24.                 <artifactId>maven-javadoc-plugin</artifactId>
  25.                 <configuration>
  26.                     <classpath>/src/main/java</classpath>
  27.                 </configuration>
  28.             </plugin>
  29.             <plugin>
  30.                 <artifactId>maven-ejb-plugin</artifactId>
  31.                 <configuration>
  32.                     <ejbVersion>3.0</ejbVersion>
  33.                     <archive>
  34.                         <manifest>
  35.                             <addClasspath>true</addClasspath>
  36.                         </manifest>
  37.                     </archive>
  38.                 </configuration>
  39.             </plugin>
  40.         </plugins>
  41.     </build>
  42.     <dependencies>
  43.         <dependency>
  44.             <groupId>org.apache.geronimo.specs</groupId>
  45.             <artifactId>geronimo-jpa_3.0_spec</artifactId>
  46.             <version>1.1</version>
  47.             <scope>provided</scope>
  48.         </dependency>
  49.         <dependency>
  50.             <groupId>org.apache.geronimo.specs</groupId>
  51.             <artifactId>geronimo-ejb_3.0_spec</artifactId>
  52.             <version>1.0</version>
  53.             <scope>provided</scope>
  54.         </dependency>
  55.         <dependency>
  56.             <groupId>junit</groupId>
  57.             <artifactId>junit</artifactId>
  58.             <version>4.1</version>
  59.             <scope>test</scope>
  60.         </dependency>
  61.     </dependencies>
  62.     <reporting>
  63.         <plugins>
  64.             <plugin>
  65.                 <groupId>org.apache.maven.plugins</groupId>
  66.                 <artifactId>maven-surefire-report-plugin</artifactId>
  67.             </plugin>
  68.             <plugin>
  69.                 <groupId>org.apache.maven.plugins</groupId>
  70.                 <artifactId>maven-jxr-plugin</artifactId>
  71.             </plugin>
  72.         </plugins>
  73.     </reporting>
  74. </project>

Besides this ejb-project I have also created a ear-project that is used to create an ear file containing the EJB's jar file (and optionally other deliverables like war-file etc). The pom file of this project looks like (the project doesn't contain anything else):

XML:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  5.     <modelVersion>4.0.0</modelVersion>
  6.     <groupId>net.pascalalma</groupId>
  7.     <artifactId>my-ear-project</artifactId>
  8.     <packaging>ear</packaging>
  9.     <version>1.0</version>
  10.     <name>my-ear-project</name>
  11.     <dependencies>
  12.         <dependency>
  13.             <groupId>net.pascalalma</groupId>
  14.             <artifactId>my-ejb-project</artifactId>
  15.             <version>1.0</version>
  16.             <type>ejb</type>
  17.         </dependency>
  18.     </dependencies>
  19.     <build>
  20.         <plugins>
  21.             <plugin>
  22.                 <groupId>org.codehaus.mojo</groupId>
  23.                 <artifactId>jboss-maven-plugin</artifactId>
  24.                 <configuration>
  25.                     <jbossHome>${jboss.home}</jbossHome>
  26.                     <serverName>default</serverName>
  27.                     <port>8080</port>
  28.                 </configuration>
  29.             </plugin>
  30.             <plugin>
  31.                 <artifactId>maven-ear-plugin</artifactId>
  32.                 <configuration>
  33.                     <displayName>My EJB Component</displayName>
  34.                     <description>My EJB Component</description>
  35.                     <version>1.4</version>
  36.                     <modules>
  37.                         <ejbModule>
  38.                             <groupId>net.pascalalma</groupId>
  39.                             <artifactId>my-ejb-project</artifactId>
  40.                         </ejbModule>
  41.                     </modules>
  42.                 </configuration>
  43.             </plugin>
  44.         </plugins>
  45.     </build>
  46. </project>

With all this in place we are able to build the EJB3 project with the command:
c:\workspace\my-ejb-project\mvn clean install
and to package and deploy the EAR project with:
c:\workspace\my-ear-project\mvn clean package jboss:harddeploy

To make our EJB3 bean available as a webservice, we have to add some annotations to the source, so the code of the interface and the bean will become something like this:

JAVA:
  1. package net.pascalalma.services;
  2.  
  3. import javax.ejb.Remote;
  4. import javax.jws.WebService;
  5.  
  6. @WebService()
  7. public interface EchoService {
  8.  
  9.     public String sayHello(String subject);
  10. }

and the implementation class:

JAVA:
  1. package net.pascalalma.services.impl;
  2.  
  3. import javax.ejb.Stateless;
  4. import javax.jws.WebService;
  5. import javax.jws.soap.SOAPBinding;
  6.  
  7. import net.pascalalma.services.EchoService;
  8.  
  9. @Stateless
  10. @WebService(endpointInterface = "net.pascalalma.services.EchoService",serviceName="EchoService")
  11. @SOAPBinding(style = javax.jws.soap.SOAPBinding.Style.DOCUMENT)
  12. public class EchoServiceBean implements EchoService {
  13.     @javax.jws.WebMethod()
  14.     public String sayHello(String name)
  15.     {
  16.         return "Hi " + name + "!";
  17.     }
  18. }

That's it! The only thing left is that we have to add a new dependency to the pom (for the javax.jws.*). The dependency looks like:

XML:
  1. <dependency>
  2.       <groupId>xfire</groupId>
  3.       <artifactId>xfire-jsr181-api</artifactId>
  4.       <version>1.0-M1</version>
  5.       <scope>provided</scope>
  6.     </dependency>

As you can see the dependency has the scope 'provided' because the library is already available in JBoss, so we don't want to package it in our jar file.

Now rebuild and redeploy the packages and it is done!

To test the webservice I use my favorite tool 'Soap UI'. We can generate the necessary WSDL at runtime by going to the url: 'http://127.0.0.1:8080/EchoServiceBeanService/EchoServiceBean?wsdl'. The result in SOAP UI looks like this:
Soap request

After sending the request we will get this respone:
soap response

I hope this post makes clear that is easy to make your EJB3 session beans available as a webservice, by simply adding some annotations to your code.