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

Reply via email to