Igal, Thanks for that information, that makes things much clearer!
I think you've hit on a reasonable, if clunky, solution given that the jsr-356 interface does not seem to explicitly pass the ServletContext anywhere. Joakim, this is more your area of expertise - got any other suggestion on how to solve the problem of using websocket as a service for many different ServletContexts? good luck, Jan On 14 July 2017 at 19:54, Igal @ Lucee.org <[email protected]> wrote: > Jan, > > Thank you for replying. Here is the scenario: > > We have a FOSS project named Lucee, which is a Servlet based on JSP, which > allows for rapid development of web applications because it's much simpler > to use and easier to learn than JSP/JSF, for example. The project is used > by many developers and organizations all over the world. > > Lucee allows for extensions (or plugins), which are loaded via OSGi, so > that they can be loaded/unloaded/updated on demand without restarting the > Servlet container, as well as use different versions of the same 3rd party > libraries side by side. > > I wrote an open source extension for Lucee which provides WebSocket > support: https://github.com/isapir/lucee-websocket -- The extension has > the following requirements: > > 1) Be packaged as an OSGi bundle so that it can be installed as a > Lucee extension. > > 2) Be JSR-356 compliant because Lucee could run on any Servlet > container, so I can not use Jetty- or Tomcat- specific APIs. > > 3) Allow for WebSocket configuration to be set at runtime, as we do > not know in advance what endpoint etc. the developer will want to use. > > 4) Be able to communicate with the Lucee servlet for Application and > Session states. > In order to be able to retrieve the correct state from Lucee (requirement > 4) my code needs to know the root directory of the ServletContext, e.g. > servletContext.getRealPath("/"), at the Handshake phase. This is > required so that multiple contexts can maintain their separate states > without "mixing" up state between the contexts, so that if there are two > contexts, ServletContext1 and ServletContext2, a user that connects to > ServletContext2 he will get the state from that context, and not the one > from ServletContext1. > > The only way that I found to retrieve the ServletContext through the > JSR-356 spec (requirement 2) is via the HttpSession in ServerEndpointConfig. > Configurator.modifyHandshake(), i.e. handshakeRequest.getHttpSession(). > getServletContext().getRealPath("/"). > > The problem is, that according to the JSR, the Session should not be > initialized in handshakeRequest.getHttpSession() if one does not exist, > so by default, handshakeRequest.getHttpSession() always returns null. > > The "recommended" way to initialize the Session is with a > ServletRequestListener, where a simple call to > httpServletRequest.getHttpSession() > does initialize the HttpSession object. I have provided a class to do that > -- https://github.com/isapir/lucee-websocket/blob/master/ > src/main/java/net/twentyonesolutions/servlet/listener/ > HttpSessionInitializer.java#L40 -- but because this is an OSGi bundle > (requirement 1), this jar is not on the classpath -- and can not be > specified as-is in the web descriptor. > > The solution that I came up with, is to add a tiny jar file to the > classpath with a Servlet Filter that initializes the HttpSession -- > https://github.com/isapir/servlet-filter-utils/blob/ > master/src/main/java/net/twentyonesolutions/servlet/filter/ > HttpSessionInitializerFilter.java#L70 -- Then the user adds the tiny jar > to the classpath, and configures the Filter to intercept WebSocket URIs. > > But there has to be a simpler method than that, no? Again, my ultimate > goal here is to get the ServletContext's root directory, so if there is > another way to do that then I would not need to jump through all those > hoops. If not, I am looking to register the ServletRequestListener so that > the user will not need to add another jar and/or modify web.xml. > > Thank you, > > > Igal Sapir > > Lucee Core Developer > Lucee.org <http://lucee.org/> > On 7/14/2017 12:23 AM, Jan Bartel wrote: > > Igal, > > Some more description of exactly what your setup is would be good: do you > have a bundle that is a traditional war? And the websocket code bundle is > external to the main webapp bundle? What bundle is the "servlet" in? What > does the websocket bundle do? Without knowing more it is difficult to give > a cogent answer. > > Assuming you have another bundle that contains a web.xml, you could either > put that listener definition in there (so long as you manually get the > manifest import statements correct on the web bundle to refer to your > websocket bundle); or you could define a context listener in there whose > job it is to register the request listener programmatically - that way > tools like bnd will generate correct manifest import statements for you. I > don't know if you want to be able to selectively enable this listener or > not, or based on what configuration .... > > If you provide more info, then maybe I can suggest something else. > > cheers > Jan > > > > On 13 July 2017 at 19:21, Igal @ Lucee.org <[email protected]> wrote: > >> Hello, >> >> I have a JSR-356 (WebSocket API) code that is packaged in an OSGi bundle. >> The servlet loads the code via Apache Felix if needed. >> >> I want to register a ServletRequestListener, which I would normally put >> in the web descriptor: >> >> <listener> >> <listener-class>path.to.my.RequestListener</listener-class> >> </listener> >> >> but since the bundle is not in the classpath that wouldn't work. >> >> How can I register the ServletRequestListener? I am thinking that maybe >> there would be a way with scanning for annotations but am not sure how to >> set that up. My other concern is that many users disable the scanning to >> improve startup time. >> >> The listener's job is to initialize HttpSession so that I can retrieve >> the ServletContext in the WebSocket handshake. If there's a way to achieve >> that without the listener then that will work for me even better. >> >> Any ideas? Thanks! >> >> p.s. This is a crosspost with https://stackoverflow.com/ques >> tions/45083982/register-servletrequestlistener-from-osgi-bundle >> >> Igal Sapir >> Lucee Core Developer >> Lucee.org <http://lucee.org/> >> >> _______________________________________________ >> jetty-users mailing list >> [email protected] >> To change your delivery options, retrieve your password, or unsubscribe >> from this list, visit >> https://dev.eclipse.org/mailman/listinfo/jetty-users >> > > > > -- > Jan Bartel <[email protected]> > www.webtide.com > *Expert assistance from the creators of Jetty and CometD* > > > > _______________________________________________ > jetty-users mailing [email protected] > To change your delivery options, retrieve your password, or unsubscribe from > this list, visithttps://dev.eclipse.org/mailman/listinfo/jetty-users > > > > _______________________________________________ > jetty-users mailing list > [email protected] > To change your delivery options, retrieve your password, or unsubscribe > from this list, visit > https://dev.eclipse.org/mailman/listinfo/jetty-users > -- Jan Bartel <[email protected]> www.webtide.com *Expert assistance from the creators of Jetty and CometD*
_______________________________________________ jetty-users mailing list [email protected] To change your delivery options, retrieve your password, or unsubscribe from this list, visit https://dev.eclipse.org/mailman/listinfo/jetty-users
