aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x[-rw-r--r--]README.md25
-rwxr-xr-x[-rw-r--r--]src/main/java/io/trygvis/appsh/booter/jetty/JettyWebServer.java67
-rwxr-xr-x[-rw-r--r--]src/main/java/io/trygvis/appsh/booter/jetty/Main.java14
3 files changed, 103 insertions, 3 deletions
diff --git a/README.md b/README.md
index 5d767f8..695755e 100644..100755
--- a/README.md
+++ b/README.md
@@ -1,5 +1,30 @@
+# Usage
+
+This Jetty-based WAR/web application booter is configured through a properties files and environment properties. It
+depends on a specific Jetty version.
+
+## Changing the version of Jetty used
+
+Feel free to use Maven's dependency management to override the version that this plugin depend on. Note that it has
+some sets of dependencies. The major one is Jetty itself. This version is reflected in the booter's version itself. The
+rest of the dependencies are based on what the Jetty version itself uses.
+
+If you change the Jetty version you should probably download the Jetty distribution for the new version and make sure
+that the versions of the artifacts that the booter depend on match.
+
# Change Log
+## 8.1.8.v20121106+2
+
+### Support for running web apps from inside a JAR file
+
+Example `booter.properties`:
+
+ context./=classpath:/webapp
+
+Note that because of the current JSP implementation the webapp has to be extracted for the JSP compiler to be able to
+find the files. It also requires a temporary area to write the class files.
+
## 8.1.8.v20121106+1 - 2012-12-20
Upgrading to 8.1.8.
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 6a7b63a..03fb17c 100644..100755
--- a/src/main/java/io/trygvis/appsh/booter/jetty/JettyWebServer.java
+++ b/src/main/java/io/trygvis/appsh/booter/jetty/JettyWebServer.java
@@ -4,14 +4,24 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.log.StdErrLog;
+import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext;
import java.io.File;
import java.io.IOException;
+import java.net.URL;
import java.util.ArrayList;
+import java.util.Enumeration;
import java.util.List;
+/**
+ * A web server that's expected to be used from main() methods.
+ *
+ * The main method is expected to know how to configure the server. It will use System.err and System.exit(-1) on
+ * errors.
+ */
public class JettyWebServer {
private File basedir = new File("").getAbsoluteFile();
private File tmp, extraClasspath;
@@ -35,6 +45,59 @@ public class JettyWebServer {
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");
@@ -65,7 +128,7 @@ public class JettyWebServer {
ContextHandlerCollection handler = new ContextHandlerCollection();
server.setHandler(handler);
for (Context context : contexts) {
- handler.addHandler(context.toJetty());
+ handler.addHandler(context.toJetty(tmp));
}
server.start();
@@ -98,7 +161,7 @@ public class JettyWebServer {
* By setting useFileMappedBuffer we prevent Jetty from memory-mapping the static resources
*
* The default servlet can be configured by setting parameters on the context in addition to the default
- * servlet's init params, saving us from injecting the DefaultServlet programatically.
+ * servlet's init params, saving us from injecting the DefaultServlet programmatically.
*
* http://stackoverflow.com/questions/184312/how-to-make-jetty-dynamically-load-static-pages
*/
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 d3920c7..1f2c58f 100644..100755
--- a/src/main/java/io/trygvis/appsh/booter/jetty/Main.java
+++ b/src/main/java/io/trygvis/appsh/booter/jetty/Main.java
@@ -35,6 +35,7 @@ public class Main {
IO.close(is);
}
+ // TODO: This should copy the output to the old std out until we have started if possible.
setStreams(basedir, properties);
JettyWebServer server;
@@ -47,7 +48,18 @@ public class Main {
String value = entry.getValue().toString();
if (key.startsWith("context.")) {
- server.addContext(key.substring(8), new File(basedir, value));
+ String contextPath = key.substring(8);
+
+ if (value.startsWith("classpath:")) {
+ value = value.substring(10);
+
+ File war = new File("wat");
+
+ server.addClasspathContext(contextPath, war, value);
+ }
+ else {
+ server.addContext(contextPath, new File(basedir, value));
+ }
}
}