gorootde
gorootde

Reputation: 4073

Jetty: load a context from another jar

I've built an application that loads multiple plugins over SPI. Each plugin has to implement the FrameworkPlugin interface.

public interface FrameworkPlugin {
    ...
    ContextHandler getWebContent();
    String getPluginID();
    ...

}

An example implementation would be

...
ContextHandler getWebContent() {
   WebAppContext wac=new WebAppContext();
   wac.setBaseResource(new ResourceCollection(new String[] {"./src/main/webapp"}));
   return wac;
}
...

The Main-Project runs a single Jetty instance, which should be used by all plugins providing web-based services. A plugin has to be able to configure it's individual environment within its own context, except the base URL, which is managed by the main project.

...
for (FrameworkPlugin p : PLUGINS) {
    ContextHandler h= p.getWebContent();
    h.setContextPath("/plugin/"+p.getPluginID().toString());
    collection.addHandler(h);
}
jettyInstance.setHandler(collection);
...

So in theory, plugins should be accessible under /plugin/<id>. Unfortunately Jetty throws an IllegalArgumentException, because plugins set ./src/main/webapp as resource base, which does not exist in the main project.

So how to supply a context handler via the plugin interface?

Deploying WARs is not an option, as the loading mechanism can't be changed. Everything has to be done by using the plugin interface.

Upvotes: 0

Views: 66

Answers (1)

Joakim Erdfelt
Joakim Erdfelt

Reputation: 49515

If this isn't going to be a WAR based project, then skip the use of WebAppContext entirely, and just use the Handler system in Jetty itself.

The WebAppContext is a specialized Handler meant to be used with a full blown and complete Web Application that follows the servlet spec. It mandates behavior that is mandated by the servlet spec, from the mundane (how url mapping order behaves), past the black art (per element descriptor order lookup and override), to the complex (webapp classloader isolation).

The Handler system in Jetty can be 1..n Handlers, in a Tree (via HandlerCollections), sometimes with Context, mutable Handler collections, and all exists at the same classloader as the server (if you want it to). Feel free to url map with regex, or your own implementation of level 3 URI templates. Completely up to you what you want to do with it. You have many pre-built Handlers and base Handler to build up from.

You'll still have access to the standard HttpServletRequest and HttpServletResponse, along with the async processing and I/O that those provide. But you'll also have access to the raw internal Request object which offers even more features over the HttpServletRequest.

Incidentally, many servlet based applications support plugins now. Most accomplish this using Controller Servlets, or Filters, or manipulation of the ServletContext's registrations.

Upvotes: 1

Related Questions