0

I am currently writing an Eclipse product including an embedded jetty. The embedded jetty is encapsulating a wink application. I am using wink 1.2.1 incubating in the eclipse product by wrapping the library as an Eclipse plugin and using the JAX RS 1.1.1 bundle from the orbit build number: R20151221205849.

Initially, i had the following exception when i run my Eclipse product:

java.lang.NullPointerException at org.apache.wink.common.internal.http.Accept.valueOf(Accept.java:139) at org.apache.wink.server.internal.contexts.HttpHeadersImpl.getAcceptHeader(HttpHeadersImpl.java:152) at org.apache.wink.server.internal.contexts.HttpHeadersImpl.getAcceptableMediaTypes(HttpHeadersImpl.java:106) at org.apache.wink.server.internal.registry.ResourceRegistry.filterByProduces(ResourceRegistry.java:558) at org.apache.wink.server.internal.registry.ResourceRegistry.filterDispatchMethods(ResourceRegistry.java:482) at org.apache.wink.server.internal.registry.ResourceRegistry.findSubResourceMethod(ResourceRegistry.java:391) at org.apache.wink.server.internal.handlers.FindResourceMethodHandler.handleSubResourceMethod(FindResourceMethodHandler.java:168) at org.apache.wink.server.internal.handlers.FindResourceMethodHandler.handleRequest(FindResourceMethodHandler.java:110) at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:26) at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:22) at org.apache.wink.server.handlers.AbstractHandlersChain.doChain(AbstractHandlersChain.java:63) at org.apache.wink.server.internal.handlers.FindRootResourceHandler.handleRequest(FindRootResourceHandler.java:95) at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:26) at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:22) at org.apache.wink.server.handlers.AbstractHandlersChain.doChain(AbstractHandlersChain.java:63) at org.apache.wink.server.internal.handlers.HeadMethodHandler.handleRequest(HeadMethodHandler.java:53) at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:26) at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:22) at org.apache.wink.server.handlers.AbstractHandlersChain.doChain(AbstractHandlersChain.java:63) at org.apache.wink.server.internal.handlers.OptionsMethodHandler.handleRequest(OptionsMethodHandler.java:46) at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:26) at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:22) at org.apache.wink.server.handlers.AbstractHandlersChain.doChain(AbstractHandlersChain.java:63) at org.apache.wink.server.internal.handlers.SearchResultHandler.handleRequest(SearchResultHandler.java:33) at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:26) at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:22) at org.apache.wink.server.handlers.AbstractHandlersChain.doChain(AbstractHandlersChain.java:63) at org.apache.wink.server.internal.log.ResourceInvocation.handleRequest(ResourceInvocation.java:92) at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:26) at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:22) at org.apache.wink.server.handlers.AbstractHandlersChain.doChain(AbstractHandlersChain.java:63) at org.apache.wink.server.internal.log.Requests.handleRequest(Requests.java:76) at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:26) at org.apache.wink.server.handlers.RequestHandlersChain.handle(RequestHandlersChain.java:22) at org.apache.wink.server.handlers.AbstractHandlersChain.doChain(AbstractHandlersChain.java:63) at org.apache.wink.server.handlers.AbstractHandlersChain.run(AbstractHandlersChain.java:48) at org.apache.wink.server.internal.RequestProcessor.handleRequestWithoutFaultBarrier(RequestProcessor.java:207) at org.apache.wink.server.internal.RequestProcessor.handleRequest(RequestProcessor.java:154) at org.apache.wink.server.internal.servlet.RestServlet.service(RestServlet.java:119) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135) at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116) at org.eclipse.jetty.server.Server.handle(Server.java:366) at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494) at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:971) at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1033) at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:640) at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:231) at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82) at org.eclipse.jetty.io.nio.SslConnection.handle(SslConnection.java:196) at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696) at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:53) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)

This answer: https://stackoverflow.com/a/20402681/5907194 suggests that the cause is a conflict of another jax rs implementation with wink.

