title: Atmosphere+Jersey error with Tomcat 8 and non-Atmosphere client
body: <p>I run a chat server that uses Atmosphere as the framework for websocket support. Atmosphere uses Jersey because I use the atmosphere-jersey maven dependency. </p>
  
  <p>The chat server runs on Tomcat 7 and we are upgrading to Tomcat 8.</p>
  
  <p>One of our clients uses Tyrus as their Java websocket API.</p>
  
  <p>When our chat server is deployed on Tomcat 7 (with Java 6,7, or 8), there are no issues.</p>
  
  <p>With our chat server on Tomcat 8 (Java 8), our testing client that uses Atmosphere works fine but the client that uses Tyrus does not. The error that we see is:</p>
  
  <pre><code>2017-01-17 02:36:51,114 ERROR () [http-nio-8443-exec-11] ReflectorServletProcessor (?) - onRequest()
  java.lang.IllegalArgumentException: Schema specific part is opaque
          at com.sun.jersey.api.uri.UriBuilderImpl.checkSsp(UriBuilderImpl.java:529)
          at com.sun.jersey.api.uri.UriBuilderImpl.replacePath(UriBuilderImpl.java:256)
          at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:703)
          at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
          at org.atmosphere.util.AtmosphereFilterChain.doFilter(AtmosphereFilterChain.java:135)
          at org.atmosphere.util.AtmosphereFilterChain.invokeFilterChain(AtmosphereFilterChain.java:96)
          at org.atmosphere.handler.ReflectorServletProcessor$FilterChainServletWrapper.service(ReflectorServletProcessor.java:317)
          at org.atmosphere.handler.ReflectorServletProcessor.onRequest(ReflectorServletProcessor.java:160)
          at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:199)
          at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:107)
          at org.atmosphere.container.Servlet30CometSupport.service(Servlet30CometSupport.java:66)
          at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:2078)
          at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:571)
          at org.atmosphere.websocket.DefaultWebSocketProcessor$3.run(DefaultWebSocketProcessor.java:333)
          at org.atmosphere.util.VoidExecutorService.execute(VoidExecutorService.java:101)
          at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:328)
          at org.atmosphere.websocket.DefaultWebSocketProcessor.invokeWebSocketProtocol(DefaultWebSocketProcessor.java:525)
          at org.atmosphere.websocket.DefaultWebSocketProcessor.invokeWebSocketProtocol(DefaultWebSocketProcessor.java:428)
          at org.atmosphere.container.JSR356Endpoint$1.onMessage(JSR356Endpoint.java:213)
          at org.atmosphere.container.JSR356Endpoint$1.onMessage(JSR356Endpoint.java:210)
          at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:393)
          at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:494)
          at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:289)
          at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:130)
          at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:60)
          at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:183)
          at org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:198)
          at org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:96)
          at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:669)
          at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
          at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
          at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
          at java.lang.Thread.run(Thread.java:745)
  </code></pre>
  
  <p>This occurs because with Tomcat 7, the request URL from the websocket request is seen as similar to "http:// localhost:8080/chat/" (The request is made to ws://localhost:8080/chat/ but it's changed to http:// somewhere). But with Tomcat 8, the request URL from the websocket request is similar to "/chat/" and the schema is not there and Jersey throws an error.</p>
  
  <p>To combat this, Atmosphere looks for the header "origin" which has the schema when an Atmosphere client makes a request. But when a Tyrus client makes a request, that "origin" header does not include the http schema resulting in the error shown above.</p>
  
  <p>I am wondering if anyone has any ideas for a simple solution to this or have come across a similar issue. I've done a lot of searching for a simple solution but have not found one yet. Without one, we are looking at having to stop using Atmosphere and use something else which is a lot of code refactoring.</p>
  
  <p>These are some links to ticket/bugs around this issue that would seem to have addressed this yet I have the correct versions and still have issues.</p>
  
  <p><a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=56573" rel="nofollow noreferrer">https://bz.apache.org/bugzilla/show_bug.cgi?id=56573</a>
  <a href="https://github.com/Atmosphere/atmosphere/issues/1839" rel="nofollow noreferrer">https://github.com/Atmosphere/atmosphere/issues/1839</a></p>
  
  <p>Atmosphere version: 2.4.8</p>
  
  <p>Jersey version (via atmosphere): 1.19</p>
  
  <p>Tyrus version: 1.13</p>