You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Justin Li <ju...@hotmail.com> on 2020/08/18 03:48:28 UTC

Is there a way to make OSGI HttpService reference ready before calling bundleContext.registerService()?

See the pseudo code as below. During OSGI bundle activation we want to register the org.apache.cxf.transport.servlet.CXFServlet servlet with the whiteboard pattern, get the cxf bus returned from the servlet and set it as the default bus of BusFactory, and after that publish the endpoints by calling javax.xml.ws.Endpoint.publish(). By doing this we can receive SOAP calls from HP devices and also send SOAP calls to HP devices.

In our old product we registered the CXFServlet servlet by calling httpService.registerServlet(…), the cxf bus retrieved from the CXFServlet was not null (which was actually an org.apache.cxf.bus.spring.SpringBus object), and the communication with HP device was always fine. Due to the OSGI version upgrading for our product we change to use the whiteboard pattern to do the registration and we notice the returned cxf bus from the CXFServlet is null after calling bundleContext.registerService(…) , and also, the published endpoints are not there for listening.  We are trying to find a solution. The experimentations showed the way to make it work is to get the org.osgi.service.http.HttpService reference ready first, and then call bundleContext.registerService(…) to register the CXFServlet. With this way the returned cxf bus is not null anymore and the communication between the web server and HP device is fine.

As per tests and experimentations, the OSGI HttpService instance seems to be lazy started. In order to get the org.osgi.service.http.HttpService reference ready (which is actually an  org.apache.felix.http.base.internal.service.PerBundleHttpServiceImpl object), there has to be a web request sent to the web server. For example, in the code make a web request to the web server itself. But, this does not seem to be elegant . ) Is there any other way to make the OSGI HttpService reference ready before calling bundleContext.registerService()?

... ...
import javax.servlet.Servlet;
import javax.xml.ws.Endpoint;
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.transport.http.osgi.HTTPTransportActivator;
import org.apache.cxf.transport.servlet.CXFServlet;
... ...

@Component(service = { HPOmniWebServicePublishComponent.class })
public class HPOmniWebServicePublishComponent implements IWebComponent {
    ... ...
    private HTTPTransportActivator httpTransportActivator = new HTTPTransportActivator();
    ... ...

    @Activate
    public void activate(ComponentContext ctx)
    {
         try {
            // Set value for keystore and keystore password
                ... ...
            System.setProperty("javax.net.ssl.keyStore", keyStoreLocation);
            System.setProperty("javax.net.ssl.keyStorePassword", password);
            ... ...
            httpTransportActivator.start(ctx.getBundleContext());
        } catch (NoClassDefFoundError | Exception exception) {
            // Log error for starting HTTPTransportActivator
        }
        … …
        ClassLoader currentcl = Thread.currentThread().getContextClassLoader();
        try {
            // set classloader to CXF bundle class loader to avoid OSGi classloader problems
            ClassLoader bundlecl = BusFactory.class.getClassLoader();
            Thread.currentThread().setContextClassLoader(bundlecl);
            ... ...
            System.setProperty("javax.xml.ws.spi.Provider", "org.apache.cxf.jaxws.spi.ProviderImpl");
            … …
            org.apache.cxf.transport.servlet.CXFServlet servlet = new org.apache.cxf.transport.servlet.CXFServlet();
            BundleContext bundleContext = ctx.getBundleContext();
            params.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, ApplicationFactory.SERVICE_BASE_PATH);
            params.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(osgi.http.whiteboard.context.name=org.osgi.service.http)");
           cxfServletRegistration = bundleContext.registerService(Servlet.class, servlet, params); // Register the org.apache.cxf.transport.servlet.CXFServlet servlet

            org.apache.cxf.Bus bus = servlet.getBus(); // The returned org.apache.cxf.Bus bus is always null if we didn’t get OSGI HttpService reference ready before calling bundleContext.registerService(Servlet.class, servlet, params);
            BusFactory.setDefaultBus(bus); //org.apache.cxf.BusFactory

            // Publishe endpoints for specified implementors
           Endpoint.publish("/HPOmniWebAuthenticationAgentService", jaxwsAuthenticationAgent);
           ... ...


Thanks.
Justin Li