0
votes

I have a sample Maven project in Eclipse (Mars) with embedded jetty v9. I have defined a resource handler for static html / javascript files and a servlet handler for REST APIs. I create a single fat jar (shade package) and it does all I want when I run the jar from project homedir. It serves the rest API and web pages. From any other directory, it only serves up REST API. For HTML pages jetty server gives a reason not found.

Handlers are armed this way:

    //REST handler context
    ServletContextHandler restHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
    restHandler.setContextPath("/");

    // Jersey REST handling servlet
    ServletHolder jerseyServlet = restHandler.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*");
    jerseyServlet.setInitOrder(0);

    // Tell Jersey which REST service class to load....
    jerseyServlet.setInitParameter("jersey.config.server.provider.classnames", RestHandler.class.getCanonicalName());

    // Handler that will handle the request for a given html page
    ResourceHandler resourceHandler = new ResourceHandler();

    // Configure page handler with login.html as the initial landing page
    resourceHandler.setDirectoriesListed(true);
    resourceHandler.setWelcomeFiles(new String[]{ "pages/login.html" });
    resourceHandler.setResourceBase("src/main/webapp/");

    //Add all handlers to the server
    Server jettyServer = new Server(8080);
    //ConstraintSecurityHandler authenticationHandler = authenticationService(jettyServer);
    //authenticationHandler.setHandler( resourceHandler );

    HandlerCollection handlerList = new HandlerCollection();
    handlerList.setHandlers(new Handler[] { resourceHandler,, 
                                            restHandler, 
                                            new DefaultHandler(), 
                                            });

    jettyServer.setHandler(handlerList);

Build clause in POM.xml is like this:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<build>
  <resources>
    <resource>
        <directory>${project.basedir}/src/main/webapp</directory>
    </resource>
  </resources>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-shade-plugin</artifactId>
      <version>1.6</version>

      <executions>
        <execution>
          <phase>package</phase>
          <goals>
            <goal>shade</goal>
          </goals>
          <configuration>
            <transformers>
              <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
              <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                <manifestEntries>
                  <Main-Class>com.dastratum.DasConsole.ConsoleMain</Main-Class>
                </manifestEntries>
              </transformer>
            </transformers>
            <minimizeJar>false</minimizeJar>
            <createDependencyReducedPom>true</createDependencyReducedPom>
            <filters>
            <filter>
                <artifact>*:*</artifact>
                <excludes>
                    <exclude>META-INF/*</exclude>
                    <exclude>junit:junit</exclude>
                </excludes>
            </filter>
            </filters>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

</project>

Any help appreciated. Thanks.

1

1 Answers

1
votes

The fundamental part of this question (mixing ResourceHandler & ServletContextHandler) has been answered before.

However, the added wrinkle here is that you are using Jersey, which (historically) will default to serving static files itself, not allowing the Servlet Container to serve the static files via the DefaultServlet.

Would recommend that you drop the ResourceHandler entirely, and setup a proper ResourceBase for your ServletContextHandler (that has Jersey in it), and then make sure you add the DefaultServlet mapped to /. This is likely to work just fine, with Jersey serving the static content, but if you need more control over the static file serving (such as cache control, efficient memory use, intelligent http/2 push filters, etc.) then you'll need to take the extra step of configuring Jersey to not serve static content and let Jetty's DefaultServlet do the work.