If using the ${jetty.base}
and ${jetty.home}
recommended installation process for Standalone Jetty, you should go to your ${jetty.base}
instance directory and enable the websocket
module.
$ cd /path/to/mybase
$ java -jar /opt/jetty/jetty-home-9.4.14.v20181114/start.jar --add-to-start=websocket
$ grep "websocket" start.ini
--module=websocket
Now you have websocket enabled for that ${jetty.base}
instance.
If you want Jetty to discover your Server WebSocket endpoints via bytecode scanning your deployed webapps for annotations, then you'll also want the annotations
module.
$ cd /path/to/mybase
$ java -jar /opt/jetty/jetty-home-9.4.14.v20181114/start.jar --add-to-start=annotations
$ grep "annotations" start.ini
--module=annotations
Once that's complete, you can do one (or more) of the following to have the websocket server endpoints deployed with your webapp.
Why does this work in standalone Jetty? What is standalone Jetty doing to make this possible?
The following happens:
- The
websocket
module adds the lib/websocket/*.jar
to the server classpath
- The
websocket
module depends on both client
and annotations
modules
- The
client
module adds lib/jetty-client-<jetty.version>.jar
to the server classpath
- The
annotations
module adds lib/jetty-annotations-<jetty.version>.jar
and lib/annotations/*.jar
to the server classpath
- The
annotations
module depends on the plus
module
- The
annotations
module selects etc/jetty-annotations.xml
for execution on startup
- The
annotations
module adds JPMS modules by name org.objectweb.asm
- The
plus
module adds lib/jetty-plus-<jetty.version>.jar
to the server classpath
- The
plus
module selects etc/jetty-plus.xml
for execution on startup
- The
plus
module depends on the server
, security
, jndi
, webapp
, and transactions
modules
(I'll skip the rest of the modules that are selected this way)
In short, with just adding websocket
module you gain the following server classpath entries
lib/websocket/*.jar
lib/jetty-client-<jetty.version>.jar
lib/jetty-annotations-<jetty.version>.jar
lib/annotations/*.jar
lib/jetty-plus-<jetty.version>.jar
And the following XML files
lib/jetty-annotations.xml
lib/jetty-plus.xml
Both of these XML files simply modify the default Configuration
list on the server side, making the Configuration
behavior they introduce available to all deployed WebApps.
You can alternatively set the Configuration
on the WebAppContext
(before it's started) for webapp specific behaviors.
Example:
WebAppContext context = new WebAppContext();
context.setContextPath("/");
context.setBaseResource(Resource.newResource(rootResourceUrl));
context.setConfigurations(new Configuration[] {
new AnnotationConfiguration(),
new WebXmlConfiguration(),
new WebInfConfiguration(),
new PlusConfiguration(),
new MetaInfConfiguration(),
new FragmentConfiguration(),
new EnvConfiguration()});
handlerList.addHandler(context);
Note: for javax.websocket
you must use a WebAppContext
, as the behaviors defined for its initialization require a full Web App to function.
While you can use a ServletContextHandler
with javax.websocket
endpoints, this style is 100% manually defined, intialized, and declared, with no automatic bytecode / annotation scanning features that JSR-356 relies on.
You can see all of this from the command line too.
Show the active ${jetty.base}
configuration, what the XML property values are, what the server classpath is, and what XML is going to be executed (and in what order!!)
$ cd /path/to/mybase
$ java -jar /opt/jetty/jetty-home-9.4.14.v20181114/start.jar --list-config
Show the list of modules and how they relate (along with which ones are selected in your ${jetty.base}
configuration)
$ cd /path/to/mybase
$ java -jar /opt/jetty/jetty-home-9.4.14.v20181114/start.jar --list-modules