Maven setup for Axis2 service development

There are many resources on the Net giving how to write an Axis2 service. And of course internals of Axis2 itself. This is a simple guide that aims to provide info on howto setup the build environment so that you can get a deployable artifact of an Axis2 service.

  1. For the most part you’ll be starting after generating Java code against a given WSDL. Generate code with the same version of Axis2 that you’ll be using to deploy this service. Evil things will happen otherwise.
  2. After this, you can create a skeleton maven project using the maven quickstart archetype.
    $ mvn archetype:generate -DgroupId=com.example.myproject -DartifactId=mysuper-service -DpackageName=org.example.myproject -Dversion=1.0-SNAPSHOT
    

    In the next screen you just have to press enter the selected archetype is the quickstart archetype. Then you can select an appropriate version number for the project followed by the package name. Now you should have a skeleton maven project where you can run mvn clean install and it’ll successfully build it.

  3. Now you can copy the generated classes to mysuper-service/src/main/java and start developing your services.
  4. To generate an Axis2 .aar file you have to tell maven to build a .aar file using the maven aar plugin.
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.axis2</groupId>
                    <artifactId>axis2-aar-maven-plugin</artifactId>
                    <version>1.4</version>
                    <extensions>true</extensions>
                    <configuration>
                        <servicesXmlFile>${basedir}/resources/services.xml</servicesXmlFile>
                        <wsdlFile>${basedir}/resources/test.wsdl</wsdlFile>
                        <fileSets>
                            <fileSet>
                                <directory>${basedir}/lib</directory>
                                <outputDirectory>lib</outputDirectory>
                                <includes>
                                    <include>*.jar</include>
                                </includes>
                            </fileSet>
                        </fileSets>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    

    Here, I've included a lib folder as well, which contains 3rd party .jar files that's not available on a maven repo. Once you've added the lib folder containing a set of .jar files you can add the dependency later using something like,

    <dependency>
                <groupId>com.example.myjar</groupId>
                <artifactId>jarfile</artifactId>
                <version>1.0</version>
                <scope>system</scope>
                <systemPath>${basedir}/lib/the-other-awesome-project.jar</systemPath>
    </dependency>
    

    When you're specifying a 3rd party JAR dependency even though the actual JAR file might not contain a version number, you have to include something in the <version> element. Otherwise maven will not work correctly.

Now, when you type $ mvn clean install you should have a .aar file in the target folder. You can upload this to Axis2 and your services will be deployed in a few seconds.

Building within the IDE

An IntelliJ IDEA project file for your project can be easily generated with $ mvn idea:idea. But if you project use maven, you have to install IntelliJ IDEA maven 2 integration plugin. This can be done using the IDEA plugin browser. Even after adding my root pom.xml to Maven-2 Build in IDEA, I was only able to compile all the classes. I couldn't get any maven plugin goals to be executed. So, Ctrl+F9 still doesn't generate the .aar file.

As it turns out, you need to install Maven Reloaded plugin to be able to execute maven plugin goals. After installing this, the execution process dies with exit status 1 without any helpful remarks.

Codegen and runtime Axis2 versions

I was bitten by this error a couple of times I thought of blogging it for my own reference. It’s important to remember that when you’re generating code against some WSDL, you have to use the same version of Axis2 that you’re going to deploy this service on. So, when you’re running WSDL2Java.sh that should come from a Axis2 distribution that is used in the application server that your service will get deployed. Otherwise, if the Axis2 versions differ you’ll see the following error message.

java.lang.AbstractMethodError
	at org.apache.axis2.databinding.ADBDataSource.serialize(ADBDataSource.java:90)
	at org.apache.axiom.om.impl.llom.OMSourcedElementImpl.internalSerialize(OMSourcedElementImpl.java:691)
	at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.java:965)
	at org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.serializeInternally(SOAPEnvelopeImpl.java:283)
	at org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.internalSerialize(SOAPEnvelopeImpl.java:245)
	at org.apache.axiom.om.impl.llom.OMSerializableImpl.serializeAndConsume(OMSerializableImpl.java:193)
	at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:79)
	at org.apache.axis2.transport.http.CommonsHTTPTransportSender.sendUsingOutputStream(CommonsHTTPTransportSender.java:361)
	at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:238)
	at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:443)
	at org.apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.java:43)
	at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:114)
	at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:178)
	at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:173)
	at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:144)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
	at org.eclipse.equinox.http.servlet.internal.ServletRegistration.handleRequest(ServletRegistration.java:90)
	at org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:111)
	at org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:67)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
	at org.wso2.carbon.bridge.BridgeServlet.service(BridgeServlet.java:154)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:870)
	at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
	at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:685)
	at java.lang.Thread.run(Thread.java:619)

PaaS and open source

Ted Leung has some interesting ideas about Platform As a Service (PaaS) and open source. I agree with Ted that open source software is not becoming any less relevant. Looking at current platform as a service offerings Ted’s view of,

The more interesting question for developers has to do with infrastructure software. In my mind LAMP is really a proxy for “infrastructure software” If you’ve been paying any attention at all to the development of web application software, you know that there is a lot happening with various kinds of infrastructure software.

is understandable. Almost all the current PaaS vendors have developed mechanisms to harvest commons based peer production. Ultimately all of this ends up in some server of a vendor locked away in a data center somewhere. Most of the vendors use open source software heavily for their PaaS offerings and some have open sourced bits and pieces of their platform. While I’m certainly not the overzealous freedom fighter I was, this awfully sounds like writing open source applications for a proprietary platform. Not that it’s necessarily a bad thing. Unlike developing software on a proprietary operating system, developing on a proprietary platform as a service offering is limited in various aspects which are unique to its usecase.

So, IMHO, a more interesting problem to tackle in an environment like this is open source platform as a service. You still have a hosted service where people can just develop applications and forget about underlying technical details of the platform, where your data is residing and so on. At the same time this entire platform is open source! Sounds like a pipe dream but it’s a reality. I hope this will set a trend that other vendors follow, eventually.

The open source platform as a service is Stratos. The hosted platform reside in cloud.wso2.com where anyone can register for free (during the alpha and beta stages) and get an entire middleware platform at your fingertips with a few clicks. Another bold move is that the code base of the downloadable version and the hosted version are exactly the same! So, the platform itself and hosted applications behave in a predictable manner where ever they’re deployed. Also, it should be mentioned here that most of the services provided by Stratos started their life as standalone programs (like Tomcat). This also, provide invaluable repository of information if anyone wants to study how their should architect their applications to make them cloud native. Source code for the entire platform available here.