2

I try to get http session in Endpoint. I followed this recomendations https://stackoverflow.com/a/17994303 . Thats why I did:

public class MyConfigurator extends ServerEndpointConfig.Configurator
{
    @Override
    public void modifyHandshake(ServerEndpointConfig config, 
                                HandshakeRequest request, 
                                HandshakeResponse response)
    {
        HttpSession httpSession = (HttpSession)request.getHttpSession();
        config.getUserProperties().put(HttpSession.class.getName(),httpSession);
    }
}

and

@ServerEndpoint(value = "/foo", configurator = MyConfigurator.class)
public class MyEndpoint {

    private Session wsSession;

    private HttpSession httpSession;


    @OnOpen
    public void open(final Session session,EndpointConfig config) {
        this.wsSession=session;
        this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
    }
}

And this is what I get

java.lang.RuntimeException: Cannot load platform configurator
    at javax.websocket.server.ServerEndpointConfig$Configurator.fetchContainerDefaultConfigurator(ServerEndpointConfig.java:123)
    at javax.websocket.server.ServerEndpointConfig$Configurator.getContainerDefaultConfigurator(ServerEndpointConfig.java:128)
    at javax.websocket.server.ServerEndpointConfig$Configurator.checkOrigin(ServerEndpointConfig.java:192)
    at org.eclipse.jetty.websocket.jsr356.server.JsrCreator.createWebSocket(JsrCreator.java:88)
    at org.eclipse.jetty.websocket.server.WebSocketServerFactory.acceptWebSocket(WebSocketServerFactory.java:187)
    at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:207)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1676)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581)
    at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:70)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)
    at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:276)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:80)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
    at org.eclipse.jetty.server.Server.handle(Server.java:524)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
    at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
    at java.lang.Thread.run(Thread.java:745)

I use osgi, jetty 9.3.11 and pax-web 6.0.0.

Community
  • 1
  • 1
Pavel_K
  • 10,748
  • 13
  • 73
  • 186
  • Looks like a `ServiceLoader` issue in your OSGi environment. The `javax.websocket.server.ServerEndpointConfig` uses a ServiceLoader to load the default Configurator (from Jetty) – Joakim Erdfelt Sep 28 '16 at 23:20

5 Answers5

4

The problem is that the javax.websocket-api jar is not set up for using the ServiceLoader mechanism in osgi so it can find custom Configurator instances.

In order for that to work in osgi, the manifest in the javax.websocket-api jar would need to have these lines:

Require-Capability: osgi.serviceloader;filter:="(osgi.serviceloader=javax.websocket.server.ServerEndpointConfig.Configurator)";resolution:=optional;cardin
 ality:=multiple,osgi.extender;filter:="(osgi.extender=osgi.serviceloa
 der.processor)"

So as it does NOT have those lines, you are going to need to add another bundle with a manifest with those lines in it and that declares itself as a fragment for the javax.websocket-api bundle.

If you're using maven, the lines you'd need in a pom are something like:

      <plugin>
        <groupId>org.apache.felix</groupId>
        <artifactId>maven-bundle-plugin</artifactId>
        <configuration>
            <instructions>
              <Bundle-SymbolicName>${bundle-symbolic-name};singleton:=true</Bundle-SymbolicName>
              <Bundle-Name>OSGi Websocket API Fragment</Bundle-Name>
              <Fragment-Host>javax.websocket-api</Fragment-Host>
            <Require-Capability>osgi.serviceloader; filter:="(osgi.serviceloader=)javax.websocket.server.ServerEndpointConfig.Configurator";resolution:=optional;cardinality:=multiple, osgi.extender; filter:="(osgi.extender=osgi.serviceloader.processor)"</Require-Capability>
            </instructions>
        </configuration>
      </plugin>
Jan
  • 1,287
  • 7
  • 7
  • Thank you for your answer and time. It didn't help. I tried to add those lines to manifest of javax.websocket-api. Besides I tried to make separate bundle as you said. It didn't help. I have a feeling that aries.spifly doesn't work for me. Maybe I need to do something more besides adding three bundles `asm-all-5.0.4.jar, org.apache.aries.util-1.1.1.jar, org.apache.aries.spifly.dynamic.bundle-1.0.1.jar`. – Pavel_K Sep 30 '16 at 04:50
  • Your answer is almost right. The mistake is that Configurator is nested class, so the instead of the last `.` must be `$`. So I just added `Require-Capability: osgi.extender;filter:="(osgi.extender=osgi.servicelo ader.processor)",osgi.serviceloader;filter:="(osgi.serviceloader=javax. websocket.server.ServerEndpointConfig$Configurator)";resolution:=option al;cardinality:=multiple` to manifest of javax.websocket-api.jar – Pavel_K Sep 30 '16 at 06:41
  • Could you please post info on what file goes where into the WAR file, for those of us that doesn't give a crap about OSGi, and are just unlucky to be tasked to deploy a war file into Karaf? – Martin Vysny Oct 09 '18 at 02:16
1

You can install the mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.javax-websocket-api/1.1_1 bundle which is a repackage of the original javax.websocket-api but with proper OSGi descriptors. More on this here: http://mavi.logdown.com/posts/7813065-deploying-vaadin-app-on-karaf

Martin Vysny
  • 3,088
  • 28
  • 39
0

This is what worked for creating my fragment fix:

        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Bundle-SymbolicName>${project.groupId}.${project.artifactId};singleton:=true</Bundle-SymbolicName>
                    <Bundle-Name>Websocket API OSGi Fix</Bundle-Name>
                    <Fragment-Host>javax.websocket-api</Fragment-Host>
                    <Require-Capability>
                        osgi.serviceloader;osgi.serviceloader="javax.websocket.server.ServerEndpointConfig$Configurator"
                    </Require-Capability>
                </instructions>
            </configuration>
        </plugin>
rob64zz
  • 3
  • 2
0

This is not an answer, but we thought it might help other users who run into the same issue that we did: we had the same exact problem as described by the OP but the "accepted answer" did not fix it. That is, we added precisely the described entry to the Manifest in the specified jar, and we continued to get the same exception (identical to the one listed by the OP).

We managed to solve the issue as follows. In our Dropwizard initialize() method, we had code like:

@Override
public void initialize(Bootstrap<AppConfig> bootstrap) {
   ...
   bootstrap.addBundle(new WebsocketBundle(MyWebsocketHandler.class));
   ...
}

After tracing through the Dropwizard code, we discovered that the WebsocketBundle constructor we were invoking was assigning null to the default configurator, despite the fact that the @ServerEndpoint annotation on the MyWebsocketHandler class specified a Configurator class, as follows:

@ServerEndpoint(value="/myWebsocketPath",configurator=CustomEndpointConfigurator.class)

We changed the constructor call in initialize() to instead be

bootstrap.addBundle(new WebsocketBundle(new CustomEndpointConfigurator(), TeamWebsocketHandler.class));

and poof, the exception went away. (It DID result in a long succession of new "NoClassDefFound" exceptions, but those are easy to find. After installing the missing libraries containing all the missing classes, the application websockets began functioning as expected.)

It is entirely possible that we have completely misinterpreted something about how Dropwizard works (or is supposed to work); those of us on this project are all serious novices when it comes to this area, and we would welcome any explanation of why what we did was "wrong" or "doesn't make sense". But we thought it might help others to discover something that worked for us when the "accepted answer" didn't.

0

In my case I was obfuscating javax.websocket with proguard. The following fixed the problem for me:

-keep class javax.websocket.** { *; }
Displee
  • 670
  • 8
  • 20