0

I'm banging my head against the wall on this. I wrote a tiny embedded jetty server (jetty 9.4.18, jersey 1.19.4) and I cannot for the life of me get it to respect the context path and my REST services deployed.

I tried setContextPath, but that never worked on ServletContextHandler, so I went with WebAppContext.

This is about as simple as I can get it:

Server jettyServer = new Server(9999);

// set up the web app
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/app/");
webapp.setResourceBase("web");

jettyServer.setHandler(webapp);

// add REST service
ServletHolder jerseyServlet = webapp.addServlet(ServletContainer.class, "/service/*");
final ResourceConfig resourceConfig = new ResourceConfig(RestService.class);
resourceConfig.register(MultiPartFeature.class);
jerseyServlet.setInitParameter("jersey.config.server.provider.packages", "org.futureboy.app.server.rest");

try {
    jettyServer.start();
    jettyServer.join();
} catch (Exception e) {
    e.printStackTrace();
    //jettyServer.stop();
    jettyServer.destroy();
}

The static HTML files are served up in the web directory, and this works fine if I keep this line as follows:

ServletHolder jerseyServlet = webapp.addServlet(ServletContainer.class, "/service/*");

However this means the REST service (which operates under /app/service) does not work. If I swap this line out:

ServletHolder jerseyServlet = webapp.addServlet(ServletContainer.class, "/*");

Then the REST service works fine, but now the static HTML content does NOT work fine. So I either get a working static HTML service on /app/ or a working REST service underneath /app/service, but I can't have both. What am I doing wrong? The RestService.java file starts like:

@Path("/service")
public class RestService {

Any help would be appreciated, for I feel I am stuck on the one-yard line here.

user3837868
  • 957
  • 1
  • 11
  • 20
futureboy
  • 83
  • 10

1 Answers1

2

Why do you want Jersey to serve static content?

That's not the role of a JAX-B server.

What do do ...

  1. Switch from WebAppContext to ServletContextHandler (you don't need the overhead of WebAppContext or any of the bytecode scanning or annotation scanning deployment techniques that a full blown WebAppContext brings to the table.
  2. Prevent Jersey from serving static content.
  3. Setup a proper ResourceBase - use a fully qualified path or URI (no relative paths, no partial URIs)
  4. Add a DefaultServlet on the default url-pattern "/" named "default".

Which these changes Jetty will serve static content, from your Resource Base.

Some prior answers/examples of the Jetty side configuration and DefaultServlet usage:

And there's many many answers on how to configure Jersey to not serve static content.

One my favs is the solution provided at ...

Joakim Erdfelt
  • 41,193
  • 5
  • 78
  • 124
  • I basically want this little embedded server to host static html files, some images/javascript/etc, and then the bulk of the project are the REST endpoints. Ideally this would all exist within the same space, but now that you mention it, I suppose I could migrate the static content to Apache and then set up some reverse proxy for the REST. – futureboy May 31 '19 at 22:19
  • What you want to do in Jetty and Jersey is very doable, and quite common. Just need to configure it properly. – Joakim Erdfelt Jun 01 '19 at 17:38