Jan,

Thank you for the sanity check! I kept (in a way still keep) thinking that I missed something simple. I guess it's possible that the "Expert Group" missed it though, and not me.

I hope that Joakim would have a better solution. I must say here though, that much of my JSR-356 knowledge comes from Joakim's old posts in mailing list archives and on StackOverflow, so thank you, Joakim, for that!

Best,

Igal Sapir
Lucee Core Developer
Lucee.org <http://lucee.org/>

On 7/18/2017 2:05 AM, Jan Bartel wrote:
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] <mailto:[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
    <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
    
<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
    
<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]
    <mailto:[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
        <http://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/questions/45083982/register-servletrequestlistener-from-osgi-bundle
        
<https://stackoverflow.com/questions/45083982/register-servletrequestlistener-from-osgi-bundle>

        Igal Sapir
        Lucee Core Developer
        Lucee.org <http://lucee.org/>


        _______________________________________________
        jetty-users mailing list
        [email protected] <mailto:[email protected]>
        To change your delivery options, retrieve your password, or
        unsubscribe from this list, visit
        https://dev.eclipse.org/mailman/listinfo/jetty-users
        <https://dev.eclipse.org/mailman/listinfo/jetty-users>




-- Jan Bartel <[email protected] <mailto:[email protected]>>
    www.webtide.com <http://www.webtide.com>
    /Expert assistance from the creators of Jetty and CometD/



    _______________________________________________
    jetty-users mailing list
    [email protected] <mailto:[email protected]>
    To change your delivery options, retrieve your password, or unsubscribe 
from this list, visit
    https://dev.eclipse.org/mailman/listinfo/jetty-users
    <https://dev.eclipse.org/mailman/listinfo/jetty-users>


    _______________________________________________
    jetty-users mailing list
    [email protected] <mailto:[email protected]>
    To change your delivery options, retrieve your password, or
    unsubscribe from this list, visit
    https://dev.eclipse.org/mailman/listinfo/jetty-users
    <https://dev.eclipse.org/mailman/listinfo/jetty-users>




--
Jan Bartel <[email protected] <mailto:[email protected]>>
www.webtide.com <http://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

_______________________________________________
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