Howdy,

I'm extending this class: org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet extends CXFNonSpringServlet.

I would like to be able to do a similar thing to what was done by JB with CXFNonSpringServlet but rather by extending CXFNonSpringJaxrsServlet.

Currently, as shown here [1], there is not a constructor for CXFNonSpringJaxrsServlet that allows the DestinationRegistry and Bus parameters to be passed into the CXFNonSpringJaxrsServlet. The current constructors are:

CXFNonSpringJaxrsServlet()

CXFNonSpringJaxrsServlet(Application app)

CXFNonSpringJaxrsServlet(Object singletonService)

CXFNonSpringJaxrsServlet(Set<Object> applicationSingletons)

What I would like to see would be the following:

CXFNonSpringJaxrsServlet(Application app, DestinationRegistry destinationRegistry, Bus bus)  where the implementation looked like:

    public CXFNonSpringJaxrsServlet(Application app, DestinationRegistry 
destinationRegistry, Bus bus) {
        super(destinationRegistry, false);
        this.application = app;
        this.setBus(bus);
    }

so that I can do with CXFNonSpringJaxrsServlet what JB does with the CXFNonSpringServlet superclass.   Or if this is more easily done with fixes to the superclass...then I could use that as well I expect.

To get such support into future release...would it be best to open a pull request?   Or is asking here better??

Thanksinadvance,

Scott

[1] https://github.com/apache/cxf/blob/master/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/servlet/CXFNonSpringJaxrsServlet.java#L95


On 10/15/2019 8:04 AM, Jean-Baptiste Onofré wrote:
Hi,

Thanks Dan, he found a way to fix the issue.

The servlet constructor has been changed to:

     public MyServlet(MyRestApi restApi, DestinationRegistry
destinationRegistry, Bus bus) {
         super(destinationRegistry, false);
         this.restApi = restApi;
         this.setBus(bus);
     }

and the bean registering the servlet has been changed to:

         MyRestApi restApi = new MyRestApi();

         Map<Class<?>, Object> extensions = new HashMap<>();
         DestinationRegistry destinationRegistry = new
DestinationRegistryImpl();
         HTTPTransportFactory httpTransportFactory = new
HTTPTransportFactory(destinationRegistry);
         extensions.put(HTTPTransportFactory.class, httpTransportFactory);
         extensions.put(DestinationRegistry.class, destinationRegistry);
         Bus bus = new ExtensionManagerBus(extensions, null,
getClass().getClassLoader());
         org.apache.cxf.transport.DestinationFactoryManager
destinationFactoryManager =
bus.getExtension(org.apache.cxf.transport.DestinationFactoryManager.class);
         for (String url : HTTPTransportFactory.DEFAULT_NAMESPACES) {
             destinationFactoryManager.registerDestinationFactory(url,
httpTransportFactory);
         }

         MyServlet restServlet = new MyServlet(restApi,
destinationRegistry, bus);


Thanks to that, I'm able to register several servlets each "isolated"
with JAXRS Server.

I think there are couple of bugs in CXF here. For instance, the
setExtension(null, HTTPTransportFactory.class) to remove the default one
should work, but the default is still in there.
I will propose a PR to improve this.

Regards
JB

On 15/10/2019 07:44, Jean-Baptiste Onofré wrote:
Hi,

I have extended CXFNonSpringServlet two times:

public class MyServlet1 extends CXFNonSpringServlet {

   @Override
   public void init(ServletConfig config) throws ServletException {
     super.init(config);
     JAXRSServerFactoryBean bean = new JAXRSServerFactoryBean();
     bean.setAddress("/");
     bean.setBus(getBus());
     bean.setProvider(new JacksonJsonProvider());
     bean.setServiceBean(new MyApi());
     bean.create();
   }

}

same with MyServlet2.

MyServlet1 has /myservlet1 as alias, MyServlet2 has /myservlet2.
Note that I would like to use "/" for JAXRS server address as it's based
directly on the servlet alias (context).

When I start the first servlet (let say MyServlet1), it's OK. However
when I start the second one (let say MyServlet2, but the same happens if
I start MyServlet2 first and MyServlet1), it fails with:

Caused by: org.apache.cxf.service.factory.ServiceConstructionException:
There is an endpoint already running on /.
         at
org.apache.cxf.jaxrs.JAXRSBindingFactory.addListener(JAXRSBindingFactory.java:86)
~[?:?]
         at org.apache.cxf.endpoint.ServerImpl.start(ServerImpl.java:128)
~[?:?]
         at
org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:209)
~[?:?]

So, even if I use two different servlets, it seems CXF has a shared
resource somewhere.

Obviously if I have different address for JAXRS server it works, but
it's not that I want as I'm using two different servlets.

I tried:
- to create a bus dedicated in each servlet
- to create a destination registry in each servlet
but it doesn't help.

So, basically, my question is: is there a way to have completely
isolated CXFNonSpringServlet ?

I gonna dig into CXF code today but if you already have some ideas, it
would be great.

Thanks !
Regards
JB

Reply via email to