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