Hi Peter

See comments in the end
On 10/01/13 17:12, Peter Schyma wrote:
Hi,

I am trying to realize the following scenario:
1. Have one bundle (WC) initialize a web context (/app) via Pax
WebContainer and bind CXFNonSpringServlet to it (/app/services).
2. Allow other bundles (A, B, ...) to add endpoints and resources to
this web context. CXF endpoints should not be added to /cxf and
/app/services should not include ones from /cxf.

All configuration should be achievable from blueprint.

The last restriction of the second point is causing problems.

I have managed to register the CXFNonSpringServlet in WC. In order to
meet the restrictions figured out that I must provide a new
DestinationRegistry to the servlet. I'm doing this via the bus by adding
a custom feature to it:

<cxf:bus id="hicBus" bus="hicBus" name="hicBus">
<cxf:features>
<cxf:logging />
<ref component-id="hicRegistryFeature" />
</cxf:features>
</cxf:bus>

<!-- Bind a new CXFServlet to created bus -->
<bean id="hicCXFServlet"
class="org.apache.cxf.transport.servlet.CXFNonSpringServlet">
<property name="bus" ref="hicBus" />
</bean>

The feature uses a trivial implementation:
@Override
public void initialize(Bus bus) {
DestinationRegistry reg = new DestinationRegistryImpl();
new HTTPTransportFactory(bus, reg);
}

In bundles which contribute to that context I am looking up the CXF bus
and use it in the jaxrs server configuration:

<!-- Get the bus for this context -->
<reference id="bus" interface="org.apache.cxf.Bus"
availability="mandatory" filter="cxf.bus.id=hicBus" />

<bean id="service" class="..." />

<jaxrs:server bus="bus" id="server" address="/a">
<jaxrs:serviceBeans>
<ref component-id="service" />
</jaxrs:serviceBeans>
</jaxrs:server>

When I start my bundles everything works as expected. The servlet at
/cxf is not showing any endpoint registrations. The services at /app/a
and /app/b are accessible.

But when I stop one of the bundles, its registered endpoints do not get
removed from the registry (it's still showing up at /app/services) and
every query to any endpoint at /apps/* leads to an internal server error:

org.osgi.service.blueprint.container.ServiceUnavailableException: The
Blueprint container is being or has been destroyed:
(&(cxf.bus.id=hicBus)(objectClass=org.apache.cxf.Bus))
at
org.apache.aries.blueprint.container.ReferenceRecipe.getService(ReferenceRecipe.java:234)

at
org.apache.aries.blueprint.container.ReferenceRecipe.access$000(ReferenceRecipe.java:54)

at
org.apache.aries.blueprint.container.ReferenceRecipe$ServiceDispatcher.call(ReferenceRecipe.java:292)

at Proxy81a82933_4a7a_4e12_b808_3a682f503a24.getExtension(Unknown Source)
at
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:99)

at
org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:238)

at
org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:218)

at
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:198)

at
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:137)

at
org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:158)

at
org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:243)

at
org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:168)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:693)
at
org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:219)

at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:652)
at
org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:447)
at
org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:70)

at
org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)

at
org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:559)
at
org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:227)

at
org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1038)

at
org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:117)

at
org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:374)
at
org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:189)

at
org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:972)

at
org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)

at
org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:74)

at
org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)

at org.eclipse.jetty.server.Server.handle(Server.java:363)
at
org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:483)

at
org.eclipse.jetty.server.BlockingHttpConnection.handleRequest(BlockingHttpConnection.java:53)

at
org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:920)

at
org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:982)

at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:635)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
at
org.eclipse.jetty.server.BlockingHttpConnection.handle(BlockingHttpConnection.java:72)

at
org.eclipse.jetty.server.bio.SocketConnector$ConnectorEndPoint.run(SocketConnector.java:264)

at
org.eclipse.jetty.server.ssl.SslSocketConnector$SslConnectorEndPoint.run(SslSocketConnector.java:670)

at
org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)

at
org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)

at java.lang.Thread.run(Thread.java:722)


Am I missing something in my configuration? Or is there any simpler way
to achieve my goals?

I'm not sure what the cause of the above exception is, but would like to suggest you considering an alternative, how about introducing a master JAX-RS services listening at "/app" and then have this master resource service dynamically managing JAX-RS subresources covering "/app/service1", "/app/service2", etc:

@Path("/")
public class AppResource {
Map<String, AppSubResource> subresources;

@Path("/")
public AppSubResource(@Context UriInfo ui) {
// find the value of last path segment, ex, "/app/service1" -> "service1", etc

String lastPathSeg = getLastSegment(ui);
AppSubResource sub =  subresources.get(lastPathSeg);

if (sub == null) {
    throw new WAE(404);
} else {
    return sub;
}

}

}

Not sure if it will meet your requirements, typing it just in case :-)

Sergey


Any help is greatly appreciated.

Thanks
Peter


--
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com

Reply via email to