Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Working Jetty (experimental).

To try out the embedded Jetty server before the initial release, you
need to build the Warbler Embedded Jetty support. Change to the
`ext/jetty` directory and type `mvn install`. This creates a single
jar file with all of the Jetty dependencies as well as a main class to
launch the embedded server. That jar file is then embedded in the
resulting executable war created by Warbler.
  • Loading branch information...
commit 0558a285eb59a0801cf7c0f274777b06b63883b3 1 parent 128b214
@nicksieger nicksieger authored
View
13 Rakefile
@@ -33,9 +33,9 @@ begin
directory "pkg/classes"
CLEAN << "pkg"
- file jar_file => FileList['ext/**/*.java', 'pkg/classes'] do
+ file jar_file => FileList['ext/*.java', 'pkg/classes'] do
rm_rf FileList['pkg/classes/**/*']
- ant.javac :srcdir => "ext", :destdir => "pkg/classes",
+ ant.javac :srcdir => "ext", :includes => "*.java", :destdir => "pkg/classes",
:source => "1.5", :target => "1.5", :debug => true,
:classpath => "${java.class.path}:${sun.boot.class.path}",
:includeantRuntime => false
@@ -52,14 +52,7 @@ rescue LoadError
end
# Make sure jar gets compiled before the gem is built
-task Rake::Task['build'].prerequisites.first => :jar
-
-task :warbler_jar => 'pkg' do
- ruby "-rubygems", "-Ilib", "-S", "bin/warble"
- mv "warbler.jar", "pkg/warbler-#{Warbler::VERSION}.jar"
-end
-
-task :build => :warbler_jar
+task :build => :jar
require 'rdoc/task'
RDoc::Task.new(:docs) do |rd|
View
79 ext/WarMain.java
@@ -13,10 +13,13 @@
import java.io.File;
import java.io.FileOutputStream;
import java.util.Arrays;
+import java.util.Properties;
+import java.util.Map;
public class WarMain implements Runnable {
public static final String MAIN = "/" + WarMain.class.getName().replace('.', '/') + ".class";
- public static final String WINSTONE_JAR = "/WEB-INF/webserver.jar";
+ public static final String WEBSERVER_PROPERTIES = "/WEB-INF/webserver.properties";
+ public static final String WEBSERVER_JAR = "/WEB-INF/webserver.jar";
private String[] args;
private String path, warfile;
@@ -29,16 +32,17 @@ public WarMain(String[] args) throws Exception {
this.path = mainClass.toURI().getSchemeSpecificPart();
this.warfile = this.path.replace("!" + MAIN, "").replace("file:", "");
this.debug = isDebug();
- this.webroot = File.createTempFile("winstone", "webroot");
+ this.webroot = File.createTempFile("warbler", "webroot");
this.webroot.delete();
this.webroot.mkdirs();
this.webroot = new File(this.webroot, new File(warfile).getName());
+ debug("webroot directory is " + this.webroot.getPath());
Runtime.getRuntime().addShutdownHook(new Thread(this));
}
- private URL extractWinstone() throws Exception {
- InputStream jarStream = new URL("jar:" + path.replace(MAIN, WINSTONE_JAR)).openStream();
- File jarFile = File.createTempFile("winstone", ".jar");
+ private URL extractWebserver() throws Exception {
+ InputStream jarStream = new URL("jar:" + path.replace(MAIN, WEBSERVER_JAR)).openStream();
+ File jarFile = File.createTempFile("webserver", ".jar");
jarFile.deleteOnExit();
FileOutputStream outStream = new FileOutputStream(jarFile);
try {
@@ -51,26 +55,69 @@ private URL extractWinstone() throws Exception {
jarStream.close();
outStream.close();
}
- debug("winstone.jar extracted to " + jarFile.getPath());
+ debug("webserver.jar extracted to " + jarFile.getPath());
return jarFile.toURI().toURL();
}
- private void launchWinstone(URL jar) throws Exception {
+ private Properties getWebserverProperties() throws Exception {
+ Properties props = new Properties();
+ try {
+ InputStream is = getClass().getResourceAsStream(WEBSERVER_PROPERTIES);
+ props.load(is);
+ } catch (Exception e) {
+ }
+
+ for (Map.Entry entry : props.entrySet()) {
+ String val = (String) entry.getValue();
+ val = val.replace("{{warfile}}", warfile).replace("{{webroot}}", webroot.getAbsolutePath());
+ entry.setValue(val);
+ }
+
+ if (props.getProperty("props") != null) {
+ String[] propsToSet = props.getProperty("props").split(",");
+ for (String key : propsToSet) {
+ System.setProperty(key, props.getProperty(key));
+ }
+ }
+
+ return props;
+ }
+
+ private void launchWebserver(URL jar) throws Exception {
URLClassLoader loader = new URLClassLoader(new URL[] {jar});
- Class klass = Class.forName("winstone.Launcher", true, loader);
+ Thread.currentThread().setContextClassLoader(loader);
+ Properties props = getWebserverProperties();
+ String mainClass = props.getProperty("mainclass");
+ if (mainClass == null) {
+ throw new IllegalArgumentException("unknown webserver main class ("
+ + WEBSERVER_PROPERTIES
+ + " is missing 'mainclass' property)");
+ }
+ Class klass = Class.forName(mainClass, true, loader);
Method main = klass.getDeclaredMethod("main", new Class[] {String[].class});
- String[] newargs = new String[args.length + 3];
- newargs[0] = "--warfile=" + warfile;
- newargs[1] = "--webroot=" + webroot;
- newargs[2] = "--directoryListings=false";
- System.arraycopy(args, 0, newargs, 3, args.length);
- debug("invoking Winstone with: " + Arrays.deepToString(newargs));
+ String[] newargs = launchArguments(props);
+ debug("invoking webserver with: " + Arrays.deepToString(newargs));
main.invoke(null, new Object[] {newargs});
}
+ private String[] launchArguments(Properties props) {
+ String[] newargs = args;
+
+ if (props.getProperty("args") != null) {
+ String[] insertArgs = props.getProperty("args").split(",");
+ newargs = new String[args.length + insertArgs.length];
+ for (int i = 0; i < insertArgs.length; i++) {
+ newargs[i] = props.getProperty(insertArgs[i], "");
+ }
+ System.arraycopy(args, 0, newargs, insertArgs.length, args.length);
+ }
+
+ return newargs;
+ }
+
private void start() throws Exception {
- URL u = extractWinstone();
- launchWinstone(u);
+ URL u = extractWebserver();
+ launchWebserver(u);
}
private void debug(String msg) {
View
45 ext/jetty/src/main/java/JettyWarMain.java
@@ -4,28 +4,51 @@
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.webapp.WebAppContext;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+
public class JettyWarMain {
+
public static void main(String[] args) throws Exception {
- String war = "test.war";
- if (args.length > 0) {
- war = args[0];
+ if (args.length == 0) {
+ throw new IllegalArgumentException("missing war file name");
}
- Server server = new Server();
-
- Connector connector = new SelectChannelConnector();
- connector.setPort(Integer.getInteger("jetty.port",8080).intValue());
- server.setConnectors(new Connector[]{connector});
+ // Ensure we have a "work" directory for the webapp
+ if (System.getProperty("jetty.home") != null) {
+ new File(System.getProperty("jetty.home"), "work").mkdirs();
+ }
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/");
webapp.setExtractWAR(true);
- webapp.setWar(war);
- webapp.setDefaultsDescriptor("src/main/resources/webdefault.xml");
+ webapp.setWar(args[0]);
+ webapp.setDefaultsDescriptor(webdefaultPath());
+ Server server = new Server();
+ Connector connector = new SelectChannelConnector();
+ connector.setPort(Integer.getInteger("jetty.port",8080).intValue());
+ server.setConnectors(new Connector[]{connector});
server.setHandler(webapp);
-
server.start();
server.join();
}
+
+ private static String webdefaultPath() throws Exception {
+ String path = System.getProperty("jetty.home", System.getProperty("java.io.tmpdir")) + System.getProperty("file.separator") + "webdefault.xml";
+ FileOutputStream out = new FileOutputStream(path);
+ InputStream is = JettyWarMain.class.getResourceAsStream("/webdefault.xml");
+ try {
+ byte[] buf = new byte[4096];
+ int bytesRead = 0;
+ while ((bytesRead = is.read(buf)) != -1) {
+ out.write(buf, 0, bytesRead);
+ }
+ } finally {
+ is.close();
+ out.close();
+ }
+ return path;
+ }
}
View
1  lib/warbler/config.rb
@@ -146,6 +146,7 @@ class Config
# Embedded webserver to use. Currently supported webservers are:
# * <tt>winstone</tt> (default) - Winstone 0.9.10 from sourceforge
# * <tt>jenkins-ci.winstone</tt> - Improved Winstone from Jenkins CI
+ # * <tt>jetty</tt> - Embedded Jetty from Eclipse
attr_accessor :webserver
attr_reader :warbler_templates
View
50 lib/warbler/web_server.rb
@@ -35,14 +35,8 @@ def local_path
end
end
- def initialize(artifacts)
- @artifacts = artifacts
- end
-
def add(jar)
- artifacts.each do |a|
- jar.files["WEB-INF/#{a.artifact_id}.jar"] = a.local_path
- end
+ jar.files["WEB-INF/webserver.jar"] = @artifact.local_path
end
def main_class
@@ -52,25 +46,47 @@ def main_class
class WinstoneServer < WebServer
def initialize
- super([Artifact.new(ENV["MAVEN_REPO"] || "http://repo2.maven.org/maven2",
- "net.sourceforge.winstone", "winstone-lite",
- ENV["WEBSERVER_VERSION"] || "0.9.10")])
+ @artifact = Artifact.new(ENV["MAVEN_REPO"] || "http://repo2.maven.org/maven2",
+ "net.sourceforge.winstone", "winstone-lite",
+ ENV["WEBSERVER_VERSION"] || "0.9.10")
+ end
+
+ def add(jar)
+ super
+ jar.files["WEB-INF/webserver.properties"] = StringIO.new(<<-PROPS)
+mainclass = winstone.Launcher
+args = args0,args1,args2
+args0 = --warfile={{warfile}}
+args1 = --webroot={{webroot}}
+args2 = --directoryListings=false
+PROPS
end
end
- class JenkinsWinstoneServer < WebServer
+ class JenkinsWinstoneServer < WinstoneServer
def initialize
- super([Artifact.new("http://maven.jenkins-ci.org/content/groups/artifacts",
- "org.jenkins-ci", "winstone",
- ENV["WEBSERVER_VERSION"] || "0.9.10-jenkins-35")])
+ @artifact = Artifact.new("http://maven.jenkins-ci.org/content/groups/artifacts",
+ "org.jenkins-ci", "winstone",
+ ENV["WEBSERVER_VERSION"] || "0.9.10-jenkins-35")
end
end
class JettyServer < WebServer
def initialize
- super([Artifact.new(ENV["MAVEN_REPO"] || "http://repo2.maven.org/maven2",
- "org.jruby.warbler", "warbler-embedded-jetty",
- ENV["WEBSERVER_VERSION"] || "1.0.0")])
+ @artifact = Artifact.new(ENV["MAVEN_REPO"] || "http://repo2.maven.org/maven2",
+ "org.jruby.warbler", "warbler-embedded-jetty",
+ ENV["WEBSERVER_VERSION"] || "1.0.0")
+ end
+
+ def add(jar)
+ super
+ jar.files["WEB-INF/webserver.properties"] = StringIO.new(<<-PROPS)
+mainclass = JettyWarMain
+args = args0
+props = jetty.home
+args0 = {{warfile}}
+jetty.home = {{webroot}}
+PROPS
end
end
View
BIN  lib/warbler_jar.jar
Binary file not shown
Please sign in to comment.
Something went wrong with that request. Please try again.