Developers, Developers, Developers! Maksim Sorokin IT Blog

13Jan/11Off

Axis2 + Maven + Servlets + Tomcat

In this post I will show how to combine axis2 web services with maven and a war project and make it run under Tomcat 6.

We will try to avoid holding auto-generated sources, instead we will generate them and compile whenever they are needed. We will also try to make the whole process as automatic, as possible.

Start by creating a new maven project axis2Example. It will be a war project and our initial pom.xml file looks like the following:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>dk.sorokin.maksim</groupId>
  <artifactId>axis2Example</artifactId>
  <packaging>war</packaging>
  <version>1.0.0-SNAPSHOT</version>

  <name>Axis2 Example</name>

  <dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
</project>

Also, since it is a war project, we need to create web.xml file in src/main/webapp/WEB-INF. Let's start with:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_3_0.xsd"
  version="3.0">
  <display-name>axis2Example</display-name>
</web-app>

Now, we can try to create our initial web service. Create a package in src/main/java called axis2Example.ws. Let's create a web service HelloWs, which would have a method sayHello. We will pass a name to this method and it will return a greeting message to us:

package axis2Example.ws;

public class HelloWs {

  public String sayHello(String name) {
    if (name == null) {
      return "Hello";
    }

    return "Hello, " + name + "!";
  }
}

Now, we will generate a wsdl file for our future web service. Then we will copy this generated wsdl file to our project (that is the only saving of generated file!). Later on we will auto-generate axis2 classes for this wsdl file to have a web service handler. I will explain later on why we cannot do wsdl generation automatically and then use it as a source for axis2 classes generation.

We will use Maven2 Java2WSDL Plug-in to do that. Modify pom.xml to the following:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>dk.sorokin.maksim</groupId>
  <artifactId>axis2Example</artifactId>
  <packaging>war</packaging>
  <version>1.0.0-SNAPSHOT</version>

  <name>Axis2 Example</name>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.axis2</groupId>
        <artifactId>axis2-java2wsdl-maven-plugin</artifactId>
        <version>1.5.4</version>
        <executions>
          <execution>
            <phase>process-classes</phase>
            <goals>
              <goal>java2wsdl</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <className>axis2Example.ws.HelloWs</className>
		  <outputFileName>${project.build.directory}/HelloWs.wsdl</outputFileName>
        </configuration>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>3.0</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
</project>

We bind wsdl file generation to process-classes phase, because otherwise we have a NullPointerException problem caused by ClassNotFoundException. Unfortunately, we do not know the reason of it.

Then we just run

mvn clean install

And as a result we will have our generated HelloWs.wsdl file in target. Copy it and place into src/main/webapp folder, so it can be accessible by users. We will also need it for axis2 files generation.

Comment out phase process-classes of axis2-java2wsdl-maven-plugin because we will not need it. Or just remove the whole plugin from pom.xml. However, it is advisable to keep it for later usage. Also, it is possible to write custom one or use other tools for generation, just refer to axis2 website.

Now it is time to plug-in axis2 in our project. Add the following dependencies to your pom.xml file:

<dependency>
  <groupId>org.apache.axis2</groupId>
  <artifactId>axis2</artifactId>
  <version>1.5.4</version>
</dependency>

<dependency>
  <groupId>org.apache.axis2</groupId>
  <artifactId>axis2-transport-http</artifactId>
  <version>1.5.4</version>
</dependency>

<dependency>
  <groupId>org.apache.axis2</groupId>
  <artifactId>axis2-transport-local</artifactId>
  <version>1.5.4</version>
</dependency>

<dependency>
  <groupId>org.apache.xmlbeans</groupId>
  <artifactId>xmlbeans</artifactId>
  <version>2.4.0</version>
</dependency>

