Is it possible to store static resources inside the uber jar created with an embedded jetty project?

384 views Asked by At

Is it possible to store static resources inside the uber jar created with an embedded jetty server project? I created this simple project based on an answer by @JoakimErdfelt Serving static files from alternate path in embedded Jetty. I kept the default-servlet to serve the static content, but I switched the dynamic-servlet for a restful jersey-servlet and it works great as long as the jar is in the same directory as the index.html. I would like to be able to embed the index.html file inside the jar but when I issue "mvn clean install" the webapp directory doesn't appear in the jar that's built. I think the pom.xml needs an entry but I don't know what it is and I think the jetty.java needs to change to find the index.html inside the embedded webapp directory. Here is the current directory structure.

static-rest\src\main\java\org\rest\jetty.java

static-rest\src\main\java\org\rest\rest.java

static-rest\src\main\java\webapp\index.html

static-rest\pom.xml

jetty.java

package org.rest;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;

public class Jetty {
    public static void main(String[] args) throws Exception {

        System.setProperty("org.eclipse.jetty.LEVEL","INFO");

        Server server = new Server();
        ServerConnector connector = new ServerConnector(server);
        connector.setPort(8080);
        server.addConnector(connector);

        // Setup the basic appliation "context" for this application at "/"
        // This is also known as the handler tree (in jetty speak)
        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
        server.setHandler(context);

        // The filesystem paths we will map
        String homePath = System.getProperty("user.home");
        String pwdPath = System.getProperty("user.dir");

        // add a simple Servlet at "dynamic/*"
        ServletHolder holderDynamic = new ServletHolder(
            "dynamic", org.glassfish.jersey.servlet.ServletContainer.class);
        context.addServlet(holderDynamic, "/dynamic/*");

        holderDynamic.setInitOrder(0);

        // Tells the Jersey Servlet which REST service/class to load.
        holderDynamic.setInitParameter(
           "jersey.config.server.provider.classnames",
           Rest.class.getCanonicalName());

        // add special pathspec of "/home/" content mapped to the homePath
        ServletHolder holderHome = new ServletHolder(
            "static-home", DefaultServlet.class);
        holderHome.setInitParameter("resourceBase",homePath);
        holderHome.setInitParameter("dirAllowed","true");
        holderHome.setInitParameter("pathInfoOnly","true");
        context.addServlet(holderHome,"/home/*");

        // Lastly, the default servlet for root content (always needed, to satisfy servlet spec)
        // It is important that this is last.
        ServletHolder holderPwd = new ServletHolder(
            "default", DefaultServlet.class);
        holderPwd.setInitParameter("resourceBase",pwdPath);
        holderPwd.setInitParameter("dirAllowed","true");
        context.addServlet(holderPwd,"/");

        try
        {
            server.start();
            server.dump(System.err);
            server.join();
        }
        catch (Throwable t)
        {
            t.printStackTrace(System.err);
        }
    }
}

rest.java

package org.rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

    @Path("/rest")
public class Rest {

    @GET
    @Path("/{msg}")
    @Produces(MediaType.TEXT_PLAIN)
    public String echo(@PathParam("msg") String msg) {
        return "echo: " + msg;
    }
}

index.html

<html>
<body>
<p>Send Restful Request Demo</p>
<input type="text" id="myText" value="message">
<button onclick="myFunction()">Send</button>
<p id="demo"></p>
<script>
function myFunction() {
  var msg = document.getElementById("myText").value;
  var xmlhttp = new XMLHttpRequest();
  xmlhttp.onreadystatechange = function(){
    if (xmlhttp.readyState==4 && xmlhttp.status==200){
      document.getElementById("demo").innerHTML=xmlhttp.responseText;
    }
  }
  xmlhttp.open("GET", "http://localhost:8080/dynamic/rest/" + msg, true);
  xmlhttp.send();
}
</script>
</body>
</html>

pom.xml

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.games.solitaire</groupId>
  <artifactId>static-rest</artifactId>
  <packaging>jar</packaging>
  <version>0.1-SNAPSHOT</version>
  <name>static-rest</name>
  <url>http://maven.apache.org</url>
  <dependencies>
     <dependency>
      <groupId>org.eclipse.jetty</groupId>
      <artifactId>jetty-server</artifactId>
      <version>9.2.3.v20140905</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.jetty</groupId>
      <artifactId>jetty-servlet</artifactId>
      <version>9.2.3.v20140905</version>
    </dependency>
    <dependency>
      <groupId>org.glassfish.jersey.core</groupId>
      <artifactId>jersey-server</artifactId>
      <version>2.7</version>
    </dependency>
    <dependency>
      <groupId>org.glassfish.jersey.containers</groupId>
      <artifactId>jersey-container-servlet-core</artifactId>
      <version>2.7</version>
    </dependency>
    <dependency>
      <groupId>org.glassfish.jersey.containers</groupId>
      <artifactId>jersey-container-jetty-http</artifactId>
      <version>2.7</version>
    </dependency>
    <dependency>
      <groupId>org.glassfish.jersey.media</groupId>
      <artifactId>jersey-media-moxy</artifactId>
      <version>2.7</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>1.6</version>
        <configuration>
          <createDependencyReducedPom>true</createDependencyReducedPom>
          <filters>
            <filter>
              <artifact>*:*</artifact>
              <excludes>
                <exclude>META-INF/*.SF</exclude>
                <exclude>META-INF/*.DSA</exclude>
                <exclude>META-INF/*.RSA</exclude>
              </excludes>
            </filter>
          </filters>
        </configuration>

        <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>org.rest.Jetty</Main-Class>
                  </manifestEntries>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>
0

There are 0 answers