The product I am developing is going to come out in early access package pretty soon. My QA and Support team are still not quite get it why the web services in our product needs additional steps to add some descriptor files when it going to be deployed on Sun Java System Web Server. I also found this confusion quite commonplace among beginners who start learning JAX-WS. I would like to explain it here so the next time somebody asks me again then I can just direct him to this post.

Java EE deployment model
The final package of JAX-WS web services is an ordinary war file just like any other Servlet/JSP web application’s war file. If you look at the basic JAX-WS tutorial you will notice that the implementation can be as minimal as a simple Java class with a couple of web service annotations.

@WebService()
public class NewsService {
    public String[] getAlert(){
        //implementation
    }
}

You can just pack this class to a war file without the need of any descriptor file even web.xml and then deploy it to Java EE application server to get a nice and simple web services.

You are able to do this kind of deployment because your application server has implemented all the necessary specifications for developing/deploying web services on Java EE platform. The main specification defining potable programming model for Java EE platform is JSR-109 (Implementing Enterprise Web Services). If you search internet and mailing list, you may found many developers call web services with this kind of deployment model as “JSR-109 web services”. Actually, JSR-109 always works together with other specification like JSR-224 (JAX-WS) and JSR-181 (web services annotation) so I will choose to call this deployment model “Java EE deployment model”.

If you choose to make your web services compliant with JSR-109 specification then your war file can be deployed on any Java EE application servers that support the specification. I have developed my unit testing on Glassfish and give the same package to QA team to run system test on WebSphere.

Now, let’s look at it in the real action.
Here we are creating a web services stating from creating a web application project. To demonstrate JSR109 web services, I will choose target server to be Glassfish which is a full Java EE application server.

ChoosingContainer

Once you have created a web service (using web services wizard or manually create java class with web services annotation), you will see that there is nothing in your web.xnl that related to web services information. You can ignore the sun-web.xml, this file is specific to Glassfish and it is not descriptor in our main topic. You may want to delete all descriptor in WEB-INF and deploy your web application to see that your web services application is still able to work properly.

JSR109_IDE

Here is the default web.xml file content.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

Now you may want to look at the final war file that you can distribute to your client.
You will see that there is no web services library packed in your war file at all. Since this is JSR109 web services so it expect Java EE server to provide all necessary libraries.

D:\Program\netbeans-projects\JSR109\dist>jar -tf JSR109.war
META-INF/
META-INF/MANIFEST.MF
WEB-INF/
WEB-INF/classes/
WEB-INF/classes/ws/
WEB-INF/classes/ws/news/
WEB-INF/classes/ws/news/NewsService.class
index.jsp

Servlet Based deployment model
If you want to deploy the NewsService example above on non full Java EE server (Sun Java System Web Server, Tomcat) then you may have some concerns to think about.

The most important concern is that this kind of deployment is not portable. From the eyes of the non Java EE container, your web services war file is no different from the normal Servlt/JSP web application’s war file. If you want to do web services then you have to choose an implementation of JAX-WS and pack all the necessary libraries into your war. Now you will get a web application that happens to have some libraries that know how to do web services.

Another thing is that your web services implementation classes are not going to be automatically discovered by your container. You will have to edit some file descriptors to tell your JAX-WS implementation library to know how you want your web services to be deployed. These descriptors are specific to the library you are using. The web services in my product need sun-jaxws.xml file when it is going to be deployed on SJSWS because we are using SUN JAX-WS reference implementation for this kind of deployment.

In NetBeans, if you choose target server to be Apache Tomcat then you will get the war file structure as shown below.

ServletBased_IDE

You will see that sun-jaxws.xml file will be added to your WEB-INF directory once you create a web services. Both sun-jaxws.xml and web.xml will contain descriptive information about your web services.

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">
    <listener>
        <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>NewsService</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>NewsService</servlet-name>
        <url-pattern>/NewsService</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

sun-jaxws.xml

<endpoints version="2.0" xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime">
  <endpoint implementation="ws.news.NewsService" name="NewsService" url-pattern="/NewsService"/>
</endpoints>

And here is the layout of the final package.
D:\Program\netbeans-projects\ServletBasedWS\dist>jar -tf ServletBasedWS.war
META-INF/
META-INF/MANIFEST.MF
WEB-INF/
WEB-INF/classes/
WEB-INF/classes/ws/
WEB-INF/classes/ws/news/
WEB-INF/lib/
META-INF/context.xml
WEB-INF/classes/ws/news/NewsService.class
WEB-INF/lib/activation.jar
WEB-INF/lib/webservices-api.jar
WEB-INF/lib/webservices-extra-api.jar
WEB-INF/lib/webservices-extra.jar
WEB-INF/lib/webservices-rt.jar
WEB-INF/lib/webservices-tools.jar
WEB-INF/sun-jaxws.xml
WEB-INF/web.xml
index.jsp

You will see that jar files of METRO (JAX-WS RI ) have been packed along with our final war file.