And modify web.xml to the following:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_3_0.xsd"
  version="3.0">
  <display-name>axis2Example</display-name>

  <servlet>
    <servlet-name>AxisServlet</servlet-name>
    <servlet-class>org.apache.axis2.transport.http.AxisServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>/services/*</url-pattern>
  </servlet-mapping>
</web-app>

Now we need to create a axis2 service.xml file, which would describe our web service. Create the following folder structure: src/main/webapp/WEB-INF/services/HelloWs/META-INF. And create the following services.xml file in that folder:

<serviceGroup>
  <service name="HelloWs" targetNamespace="http://ws.axis2Example/">
    <description>JNLPGenerator service</description>
    <schema schemaNamespace="http://ws.axis2Example/" />
    <parameter name="ServiceClass" locked="false">axis2Example.ws.HelloWs</parameter>
    <operation name="sayHello">
      <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
    </operation>
  </service>
</serviceGroup>

And now we need to auto-generate axis2 sources files and compile them in compile phase of maven build lifecycle. Add the following to the plugins section:


  <plugin>
	<groupId>org.apache.axis2</groupId>
	<artifactId>axis2-wsdl2code-maven-plugin</artifactId>
	<version>1.5.4</version>
	<executions>
	  <execution>
		<phase>generate-sources</phase>
		<goals>
		  <goal>wsdl2code</goal>
		</goals>
	  </execution>
	</executions>
	<configuration>
	  <classpathElements>${project.build.outputDirectory}</classpathElements>
	  <wsdlFile>src/main/webapp/HelloWs.wsdl</wsdlFile>
	  <databindingName>xmlbeans</databindingName>
	  <packageName>axis2Example.ws</packageName>
	</configuration>
  </plugin>

  <plugin>
	<groupId>org.codehaus.mojo</groupId>
	<artifactId>build-helper-maven-plugin</artifactId>
	<executions>
	  <execution>
		<phase>generate-sources</phase>
		<goals>
		  <goal>add-source</goal>
		</goals>
		<configuration>
		  <sources>
			<source>${project.build.directory}/axis2/wsdl2code/src</source>
		  </sources>
		</configuration>
	  </execution>
	</executions>
  </plugin>

And that is it. Just run mvn clean install and put your war file to webapps on Tomcat. Your web service should be available at http://localhost:8080/axis2Example/services/HelloWs/.

Axis2 also provides possibility to test web services through urls. In your browser type:


http://localhost:8080/axis2Example/services/HelloWs/sayHello?name=Max

And you should see as a response:

Hello, Max

If you need to pass xmls around instead of strings, in your web service methods you should pass org.apache.axiom.om.OMElement type of objects around:

package axis2Example.ws;

import org.apache.axiom.om.OMElement;

public class HelloWs {

  public OMElement sayHello(OMElement name) {

More information can be found on official axis2 website.

Now explanation why we cannot generate wsdl on the fly and use it as a source for axis2 code generation. The problem is that in order to generate wsdl file, we need to have web service class already compiled. But we want to compile auto-generated code too. In this case we would need to modify the lifecycle and have two compilation points, which may be unappropriate.

In next post I plan to describe how to use Guice together with axis2 in servlets. Sagara's blog post seems to be a little outdated now.

Here are the sources of the axis2Example

Comments (17) Trackbacks (1)
  1. Hi,

    Thanks a lot for this, it’s really helpful.

    I’m stuck at the auto-generating the axis2 sources, though. I get a compilation error:
    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.0.2:compile (default-compile) on project axis2Example: Compilation failure: Compilation failure:
    [workspace]\axis2Example\target\generated-sources\axis2\wsdl2code\src\org\xmlsoap\schemas\soap\encoding\NOTATION.java:[16,53] package org.apache.xmlbeans does not exist

    Seems like maven is unable to resolve the xmlbeans dependency. I searched in the maven repository and changed the version to 2.3.0. And while maven can find xmlbeans.jar (I can see it in my local repository), it seems it doesn’t do anything with that jar.

    I’m using Eclipse and m2eclipse, if that has any effect on the results. (I’ve had to tweak a bit pom.xml, and add the [dependencyManagement] tag to wrap [dependencies] in order for this project to work.)

    Can you help me with this? I don’t quite get what I’m doing wrong.

  2. Hi, Sam! Thanks for you comment.

    Did you try downloading the sources (link is in the bottom of the post)? I downloaded them and run mvn install without any problems.

    Btw, you specified wrong email.

  3. Hi, Marksim. Thanks for your promp response and help!

    Yes, I’ve downloaded the sources and mvn install gives me the same result. Maven insists in the non-existence of org.apache.xmlbeans.

    I’m not sure what I’m doing wrong here.

  4. Sam, I tried it on completely fresh machine with Maven 2.2.1 and 3.0. I have experienced only one unrelated problem — servlet-api was not found (when I wrote this article, I used internal m2 repository with manually added servlet-api 3.0, which is not present on maven central). But other then that it was built without any errors.

  5. Maksim,

    I’ll try to do this on another machine, see if I can persuade a friend to help me with this.

    Thanks again! Will get back to you.

    (e-mail fixed, btw :)

  6. Maksim,

    I’ve borrowed a friend’s machine and tried it there with a fresh install. It worked fine, so the problem seems to be on my machine.

    Thanks for your help!

  7. Hello,

    Good tutorial, I have rebuilded project and run maven commands. When I launch the my web application in browser, I have an exception. Have you an idea ?

    I uses , Tomcat 6

    Below the stack trace :
    GRAVE: The service cannot be found for the endpoint reference (EPR) /axis2Example-1.0.0-SNAPSHOT/services/HelloWs
    org.apache.axis2.AxisFault: The service cannot be found for the endpoint reference (EPR) /axis2Example-1.0.0-SNAPSHOT/services/HelloWs
    at org.apache.axis2.engine.DispatchPhase.checkPostConditions(DispatchPhase.java:65)

    Thanks Pierre-Bruno,

  8. I think you can find the answer here. I usually use tcpmon in simple JNLP version to detect what goes wrong. Unfortunately, I cannot tell you more information from error message that you provided.

  9. Hi,

    Thank you for this great tutorial.

    But, I have the same mistake either in eclipse(m2) or from the command line after downloading your code and doing mvn clean install

    Not too much info in internet.

    Retrieving document at ‘src/main/webapp/HelloWs.wsdl’.
    java.lang.RuntimeException: XMLBeans framework jars not in classpath
    at org.apache.axis2.wsdl.codegen.extension.XMLBeansExtension.engage(XMLB
    at org.apache.axis2.wsdl.codegen.CodeGenerationEngine.generate(CodeGener
    at org.apache.axis2.maven2.wsdl2code.WSDL2CodeMojo.execute(WSDL2CodeMojo
    at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPlugi
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(Defa
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLi
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(Defau
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHan
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegmen
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLi
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
    at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:6
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
    at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
    at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
    at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
    [INFO] ————————————————————————
    [ERROR] BUILD ERROR
    [INFO] ————————————————————————
    [INFO] java.lang.RuntimeException: XMLBeans framework jars not in classpath

    I have set all variables in windows 7 for xmlbeans, which is working from the command line.

    I hope you may help me.
    Thank you for your time.

  10. j, I do not know the root of this problem. I tried my sources on clean machine and other guys tried it too and everything worked. So probably something is wrong with your setup.

    As it says “XMLBeans” are not in the classpath, so you have to make sure, that xmlbeans is available during the build.

  11. ufff, it is working now!!!!
    First, I tried in ubuntu in a new maven instalation and no problems.

    So I did some cleaning, I mean, delete maven folder. Unzip and copy again to have maven. And I deleted .m2 folder.

    After downloading for a few minutes, mvn clean install is working.

    easy job, and very efficient, greattttt

    Thank you for your time again.

  12. Great tutorial, but why need to generate WSDL in compile time? Axis do it in runtime:
    at url …/services/HelloWs?wsdl

  13. Thanks for your comment, Alex.

    We actually do not need to regenerate wsdl at each build. We just need it in order to generate axis2 sources. These generated axis2 sources are compiled together with the application.

  14. very use full article

  15. I’m curious what does

    ${project.build.outputDirectory}

    do? Tried running without it, and no diff. Btw, great article!

  16. Sorry, forgot to escape the tags,
    <classpathElements>${project.build.outputDirectory}</classpathElements>

    From the axis2-wsdl2code-maven-plugin config

    thanks to http://www.rishida.net/tools/conversion/

  17. Hi I have tried all the steps given above and deployed the war file successfully.
    When I try to hit “http://localhost:8080/axis2Example-1.0.0-SNAPSHOT/” I am getting “hello” message

    But when I hit http://localhost:8080/axis2Example/services/HelloWs/sayHello?name=Max or http://localhost:8080/axis2Example/
    Iam getting 404 page
    Can some one please help me out


Leave a comment