Now I get it. That explains why the open(true) helped. I think though this should be fixed in felix. A HttpService provider should not require the clients to know a proprietary interface.

I think the real problem might be in org.apache.felix.http.base.internal.service.HttpServiceFactory.HttpServiceFactory .
There the HttpService is registered using:
final String[] ifaces = new String[] { HttpService.class.getName(), ExtHttpService.class.getName() }; this.httpServiceReg = bundleContext.registerService(ifaces, this, this.httpServiceProps); I would not have thought it is a problem if one of the interfaces is not known by a client but maybe it is. So I think it might help to do two separate calls to registerService with only one of the interfaces.
Can you try this?

Christian


On 14.07.2015 11:21, Thomas Konstantinides wrote:
Hi Christian,

as I see the problem is not the default org.osgi.service.http.HttpService 
Interface itself but org.apache.felix.http.api.ExtHttpService which is 
introduced by Felix and which inherits from HttpService. So in the end when 
context.getServiceReferences() is called from the ServiceTracker to search 
already registered HttpService implementors it finds the registered instance of 
org.apache.felix.http.base.internal.service.HttpServiceImpl. This instance 
however implements two interfaces: HttpService and ExtHttpService. This fact 
makes ServiceRegistrationImpl.isAssignableTo() return false since the Interface 
org.apache.felix.http.api.ExtHttpService is not visible for the CXF HTTP bundle.

Another workaround which makes CXF work in the given scenario is doing the 
following change:
- Add org.apache.felix.http.api to the imported Packages of the 
cxf-rt-transports-http bundle

This makes the registered Felix HttpServiceImpl visible to CXF HTTP Transport 
ServiceTracker and thus the connection between OSGi and the CXF Servlet can be 
established. The workaround is based on creating a wiring between the CXF HTTP 
Transport bundle and the Felix HTTP API.

Maybe this fix - although implementation specific - is the more future proof 
alternative, since I think ExtHttpService will disappear over time when in OSGi 
R6 the default OSGi HttpService gets more powerful.

Thomas

-----Ursprüngliche Nachricht-----
Von: Christian Schneider [mailto:[email protected]] Im Auftrag von 
Christian Schneider
Gesendet: Dienstag, 14. Juli 2015 07:59
An: [email protected]
Betreff: Re: CXF HTTP Transport in OSGi: ServiceTracker does not find 
HttpService

Can you check if there are different sources for the org.osgi.service.http 
package?
Whenever you need open(true) the reason is that the client imports a different 
package than the service.
So your goal should be to remove one of that sources so both use the same 
package.

Honestly I wonder why it works with true as you should not be able to call the 
service if it is not compatible.

Christian


Am 13.07.2015 um 21:31 schrieb Thomas Konstantinides:
Hi Christian,

thanks for your fast reply. The example on the Felix webpage is a bit
outdated and the http bridge (version 2.3.2) in its manifest has now

Import-Package: javax.servlet;version="[3.0,4)",javax.servlet.descriptor
   ;version="[3.0,4)",javax.servlet.http;version="[3.0,4)"

So what we have in our framework.properties is

org.osgi.framework.system.packages.extra = \
javax.servlet;javax.servlet.http;javax.servlet.descriptor;version=3.0

In general the http bridge works fine and for example the Felix webconsole is 
showing up without any problems. In the webconsole I can see again that the 
HttpService is available and that the CXF HTTP Transport (as well as all other 
bundles) is started. If a put a breakpoint into the 
HTTPTransportActivator.start() method and start a remote debugging session I'm 
getting to the breakpoint and all the code within the activator runs. The only 
issue is that the CXF ServiceTracker, which is started there, does not see the 
HttpService. And the only way I could make it see the HttpService is using the 
.open(true) version.

The fix with .open(true), which makes the CXF Servlet work, does seem a bit 
dirty to me, too. However at the moment I see no other way to get this setup 
working. So if you have any further ideas it would be great. Maybe someone has 
a similar setup working?

Thomas

-----Ursprüngliche Nachricht-----
Von: Christian Schneider [mailto:[email protected]] Im Auftrag
von Christian Schneider
Gesendet: Montag, 13. Juli 2015 18:05
An: [email protected]
Betreff: Re: CXF HTTP Transport in OSGi: ServiceTracker does not find
HttpService

Hi Thomas,

I think this fix is not correct. If the http service can only be found with 
.open(true) it means that the package the service implements and the package 
cxf imports are different.

I assume you simply forgot one step of the bridge installation guide:
http://felix.apache.org/documentation/subprojects/apache-felix-http-se
rvice.html#using-the-servlet-bridge

be sure to add |javax.servlet;javax.servlet.http;version=2.6| to OSGi
system packages (|org.osgi.framework.system.packages|);

Christian

On 13.07.2015 17:07, Thomas Konstantinides wrote:
Hi everyone,

I am having some problems with CXF HTTP Transport in an OSGi environment using 
Apache Felix as OSGi Framwork.

I'm using the Felix Http Bridge to start Felix within a .war web application 
which runs in Tomcat. The problem is, that the ServiceTracker which is set up 
in org.apache.cxf.transport.http.osgi.HTTPTransportActivator does not find the 
HttpService which is provided by the bundle org.apache.felix.http.bridge.

I tried a small change in the CXF code, changing line 64 in
HTTPTransportActivator to

httpServiceTracker.open(true);

With this change the HttpService is recognized by the ServiceTracker and the 
CXF Servlet is setup correctly.

I did a bit more debugging to get to the root cause of this behavior
and found, that the problem is caused when the method

ServiceRegistrationImpl.isAssignableTo()

is called in the process of opening the ServiceTracker and getting the list of already available 
services for the interface HttpService (ServiceTracker. getInitialReferences() -> 
context.getServiceReferences). The Implementation of Felix' HttpService 
(org.apache.felix.http.base.internal.service.HttpServiceImpl) implements not only HttpService but also 
ExtHttpService. And when asking ServiceRegistrationImpl.isAssignableTo() with the parameters 
requester: "org.apache.cxf.cxf-rt-transports-http [27]" and className: 
"org.apache.felix.http.api.ExtHttpService" it returns false.

Now a simple fix is given by what I already wrote above: Changing
httpServiceTracker.open() to httpServiceTracker.open(true); in
HTTPTransportActivator

So I'd like to ask two questions:
1. Does anyone have a better solution on how to get this scenario working?
2. If not: Could this fix be inserted into the CXF code to enable us (and 
others which might have similar problems) to use the offical .jar and not a 
self-built one?

Thanks for your comments,
Thomas

--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com



--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com

Reply via email to