Java – How to set up static resources and custom services with embedded Jetty

embedded-jettyjavajetty

I'm trying to set up a simple webservice for my application by embedding Jetty. I'd like to have two different web services available, a simple HTTP server that just serves up static content (which will eventually be a GWT app) and a custom servlet which can spit out JSON status messages for the application.

My distribution folder structure looks something like this:

+ dist/
  - MyApp.jar
  + lib/
  + html/
    - index.html

And here's what I have so far for configuring the embedded server. I correctly get my test output from my custom servlet when visiting http://localhost/data/, but I can't seem to get the DefaultServlet to find my index.html file.

public Webserver(int port) {
    server = new Server(port);

    ServletContextHandler context = new ServletContextHandler();
    context.setResourceBase("./html/");
    server.setHandler(context);


    JsonDataApiServlet dataServlet = new JsonDataApiServlet();
    DefaultServlet staticServlet = new DefaultServlet();

    context.addServlet(new ServletHolder(dataServlet), "/data/*");
    context.addServlet(new ServletHolder(staticServlet), "/*");
}

It seems like this would be a common task for people embedding Jetty in things.. am I even on the right track?

Edit

Turns out this problem was due to a misunderstanding of the way relative paths are calculated inside Jetty. I was running this from one folder above the dist folder, using java -jar dist\MyApp.jar, and Jetty was looking for dist\..\html rather than the correct dist\html. Running the jar from inside the dist folder fixes the issue. I'll answer with how I made it work without having to run from inside the dist directory.

Best Answer

As the edit says, this was just an issue with the directory I was running the jar from. Here is the method I used to find the html folder from wherever the Jar was run from:

First, I added the html folder to the Jar's Manifest Class-Path. The following code gives the html folder for wherever the Jar is loaded from:

ClassLoader loader = this.getClass().getClassLoader();
File indexLoc = new File(loader.getResource("index.html").getFile());
String htmlLoc = indexLoc.getParentFile().getAbsolutePath();

This uses the Classloader to find the index file in the classpath, then finds the absolute directory to pass to Jetty:

server = new Server(port);

ServletContextHandler context = new ServletContextHandler();
context.setResourceBase(htmlLoc);
context.setWelcomeFiles(new String[] { "index.html" });
server.setHandler(context);


JsonDataApiServlet dataServlet = new JsonDataApiServlet();
DefaultServlet staticServlet = new DefaultServlet();

context.addServlet(new ServletHolder(dataServlet), "/data/*");
context.addServlet(new ServletHolder(staticServlet), "/*");
Related Topic