Indeed, after investigating FactoryFinder.find(String factoryId, String fallbackClassName) in JAX RS it turns out that JAX RS falls back to the default jersey implementation because the class loader can not load the name of the JAX RS class implementation from the META-INF/services/javax.ws.rs.ext.runtimeDeletage file located in the wink common eclipse plugin i bundled.

I suspected that this is an issue with the osgi class loading as the class loader of the JAX RS plugin can not see resources in plugins that JAX RS does not depend on. Accordingly, i changed the Eclipse buddy policy (http://www.wickedshell.net/blog/2010/01/fragments-vs-buddy-classloading/) of the JAX RS plugin on my machine to "Eclipse-BuddyPolicy: registered" and registered the Wink common plugin with JAX RS using "Eclipse-RegisterBuddy: javax.Ws.rs Require-Bundle: javax.Ws.rs" .

The exception now is avoided and the product can be correctly run. Now my question is the following: does the JAX RS plugin on orbit need to be changed to work with other JAX RS implementation such as wink or there are other options that i'm missing ?

Please take in consideration the fact that i can not upgrade to JAX RS 2.0 nor use a different implementation of JAX RS as i am using OSLC4J which is dependant on wink.

Community
  • 1
  • 1
Omar Kacimi
  • 61
  • 1
  • 4

1 Answers1

0

The issue with Eclipse-BuddyPolicy is that it's specific to Equinox. Another challenge is Java's service finder. It does not work correctly by default in an OSGi environment. You could experiment with fragments contributing to the JAX-RS bundle. You might be more lucky with adding Apache SPI Fly to the stack. However, this requires additional headers to service providers as well as consumers. I've added Apache SPI Fly Bundles to EBR.

Based on your specific requirements/stack it sounds like you might have more luck with creating a JAX-RS bundle yourself. Have a look at EBR for creating custom bundles as you need them. The one in Eclipse Orbit was created specifically for the use case in Eclipse projects using it. It might not cover the specific needs of Wink and your product.

Gunnar
  • 2,264
  • 17
  • 31
  • thank you. I already have my own JAX-RS plugin. However, the code I'm working on is planned to be contributed to an Eclipse project. Hence, it might be a tricky situation to do that while relying on my own JAX-RS plugin as. Is there some way to find the eclipse projects that spawned the creation of the JAX-RS bundle in orbit? I would like to try and find out whether these projects were able to use a different implementation of JAX-RS other than the default Jersey. – Omar Kacimi Mar 15 '17 at 12:41
  • In this case you should contribute a recipe to Orbit with the proposed changes to the JAX-RS bundle. Orbit possibly also needs Apache SPI Fly to support the Java ServiceLoader approach. However, after review the error again, I do have doubts that it might solve your case. Apache Wink seems to include it's own version of the JAX-RS api. Is that the case? – Gunnar Mar 16 '17 at 13:29
  • Wink Common implements and depends on JAX-RS and but as far as i know doesn't include its own version of JAX-RS [link](https://mvnrepository.com/artifact/org.apache.wink/wink-common/1.2.1-incubating) . Proposing changes to the JAX-RS existing bundle as a recipe seems good. The only change i would propose is allowing other bundles to register as buddies with JAX-RS so that they can provide their own implementations of it as i have demonstrated in my example. Could you please point me to how to proceed for this ? shall i open a bug on Orbit or ? thanks again for the assist. – Omar Kacimi Mar 17 '17 at 13:42
  • The exceptions indicates that it found another in its classpath. That's why I'm double checking. Did you try creating some activation code that would initialize the RuntimeDelegate properly? Buddy classloading is really Equinox specific and should be avoided. The JAX-RS bundle is used in many situations and seems to work. So far, however, only Jersey seems to be used by all of them. That's why I suggested to wrap your own and ship this one with your plugin. You can create an all-in-one bundle that puts JAX-RS and Wink into the same bundle. OSGi does allow this and would not produce conflicts. – Gunnar Mar 25 '17 at 18:08