I'm developing a JAX-RS application with OSGI where resources are loaded dynamically. For this, I need to register the ServletContainer programmatically, then I can call the method ServletContainer.reload (ResourceConfig). I'm running on OSGI environment with support for servlet 3.x, using PAX-WEB 3.0.2 and Jersey 2.4. The problem is when I want to access a resource that implements Server Sent Event, Jersey raises an error that does not support asynchrony because it runs in a Servlet 2.x.
Here the exception:
2013-11-05 00:22:37,675 | WARN | qtp27902282-62 | ServletHandler | pse.jetty.servlet.ServletHandler 492 | 60 - org.eclipse.jetty.aggregate.jetty-all-server - 8.1.9.v20130131 |
javax.servlet.ServletException: java.lang.UnsupportedOperationException: Asynchronous processing not supported on Servlet 2.x container.
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:373)[224:org.glassfish.jersey.containers.jersey-container-servlet-core:2.3.1]
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)[224:org.glassfish.jersey.containers.jersey-container-servlet-core:2.3.1]
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)[224:org.glassfish.jersey.containers.jersey-container-servlet-core:2.3.1]
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)[224:org.glassfish.jersey.containers.jersey-container-servlet-core:2.3.1]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:669)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1448)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:185)[70:org.ops4j.pax.web.pax-web-runtime:3.0.2]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1419)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:455)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:69)[71:org.ops4j.pax.web.pax-web-jetty:3.0.2]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1075)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:210)[71:org.ops4j.pax.web.pax-web-jetty:3.0.2]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:384)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1009)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:77)[71:org.ops4j.pax.web.pax-web-jetty:3.0.2]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.server.Server.handle(Server.java:368)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:488)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:932)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:994)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:640)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:628)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)[60:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at java.lang.Thread.run(Thread.java:724)[:1.7.0_40]
Caused by: java.lang.UnsupportedOperationException: Asynchronous processing not supported on Servlet 2.x container.
at org.glassfish.jersey.servlet.WebComponent$1.suspend(WebComponent.java:120)[224:org.glassfish.jersey.containers.jersey-container-servlet-core:2.3.1]
at org.glassfish.jersey.servlet.internal.ResponseWriter.suspend(ResponseWriter.java:109)[224:org.glassfish.jersey.containers.jersey-container-servlet-core:2.3.1]
at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:621)[219:org.glassfish.jersey.core.jersey-server:2.3.1]
at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:357)[219:org.glassfish.jersey.core.jersey-server:2.3.1]
at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:347)[219:org.glassfish.jersey.core.jersey-server:2.3.1]
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:258)[219:org.glassfish.jersey.core.jersey-server:2.3.1]
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)[220:org.glassfish.jersey.core.jersey-common:2.3.1]
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)[220:org.glassfish.jersey.core.jersey-common:2.3.1]
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)[220:org.glassfish.jersey.core.jersey-common:2.3.1]
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)[220:org.glassfish.jersey.core.jersey-common:2.3.1]
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)[220:org.glassfish.jersey.core.jersey-common:2.3.1]
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:318)[220:org.glassfish.jersey.core.jersey-common:2.3.1]
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:235)[219:org.glassfish.jersey.core.jersey-server:2.3.1]
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:983)[219:org.glassfish.jersey.core.jersey-server:2.3.1]
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:359)[224:org.glassfish.jersey.containers.jersey-container-servlet-core:2.3.1]
I tried to register the ServletContainer in various ways, but none works and I think the problem is in the registration and settings Jersey, because I've recorded a Server Sent Event-based Asynchronous Servlet and all went perfect.
Code example:
ServletContainer container = new ServletContainer();
...
...
webContainerRef = bc.getServiceReference(WebContainer.class);
started = webContainerRef != null;
if (started) {
final WebContainer webContainer = (WebContainer) bc
.getService(webContainerRef);
if (webContainer != null) {
// create a default context to share between registrations
final HttpContext httpContext = webContainer
.createDefaultHttpContext();
// set a session timeout of 10 minutes
webContainer.setSessionTimeout(10, httpContext);
// register the hello world servlet for filtering with url
// pattern
final Dictionary<String, Object> initParamsServlet = new Hashtable<String, Object>();
initParamsServlet.put("javax.ws.rs.Application", "com.workingflows.osgi.jaxrs.samples.conf.MyJaxApp");
webContainer.registerServlet(
container, // registered
new String[]{"/rest/*"}, // url patterns
initParamsServlet, // init params
1,
true,
httpContext // http context
);
webContainer.registerServlet(
(HttpServlet) new SseServlet(), // registered
new String[]{"/servlet/sse"}, // url patterns
initParamsServlet, // init params
1,
true,
httpContext // http context
);
}
}
...
...
Here my code repository. See OsgiJersey project.
Do you have jersey-container-servlet module on your class-path (this is the module supposed to be used for Servlet 3.x support)?
The reason you're experiencing this issue is that Jersey couldn't find appropriate AsyncContextDelegateProvider (from jersey-container-servlet module) and it uses implementation from jersey-container-servlet-core module (Servlet 2.x support) which fails this way.
The error was that the jersey modules were initiated on the same level as the module of the application that registered the servletContainer.
[ 127] [ Resolved] [ 30] jersey-container-servlet-core (2.4.0)
[ 161] [ Active] [ 30] jersey-core-common (2.4.0)
[ 162] [ Active] [ 30] jersey-core-client (2.4.0)
[ 163] [ Active] [ 30] jersey-core-server (2.4.0)
[ 164] [ Active] [ 30] jersey-container-servlet (2.4.0)
[ 165] [ Active] [ 30] jersey-media-sse (2.4.0)
I start the stack of jersey in level 30, and the application at level 80 and everything works!!!! The important module is jersey-core-server, that adds support for servlet 3.x.
[ 168] [ Active] [ 80] OsgiJersey OSGi Bundle (1.0.0.SNAPSHOT)
See example in my repository
来源:https://stackoverflow.com/questions/19802671/register-servletcontainer-programmatically-in-osgi