[ 
https://issues.apache.org/jira/browse/FELIX-5310?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15505679#comment-15505679
 ] 

Carsten Ziegeler commented on FELIX-5310:
-----------------------------------------

It would be great if you could attach a test bundle/project or maybe even could 
provide a patch

> Felix HTTP Jetty WebSockets do not work out of the box
> ------------------------------------------------------
>
>                 Key: FELIX-5310
>                 URL: https://issues.apache.org/jira/browse/FELIX-5310
>             Project: Felix
>          Issue Type: Bug
>          Components: HTTP Service
>    Affects Versions: http.jetty-3.2.0
>            Reporter: Timothy Ward
>
> I have encountered two significant problems when trying to use the Jetty 
> WebSocketServlet with the Jetty based Felix HTTP service whiteboard. Both 
> problems occur in the init method of my servlet.
>  1. I have to set the TCCL for the Jetty Web Socket implementation to be able 
> to find its own internal implementation of Websockets (specifically 
> org.eclipse.jetty.websocket.server.WebSocketServerFactory). This is really 
> stupid, as the TCCL I have to use is the Felix HTTP Jetty bundle's class 
> loader!
> 2. The Jetty Web Socket implementation does one (and only one) check to check 
> that it's running on Jetty. It looks as though the only reason for this is to 
> get hold of an Executor which is available via a getter. This check involves 
> trying to establish the Jetty Context by casting the ServletContext to a 
> Jetty internal type. This does not work as the HTTP Whiteboard wrappers the 
> ServletContext. I can work around this by delaying initialisation to the 
> first request so that there is a context to get hold of, but this also sucks 
> :(
> In summary, my servlet has to look like this, most of which should not be 
> necessary!
> {code:java}
>     public class EchoServlet extends WebSocketServlet {
>     
>         private static final Logger LOGGER = 
> LoggerFactory.getLogger(EchoServlet.class);
>     
>         private final AtomicBoolean firstCall = new AtomicBoolean(true); 
>     
>         private final CountDownLatch initBarrier = new CountDownLatch(1); 
>     
>         @Override
>         public void init() throws ServletException {
>             LOGGER.info("The Echo servlet has been initialized, but we delay 
> initialization until the first request so that a Jetty Context is 
> available");   
>         }
>       
>         @Override
>         public void service(ServletRequest arg0, ServletResponse arg1) throws 
> ServletException, IOException {
>             if(firstCall.compareAndSet(true, false)) {
>                 try {
>                     delayedInit();
>                 } finally {
>                     initBarrier.countDown();
>                 }
>             } else {
>                 try {
>                     initBarrier.await();
>                 } catch (InterruptedException e) {
>                     throw new ServletException("Timed out waiting for 
> initialisation", e);
>                 }
>             }
>               
>             super.service(arg0, arg1);
>         }
>         private void delayedInit() throws ServletException {
>             // Overide the TCCL so that the internal factory can be found
>             // Jetty tries to use ServiceLoader, and their fallback is to
>             // use TCCL, it would be better if we could provide a loader...
>               
>             Thread currentThread = Thread.currentThread();
>             ClassLoader tccl = currentThread.getContextClassLoader();
>             
> currentThread.setContextClassLoader(WebSocketServlet.class.getClassLoader());
>             try {
>                 super.init();
>             } finally {
>                 currentThread.setContextClassLoader(tccl);
>             }
>         }
>         @Override
>         public void configure(WebSocketServletFactory wsf) {
>             wsf.setCreator((req,res) -> new WebSocketAdaptor() {
>                     public void onWebSocketText(String message) {
>                         getRemote().sendStringByFuture("Echo: " + message);
>                     }
>                 });
>         }
>     }
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to