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>