JAX-WS Web service on Tomcat without sun-jaxws.xml
Solution 1
Sadly, the configuration must exist somewhere. That is mandatory, per the source. Believe it or not, the location of the sun-jaxws.xml file is hard-coded to /WEB-INF/sun-jaxws.xml (thanks, guys @ Metro).
Effectively, you need to take control of the following classes
What needs to happen:
-
WSServletContextListener
will obviously not be extended. This listener performs most of the initializations per the sun-jaxws.xml and jaxws-catalog file. Like I mentioned earlier, the location is hard coded. So your path of least resistance here is toimplement your own vanilla servlet listener (with
@WebListener
) and call anew WSServletContextListener()
. You'll then delegate your owncontextInitialized(ServletContext ctxt)
andcontextDestroyed()
methods to the ones in your instance ofWSServletContextListener
.Generate the file on instantiation of the listener, on the fly, using an
@XmlRootElement
class that'll represent the sun-jaxws file(I'll provide a sample of this in a short while, don't have the time right now :) ).
It's a lot of trouble for such a dispensable convenience, IMO, but it should work in theory. I'll write some samples and see how they play shortly.
Solution 2
To have JAX-WS support in Tomcat you must configure:
- WEB-INF/sun-jaxws.xml
- WSServletContextListener
- WSServlet
Unfortunately it is hard to omit the WEB-INF/sun-jaxws.xml file but there is easier way to omit web.xml configuration because of Servlet 3.0 API.
You can do something like this:
@WebServlet(name = "ServiceServlet" , urlPatterns = "/service", loadOnStartup = 1)
public class Servlet extends WSServlet {
}
and
@WebListener
public class Listener implements ServletContextAttributeListener, ServletContextListener {
private final WSServletContextListener listener;
public Listener() {
this.listener = new WSServletContextListener();
}
@Override
public void attributeAdded(ServletContextAttributeEvent event) {
listener.attributeAdded(event);
}
@Override
public void attributeRemoved(ServletContextAttributeEvent event) {
listener.attributeRemoved(event);
}
@Override
public void attributeReplaced(ServletContextAttributeEvent event) {
listener.attributeReplaced(event);
}
@Override
public void contextInitialized(ServletContextEvent sce) {
listener.contextInitialized(sce);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
listener.contextDestroyed(sce);
}
}
I have tested it on Tomcat-8.5.23 version and it works. But remember that you still must have WEB-INF/sun-jaxws.xml file.
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
version="2.0">
<endpoint name="SampleService"
implementation="com.ws.ServiceImpl"
url-pattern="/service" />
</endpoints>
Solution 3
I have publised web services successfully by this way. I have used apache cfx for publishing in servletContextListener.
@WebListener
public class WebServicePublisListener implements ServletContextListener {
/**
* Default constructor.
*/
public WebServicePublisListener() {
// TODO Auto-generated constructor stub
}
/**
* @see ServletContextListener#contextInitialized(ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent sce) {
JaxWsServerFactoryBean srvFactory = new JaxWsServerFactoryBean();
srvFactory.setServiceClass(RandService.class);
srvFactory.setAddress("/RandService");
srvFactory.setServiceBean(new RandServiceImplement());
srvFactory.create();
}
Solution 4
You have to publish the web service. You can implement a ServletContextListener and publish the endpoint:
@javax.servlet.annotation.WebListener
public class AppServletContextListener implements javax.servlet.ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
Endpoint.publish("{protocol}://{host}:{port}/{context}/{wsName}", new MyHelloWorldWSImpl());
}
public void contextDestroyed(ServletContextEvent sce) {
....
}
}
sun-jaxws.xml is not mandatory by specs...If you note, for example, glassfish (metro) makes it optional. Also, if you expose a EJB 3.1 as webservice (with jaxws) you can see no sun-jaxws.xml file in the generated build.
Related videos on Youtube
Miljen Mikic
Math & problem solving lover. Software development engineer with considerable experience in Linux and database worlds. Holding MSc in Computer Science and PhD in Mathematics. Some answers that I learnt a lot from: BalusC's Using java.net.URLConnection to fire and handle HTTP requests templatetypedef's What is pseudopolynomial time? How does it differ from polynomial time? Mystical's Why is processing a sorted array faster than an unsorted array? Some answers that I am proud of: How to calculate smallest multiple formed only of the digit 1? How to calculate smallest number with certain number of divisors? Java EE Containers vs Web Containers
Updated on September 28, 2022Comments
-
Miljen Mikic over 1 year
I am trying to minimize required configuration while deploying JAX-WS-based Web service on Tomcat. With the introduction of Servlet 3.0 (supported by Tomcat 7+),
web.xml
can be thrown out, but there is stillsun-jaxws.xml
. This blog post is interesting:Of course, with the use of jax-ws annotations, even configuration sun-jaxws.xml can be made optional making it completely descriptor free, but that requires specifying a default url-pattern like in JSR-109 or custom pattern like in Jersey REST services, in the JAX-WS specification.
Is it possible to avoid
sun-jaxws.xml
on Tomcat, and how? -
Miljen Mikic almost 11 yearsThanks for the answer. However, I don't want to use Endpoint.publish(..) infrastructure because it represents a lightweight HTTP server - if I wanted that, I wouldn't have used Tomcat. Next, Tomcat is a servlet container; in other words you cannot deploy EJBs on Tomcat. I'm aware that works like a charm in Glassfish, but that's because Glassfish is JSR-109-compliant.
-
Michael Henrique almost 11 yearsTomcat does not supports EJB by default. You should consider using, for instance, TomEE. I mentioned EJB just to act as a example to demonstrate no needs of sun-jaxws.xml (It's not mandatory).
-
Miljen Mikic almost 11 yearsPersonally, I would always prefer full application server (such as Glassfish) over servlet container (such as Tomcat). But, our clients use Tomcat and I am curious if it's possible to simplify a configuration needed for the deployment of Web services on Tomcat. Therefore, my question is specifically about Tomcat, not TomEE or Glassfish.
-
Miljen Mikic almost 11 years+1, didn't know that the location of
sun-jaxws.xml
is hard-coded :) What about default url-pattern that should makesun-jaxws.xml
optional (see the blog I have cited in my question), do you know anything about it? -
kolossus almost 11 years@MiljenMikic reading that post carefully, it all seems like a lot of wishful thinking and not much of a reference: The link in his blog post is dead. I still managed to track down the sources he was referring to here and the readme.txt still indicates a sun-jaxws.xml is necessary
-
Miljen Mikic almost 9 yearsThanks for the answer. I should have tagged my question with "JAX-WS RI" or "Metro" tags, since
sun-jaxws.xml
is related to these implementations. Apache CXF is different implementation of JAX-WS, so it does not have nothing withsun-jaxws.xml
. -
Miljen Mikic over 6 yearsI am aware that we can omit
web.xml
file, that is already mentioned in the text of the question. The question is about omittingsun-jaxws.xml
file. -
Adrian Malik over 6 yearsAhh okay but I added the solution for other people that might not know how to omit web.xml file for this problem. For example I had that problem several weeks ago.
-
user1887464 over 2 yearsis there any way we can specify port in this xml configuration ?