1
votes

I am developing some web services that must be implemented using JAXWS, and that must run on WebLogic 10.3, WebSphere 7 and Tomcat 5.5. Furthermore, installation of the services must be completely self-contained to avoid conflicts with any other applications in the container. WebLogic and WebSphere are solved, but tomcat gives me trouble.

Enabling tomcat for jaxws by using JAXWS-RI is functional, but installation of additional jars (jaxws.jar, jaxb.jar) in tomcat or jre is to be avoided.

Shipping my application with axis2 embedded inside the war is better, but the services get funny URIs. Take for example this service:

PortType generated with wsimport:

@WebService(name = "AuthenticationServicePortType", targetNamespace = "http://impl.auth.webservice.my.company")
@XmlSeeAlso({
    company.my.exposed.xsd.ObjectFactory.class,
    company.my.webservice.auth.impl.ObjectFactory.class
})
public interface AuthenticationServicePortType {

Implementation:

@WebService(
  portName = "AuthenticationServicePort", serviceName = "AuthenticationService",
  targetNamespace = "http://impl.auth.webservice.my.company", wsdlLocation = "WEB-INF/wsdl/AuthenticationService.wsdl",
  endpointInterface = "company.my.webservice.auth.impl.AuthenticationServicePortType"
)
public class AuthenticationServiceImpl implements AuthenticationServicePortType {

In WebSphere, WebLogic and tomcat+JAXWS-RI this service becomes available at the uri

http://localhost/MyProduct/services/AuthenticationService

However, with axis2 embedded inside the war, the service becomes available at the uri

http://localhost/MyProduct/services/AuthenticationService.AuthenticationServicePort

Because this is an upgrade of an existing service with a wide installed base, this change is not acceptable.

Configuring the service via services.xml has been removed from axis2's jaxws support, so that is dead end.

Using Apache CXF instead of Axis2 is not a good solution because it could create a support nightmare.

The tomcat version of web.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 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 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <description>My web service</description>
    <display-name>MyProduct</display-name>
    <servlet>
        <description>JAX-WS endpoint for MyProduct</description>
        <display-name>MyProduct</display-name>
        <servlet-name>MyProduct</servlet-name>
        <servlet-class>org.apache.axis2.transport.http.AxisServlet</servlet-class>
    </servlet>

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

I also modified axis2.xml to make it look for annotated classes among regular classes:

<deployer extension=".class" directory="classes" class="org.apache.axis2.jaxws.framework.JAXWSDeployer"/>

Two kinds of solutions would help:

  • A way of embedding JAXWS-RI inside the war, so nothing has to be installed in tomcat
  • A way to get Axis2 to deploy the services at regular URI's (same as other containers)
1
Out of curiosity, how would using CXF instead of Axis2 create a support nightmare?Daniel Kulp
Using CXF could (not "would") create a support nightmare. It is a risk, not a certainty.kresho

1 Answers

0
votes

I did not find a real solution to this problem, but I found a workaround.

I used url rewriting (http://www.tuckey.org/urlrewrite/) to add the extra part in the URL.

filter in web.xml:

<filter>
    <filter-name>UrlRewriteFilter</filter-name>
    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
    <init-param>
        <param-name>logLevel</param-name>
        <param-value>INFO</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/services/*</url-pattern>
</filter-mapping>

urlrewrite.xml:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN"
        "http://tuckey.org/res/dtds/urlrewrite3.2.dtd">
<urlrewrite>
    <rule>
        <note>
            Add .SomeServicePort to all urls
        </note>
        <from>/services/(.*)</from>
        <to>/services/$1.$1Port</to>
    </rule>
</urlrewrite>

Not beautyful but good enough.