Ben Ben - 1 year ago 106
Java Question

How to programmatically publish webservice to tomcat

I would like to publish a webservice programmatically to tomcat.

With e.g JAX-WS or Apache CXF

Similar to


//how to tell this tomcat?
Endpoint.publish("", serviceImpl);
//or better something like this:
Endpoint.publish("/SimpleService", serviceImpl);

Without need to use
(for each service)


Is there any known way to accomplish it (with JAX-WS or Apache CXF or ...)?

(I know there are similar questions already posted. But none of them really answers my question.)

Ben Ben
Answer Source

This is an anwer to my own question.
I managed to make this work [programmatically publish webservice to tomcat] with help of Apache CXF.

Here is a simplified working example:

I subclassed a CXFNonSpringServlet and registered it in web.xml:

 <display-name>CXF Servlet</display-name>


This is my subclassed CXFNonSpringServlet:

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashSet;
import java.util.Set;
import javax.jws.WebMethod;
import javax.servlet.ServletConfig;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.frontend.ServerFactoryBean;
import org.apache.cxf.service.factory.ReflectionServiceFactoryBean;
import org.apache.cxf.transport.servlet.CXFNonSpringServlet;

public class MyCXFServlet extends CXFNonSpringServlet
    protected void loadBus(ServletConfig sc) 

    private void publishServices()
        Set<Class> serviceInterfaces = new HashSet<>();

        for (Class aSVCInterface : serviceInterfaces)
            final String serviceName = aSVCInterface.getSimpleName();

                ReflectionServiceFactoryBean reflectionFactory = new ReflectionServiceFactoryBean(){
                    protected boolean isValidMethod(Method method)
                        boolean ret = super.isValidMethod(method);
                        WebMethod wm = method.getAnnotation(WebMethod.class);
                        if (wm != null && wm.exclude())
                            ret = false;
                        return ret;

                    protected String getServiceName() //Override for custom service name
                        return serviceName;


                Object proxiedServiceObject = Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{aSVCInterface}, new de.test.MyWebServiceInvocationHandler(aSVCInterface));

                ServerFactoryBean factory = new ServerFactoryBean(reflectionFactory);
                factory.setAddress("/" + serviceName);
                Server svr = factory.create();    
                svr.getEndpoint().getInInterceptors().add(new de.test.MyServiceInterceptor());
            catch (Exception exception)

The above Servlet will publish 2 simple interfaces as SOAP-WebService.
The implementation is dynamically (Proxies)

This is my MyServiceInterceptor:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.service.Service;
import org.apache.cxf.service.invoker.BeanInvoker;
import org.apache.cxf.service.invoker.Invoker;

public class MyServiceInterceptor extends AbstractSoapInterceptor
    public MyServiceInterceptor() 

    public void handleMessage(SoapMessage p_message) throws Fault 
        final Exchange exchange = p_message.getExchange();
        final Endpoint endpoint = exchange.get(Endpoint.class);
        final Service service = endpoint.getService();
        final Invoker invoker = service.getInvoker();

        if (invoker instanceof BeanInvoker)
            BeanInvoker bi = (BeanInvoker)invoker;
            Object serviceObj = bi.getServiceObject(null);
            if (Proxy.isProxyClass(serviceObj.getClass()))
                InvocationHandler ih = Proxy.getInvocationHandler(serviceObj);
                if (ih instanceof MyWebServiceInvocationHandler)
                    MyWebServiceInvocationHandler h = (MyWebServiceInvocationHandler)ih;

The MyServiceInterceptor-Class is mainly used to inject the current SOAPMessage to MyWebServiceInvocationHandler.

My MyWebServiceInvocationHandler (I think, no code needed here) is responsible to invoke the real Service-Method. It just implements InvocationHandler and has a field for the Soap-Message (see MyServiceInterceptor). This is needed to get SOAPMessage-Details (like Header).

Hope this helps.