Hi folks,
Since PFD was posted, we already have a few things to sort out. You will
remember that according to the JCP process, we are allowed to revise the
specification where it is '"underdefined, incomplete, or ambiguous" as
we (implementors of the spec) complete our implementations, we (Oracle)
finish up the TCK.
So here goes A, B and C, biggest first:
A) Implementation Issue with ServerContainerProvider
Both Mark and we in our RI work found that the
ServerContainerProvider.getServerContainer() provider is problematic to
implement. You'll remember that we need this bootstrap to be able to
programmatically deploy endpoints during app initialization: in
particular from a ServerContextListener. Without getting into the weeds,
the fundamental problem is without further information its tricky to get
the right instance of the ServerContainer corresponding to the current
application the ServerContainerProvider.getServerContainer() call is
being made from. It can be done, but only by underhand methods such as
thread local and/or looking at the classloader. We both agree that if we
had the instance of the ServletContext corresponding to the current
application, it would be easy, and also portable across web containers.
Certainly in Tyrus, we are associating the instance of the
ServerContainer corresponding to the application being deployed with the
instance of the ServletContext corresponding to the application being
deployed in a module level ServletContainerInitializer.
So the upshot is that to get the right instance of the ServerContainer,
you need the right instance of the ServletContext, so the API has to be
fixed.
Fortunately, this instance of the ServletContext is readily available in
any ServletContexListener the developer may need to make the bootstrap
call from. There are various options for reworking the API,
ServerContainerProvider.getServerContainer(String contextRoot)
ServerContainerProvider.getServerContainer(ServletContext servletContext)
or ServerContainer.setContext(Object context)
though after some thought, I think the simplest approach is to remove
the ServerContainerProvider class altogether and require that, for
websocket implementations in the web container, the ServletContext
instance have a named attribute that is the websocket ServerContainer.
Its one less API class, in exchange for a named attribute.
So in a ServletContextListener, instead of doing:-
import javax.websocket.server.ServerContainerProvider;
...
ServerContainer sc =
ServerContainerProvider.getServerContainer(myServletContext);
sc.deploy(endpoints);
we would simply have
ServerContainer sc = (ServerContainer)
myServletContext.getAttribute(ServerContainer.SERVLETCONTEXT_NAME);
sc.deploy(endpoints);
B) Precedence of URI-Template matching
We have not clarified some of the edge cases, for example:-
endpoint X mapped to /a/b/
endpoint Y mapped to /a/{foo}
does an incoming URI /a/b match X (exact match wins over URI-template
match), or Y (URI-template match wins over exact match) ?
I'm proposing the 'most exact match wins' rule: i.e. the implementation
picks the match where the segments match most exactly, reading from left
to right.
So for example:-
endpoint M mapped to /a/{foo}
endpoint N mapped to /{bar}
anything beginning /a matches M
everything else matches N.
and
endpoint P mapped to /a/{foo}
endpoint Q mapped to /{bar}/b/c
/a/b/c matches P, not Q.
Are there any objections to this clarification ?
This does seem to be the scheme employed by other URI-template matching
algorithms, but I can't find a good reference. Can anyone point me to a
good standard definition of this kind of policy, or an alternative if
you think it should work another way ?
C) Some javadoc glitches that I will fix, see
http://java.net/jira/browse/WEBSOCKET_SPEC-169
http://java.net/jira/browse/WEBSOCKET_SPEC-168
http://java.net/jira/browse/WEBSOCKET_SPEC-171
Let me know if you have further comments.
Thanks,
- Danny
--
<http://www.oracle.com> *Danny Coward *
Java EE
Oracle Corporation