aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2013-01-11 22:24:26 +0100
committerTrygve Laugstøl <trygvis@inamo.no>2013-01-11 22:24:26 +0100
commite5b20aa811ed2180d01e71d96c3d5d2ffa886c5f (patch)
treedad879d954a01a74712bc1807be01b09b97ef7f1
parentb327982f49172604c38ca3ca7af28b49b3407102 (diff)
downloadapp.sh-booter-jetty-e5b20aa811ed2180d01e71d96c3d5d2ffa886c5f.tar.gz
app.sh-booter-jetty-e5b20aa811ed2180d01e71d96c3d5d2ffa886c5f.tar.bz2
app.sh-booter-jetty-e5b20aa811ed2180d01e71d96c3d5d2ffa886c5f.tar.xz
app.sh-booter-jetty-e5b20aa811ed2180d01e71d96c3d5d2ffa886c5f.zip
o New feature: Ability to run web apps from nested classpath (foo.jar!/my-webapp/WEB-INF/web.xml).
o Refactored the code to separate configuration from the "active" parts.
-rw-r--r--pom.xml2
-rwxr-xr-xsrc/main/java/io/trygvis/appsh/booter/jetty/JettyWebServer.java188
-rwxr-xr-xsrc/main/java/io/trygvis/appsh/booter/jetty/Main.java6
3 files changed, 118 insertions, 78 deletions
diff --git a/pom.xml b/pom.xml
index 26d3184..1cdcf93 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,10 +9,10 @@
<groupId>io.trygvis.appsh</groupId>
<artifactId>booter-jetty</artifactId>
<version>8.1.8.v20121106+2-SNAPSHOT</version>
+ <name>App.sh :: Jetty Booter for Jetty v${versions.jetty8}</name>
<properties>
<versions.jetty8>8.1.8.v20121106</versions.jetty8>
</properties>
- <name>App.sh :: Jetty Booter</name>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
diff --git a/src/main/java/io/trygvis/appsh/booter/jetty/JettyWebServer.java b/src/main/java/io/trygvis/appsh/booter/jetty/JettyWebServer.java
index 03fb17c..7f07fb7 100755
--- a/src/main/java/io/trygvis/appsh/booter/jetty/JettyWebServer.java
+++ b/src/main/java/io/trygvis/appsh/booter/jetty/JettyWebServer.java
@@ -24,7 +24,6 @@ import java.util.List;
*/
public class JettyWebServer {
private File basedir = new File("").getAbsoluteFile();
- private File tmp, extraClasspath;
private int httpPort = 8080;
List<Context> contexts = new ArrayList<Context>();
@@ -37,75 +36,22 @@ public class JettyWebServer {
this.httpPort = port;
}
- public Context addContext(String contextPath, File webapp) throws Exception {
- Context context = new Context();
- context.setContextPath(contextPath);
- context.setWebapp(webapp);
+ public Context addContext(Context context) throws Exception {
contexts.add(context);
return context;
}
/**
- * Adds a web application context from within the classpath.
- *
- * To get JSPs to work the app has to be extracted
- *
- * @param contextPath Where to "mount" the application, for example /myapp
- * @param war Where there extracted files are places. Will be cleaned out before starting.
- * @param prefix Where to start the classpath scan, for example "/my-awesome-webapp".
- */
- public Context addClasspathContext(String contextPath, File war, String prefix) throws Exception {
- war = war.getAbsoluteFile();
-
- // Clean out any old cruft
- if (war.isDirectory()) {
- IO.delete(war);
- }
-
- if (!war.mkdirs()) {
- System.err.println("Could not create directory: " + war);
- System.exit(-1);
- }
-
- // Classloaders doesn't like slash prefixed searches.
- if (prefix.startsWith("/")) {
- prefix = prefix.substring(1);
- }
-
- Enumeration<URL> enumeration = Main.class.getClassLoader().getResources(prefix);
-
- // TODO: just check for presence of WEB-INF/web.xml after extraction.
- if (!enumeration.hasMoreElements()) {
- System.err.println("Could not look up classpath resource: '" + prefix + "'.");
- System.exit(-1);
- }
-
- while (enumeration.hasMoreElements()) {
- URL url = enumeration.nextElement();
-
- try {
- Resource resource = Resource.newResource(url);
-
- resource.copyTo(war);
- } catch (IOException e) {
- System.err.println("Unable to extract " + url.toExternalForm() + " to " + war);
- }
- }
-
- return addContext(contextPath, war);
- }
-
- /**
* This should be moved to the main method. JettyWebServer should only be code to set up Jetty.
*/
public void run() throws Exception {
- tmp = new File(basedir, "tmp");
+ File tmp = new File(basedir, "tmp/jetty-booter");
if (!tmp.isDirectory() && !tmp.mkdirs()) {
throw new IOException("Could not create temp directory: " + tmp);
}
- extraClasspath = new File(basedir, "etc");
+ File extraClasspath = new File(basedir, "etc");
if (!extraClasspath.isDirectory()) {
extraClasspath = null;
@@ -127,26 +73,31 @@ public class JettyWebServer {
ContextHandlerCollection handler = new ContextHandlerCollection();
server.setHandler(handler);
+
+ ServerSettings settings = new ServerSettings(tmp, extraClasspath != null ? extraClasspath.getAbsolutePath() : null);
+
for (Context context : contexts) {
- handler.addHandler(context.toJetty(tmp));
+ handler.addHandler(context.toJetty(settings));
}
server.start();
server.join();
}
- public class Context {
- private File webapp;
- private String contextPath;
+ public static class ServerSettings {
+ public final File tmp;
+ public final String extraClasspath;
- public void setWebapp(File webapp) throws IOException {
- if (!webapp.exists()) {
- throw new IOException("File has to exist: " + webapp);
- }
- this.webapp = webapp;
+ public ServerSettings(File tmp, String extraClasspath) {
+ this.tmp = tmp;
+ this.extraClasspath = extraClasspath;
}
+ }
- public void setContextPath(String contextPath) {
+ private static abstract class Context {
+ public final String contextPath;
+
+ protected Context(String contextPath) {
if (!contextPath.startsWith("/")) {
throw new RuntimeException("The context path has to start with '/'.");
}
@@ -154,7 +105,30 @@ public class JettyWebServer {
this.contextPath = contextPath;
}
- public ContextHandler toJetty() {
+ public String getContextPath() {
+ return contextPath;
+ }
+
+ protected abstract ContextHandler toJetty(ServerSettings settings) throws IOException;
+ }
+
+ public static class WarContext extends Context {
+ private final File webapp;
+
+ public WarContext(String contextPath, File webapp) throws IOException {
+ super(contextPath);
+ this.webapp = webapp;
+
+ if (!webapp.exists()) {
+ throw new IOException("File has to exist: " + webapp);
+ }
+ }
+
+ protected ContextHandler toJetty(ServerSettings settings) {
+ return warContext(settings, contextPath, webapp);
+ }
+
+ public static ContextHandler warContext(ServerSettings settings, String contextPath, File webapp) {
WebAppContext context = new WebAppContext();
/*
@@ -167,20 +141,88 @@ public class JettyWebServer {
*/
context.setInitParameter("org.eclipse.jetty.servlet.Default.useFileMappedBuffer", "false");
- context.setContextPath(this.contextPath);
+ context.setContextPath(contextPath);
context.setWar(webapp.getAbsolutePath());
- if (extraClasspath != null) {
- context.setExtraClasspath(extraClasspath.getAbsolutePath());
+ if (settings.extraClasspath != null) {
+ context.setExtraClasspath(settings.extraClasspath);
}
context.setExtractWAR(true);
// TODO: Should the temp directory be cleaned out before starting?
String dir = contextPath.substring(1);
if (dir.length() == 0) {
- dir = "ROOT";
+ dir = "ROOT-tmp";
}
- context.setTempDirectory(new File(tmp, dir));
+ context.setTempDirectory(new File(settings.tmp, dir));
return context;
}
}
+
+ /**
+ * Adds a web application context from within the classpath.
+ *
+ * To get JSPs to work the app has to be extracted
+ */
+ public static class ClasspathContext extends Context {
+ private final String prefix;
+
+ /**
+ * @param contextPath Where to "mount" the application, for example /my-app
+ * @param prefix Where to start the classpath scan, for example "/my-awesome-webapp".
+ */
+ public ClasspathContext(String contextPath, String prefix) {
+ super(contextPath);
+ this.prefix = prefix;
+ }
+
+ protected ContextHandler toJetty(ServerSettings settings) throws IOException {
+ String prefix = this.prefix;
+
+ String tmpName;
+ if (contextPath.length() == 1) {
+ tmpName = "ROOT-web";
+ } else {
+ tmpName = contextPath.substring(1).replace('/', '_');
+ }
+
+ File war = new File(settings.tmp, tmpName);
+ // Clean out any old cruft
+ if (war.isDirectory()) {
+ IO.delete(war);
+ }
+
+ if (!war.mkdirs()) {
+ System.err.println("Could not create directory: " + war);
+ System.exit(-1);
+ }
+
+ // Classloaders doesn't like slash prefixed searches.
+ if (prefix.startsWith("/")) {
+ prefix = prefix.substring(1);
+ }
+
+ Enumeration<URL> enumeration = Main.class.getClassLoader().getResources(prefix);
+
+ // TODO: just check for presence of WEB-INF/web.xml after extraction.
+ if (!enumeration.hasMoreElements()) {
+ System.err.println("Could not look up classpath resource: '" + prefix + "'.");
+ System.exit(-1);
+ }
+
+ while (enumeration.hasMoreElements()) {
+ URL url = enumeration.nextElement();
+
+ try {
+ Resource resource = Resource.newResource(url);
+
+ resource.copyTo(war);
+ } catch (IOException e) {
+ System.err.println("Unable to extract " + url.toExternalForm() + " to " + war + ": " + e.getMessage());
+ System.exit(-1);
+ }
+ }
+
+ return WarContext.warContext(settings, contextPath, war);
+ }
+ }
}
diff --git a/src/main/java/io/trygvis/appsh/booter/jetty/Main.java b/src/main/java/io/trygvis/appsh/booter/jetty/Main.java
index 1f2c58f..b0784a7 100755
--- a/src/main/java/io/trygvis/appsh/booter/jetty/Main.java
+++ b/src/main/java/io/trygvis/appsh/booter/jetty/Main.java
@@ -53,12 +53,10 @@ public class Main {
if (value.startsWith("classpath:")) {
value = value.substring(10);
- File war = new File("wat");
-
- server.addClasspathContext(contextPath, war, value);
+ server.addContext(new JettyWebServer.ClasspathContext(contextPath, value));
}
else {
- server.addContext(contextPath, new File(basedir, value));
+ server.addContext(new JettyWebServer.WarContext(contextPath, new File(basedir, value)));
}
}
}