You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by jk...@apache.org on 2016/07/14 05:42:18 UTC

tapestry-5 git commit: TAP5-2548: upgrade embedded Tomcat and Jetty versions

Repository: tapestry-5
Updated Branches:
  refs/heads/master 91af872e1 -> 95413c0c9


TAP5-2548: upgrade embedded Tomcat and Jetty versions


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/95413c0c
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/95413c0c
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/95413c0c

Branch: refs/heads/master
Commit: 95413c0c9633612d42ff07f3636b8501ebb6e56a
Parents: 91af872
Author: Jochen Kemnade <jk...@apache.org>
Authored: Wed May 18 09:55:37 2016 +0200
Committer: Jochen Kemnade <jk...@apache.org>
Committed: Thu Jul 14 07:40:22 2016 +0200

----------------------------------------------------------------------
 55_RELEASE_NOTES.md                             |   7 +
 build.gradle                                    |   4 +-
 tapestry-core/build.gradle                      |   2 +-
 .../org/apache/tapestry5/LaunchJetty7.groovy    |  21 --
 .../org/apache/tapestry5/LaunchJetty8.groovy    |  21 ++
 .../apache/tapestry5/integration/RunJetty.java  |   4 +-
 .../integration/cluster/ClusterTests.java       |  10 +-
 tapestry-runner/build.gradle                    |   6 +-
 .../org/apache/tapestry5/test/Jetty7Runner.java | 232 ------------------
 .../org/apache/tapestry5/test/JettyRunner.java  | 235 +++++++++++++++++++
 .../apache/tapestry5/test/Tomcat6Runner.java    | 151 ------------
 .../org/apache/tapestry5/test/TomcatRunner.java | 120 ++++++++++
 .../apache/tapestry5/test/SeleniumTestCase.java |   4 +-
 .../apache/tapestry5/upload/RunJettyUpload.java |   4 +-
 .../webresources/tests/CssCompressorSpec.groovy |   2 +-
 .../webresources/tests/WebResourcesSpec.groovy  |   4 +-
 16 files changed, 403 insertions(+), 424 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95413c0c/55_RELEASE_NOTES.md
----------------------------------------------------------------------
diff --git a/55_RELEASE_NOTES.md b/55_RELEASE_NOTES.md
new file mode 100644
index 0000000..d4e65e4
--- /dev/null
+++ b/55_RELEASE_NOTES.md
@@ -0,0 +1,7 @@
+Scratch pad for changes destined for the 5.5 release notes page.
+
+# Java 8 required
+The minimum Java release required to run apps created with Tapestry 5.5 is Java 8.
+
+# Updates to embedded Tomcat and Jetty versions (TAP5-2548)
+With Java 8, we made the switch to servlet-api 3.0. We updated the embedded Tomcat and Jetty containers to the respective versions. Unfortunately, we had to rename Jetty7Runner to JettyRunner and Tomcat6Runner to TomcatRunner in the tapestry-runner package.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95413c0c/build.gradle
----------------------------------------------------------------------
diff --git a/build.gradle b/build.gradle
index 635322f..4b90a01 100755
--- a/build.gradle
+++ b/build.gradle
@@ -9,8 +9,8 @@ apply from: "ssh.gradle"
 apply from: "md5.gradle"
 
 project.ext.versions = [
-    jetty: "7.6.11.v20130520",
-    tomcat: "6.0.30",
+    jetty: "8.1.19.v20160209",
+    tomcat: "7.0.70",
     testng: "6.8.21",
     easymock: "3.3.1",
     servletapi: "3.0.1",

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95413c0c/tapestry-core/build.gradle
----------------------------------------------------------------------
diff --git a/tapestry-core/build.gradle b/tapestry-core/build.gradle
index e0f8d8d..d7453dd 100644
--- a/tapestry-core/build.gradle
+++ b/tapestry-core/build.gradle
@@ -66,7 +66,7 @@ jar {
 }
 
 task runTestApp1(type:JavaExec) {
-  main = 'org.apache.tapestry5.test.Jetty7Runner'
+  main = 'org.apache.tapestry5.test.JettyRunner'
   args "-d", "src/test/app1", "-p", "8080"
   classpath += project.sourceSets.test.runtimeClasspath
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95413c0c/tapestry-core/src/test/groovy/org/apache/tapestry5/LaunchJetty7.groovy
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/LaunchJetty7.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/LaunchJetty7.groovy
deleted file mode 100644
index 32f3266..0000000
--- a/tapestry-core/src/test/groovy/org/apache/tapestry5/LaunchJetty7.groovy
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2011 The Apache Software Foundation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import org.apache.tapestry5.test.Jetty7Runner
-
-if (this.args.length != 1) {
-  fail "Expects one argument: the path to the web context to execute."
-}
-
-new Jetty7Runner(this.args[0], "/", 8080, 9999).start()

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95413c0c/tapestry-core/src/test/groovy/org/apache/tapestry5/LaunchJetty8.groovy
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/LaunchJetty8.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/LaunchJetty8.groovy
new file mode 100644
index 0000000..393a40c
--- /dev/null
+++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/LaunchJetty8.groovy
@@ -0,0 +1,21 @@
+// Copyright 2011 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import org.apache.tapestry5.test.JettyRunner
+
+if (this.args.length != 1) {
+  fail "Expects one argument: the path to the web context to execute."
+}
+
+new JettyRunner(this.args[0], "/", 8080, 9999).start()

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95413c0c/tapestry-core/src/test/java/org/apache/tapestry5/integration/RunJetty.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/RunJetty.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/RunJetty.java
index 93f1097..e84aa76 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/RunJetty.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/RunJetty.java
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry5.integration;
 
-import org.apache.tapestry5.test.Jetty7Runner;
+import org.apache.tapestry5.test.JettyRunner;
 
 /**
  * A "shim" to run Demo App #1 inside IntelliJ.  I still haven't found a way to get IntelliJ to export test classes and
@@ -27,6 +27,6 @@ public class RunJetty
         String contextName = args[0];
         String path = args[1];
         
-        new Jetty7Runner(path, contextName, 9090, 8443);
+        new JettyRunner(path, contextName, 9090, 8443);
     }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95413c0c/tapestry-core/src/test/java/org/apache/tapestry5/integration/cluster/ClusterTests.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/cluster/ClusterTests.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/cluster/ClusterTests.java
index 9feb752..4670aaf 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/cluster/ClusterTests.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/cluster/ClusterTests.java
@@ -16,7 +16,7 @@ package org.apache.tapestry5.integration.cluster;
 
 import com.thoughtworks.selenium.DefaultSelenium;
 import com.thoughtworks.selenium.Selenium;
-import org.apache.tapestry5.test.Jetty7Runner;
+import org.apache.tapestry5.test.JettyRunner;
 import org.apache.tapestry5.test.TapestryTestConstants;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.session.JDBCSessionIdManager;
@@ -63,9 +63,9 @@ public class ClusterTests
 
     private static final String CLEAR = "//a[contains(text(),'Clear')]";
 
-    Jetty7Runner serverA;
+    JettyRunner serverA;
 
-    Jetty7Runner serverB;
+    JettyRunner serverB;
 
     SeleniumServer seleniumServer;
     Selenium selenium;
@@ -194,9 +194,9 @@ public class ClusterTests
         selenium.waitForPageToLoad("5000");
     }
 
-    private Jetty7Runner configureClusteredJetty(String name, int port) throws Exception
+    private JettyRunner configureClusteredJetty(String name, int port) throws Exception
     {
-        Jetty7Runner runner = new Jetty7Runner();
+        JettyRunner runner = new JettyRunner();
 
         runner.configure("src/test/cluster", "", port, port + 100);
 

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95413c0c/tapestry-runner/build.gradle
----------------------------------------------------------------------
diff --git a/tapestry-runner/build.gradle b/tapestry-runner/build.gradle
index 009c9f0..f905c70 100644
--- a/tapestry-runner/build.gradle
+++ b/tapestry-runner/build.gradle
@@ -8,9 +8,9 @@ dependencies {
     compile "org.eclipse.jetty:jetty-plus:${versions.jetty}"
     compile "org.eclipse.jetty:jetty-webapp:${versions.jetty}"
 
-    compile "org.apache.tomcat:catalina:${versions.tomcat}"
-    compile "org.apache.tomcat:coyote:${versions.tomcat}"
+    compile "org.apache.tomcat:tomcat-catalina:${versions.tomcat}"
+    compile "org.apache.tomcat:tomcat-coyote:${versions.tomcat}"
 
-    compile "org.apache.tomcat:dbcp:${versions.tomcat}"
+    compile "org.apache.tomcat:tomcat-dbcp:${versions.tomcat}"
     compile "commons-cli:commons-cli:1.2"
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95413c0c/tapestry-runner/src/main/java/org/apache/tapestry5/test/Jetty7Runner.java
----------------------------------------------------------------------
diff --git a/tapestry-runner/src/main/java/org/apache/tapestry5/test/Jetty7Runner.java b/tapestry-runner/src/main/java/org/apache/tapestry5/test/Jetty7Runner.java
deleted file mode 100644
index 00bcba9..0000000
--- a/tapestry-runner/src/main/java/org/apache/tapestry5/test/Jetty7Runner.java
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2009, 2010, 2011, 2013 The Apache Software Foundation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package org.apache.tapestry5.test;
-
-import org.apache.commons.cli.*;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
-import org.eclipse.jetty.webapp.WebAppContext;
-
-import java.io.File;
-
-/**
- * Launches an instance of Jetty7.
- */
-public class Jetty7Runner implements ServletContainerRunner
-{
-    private Server jettyServer;
-
-    private String description;
-
-    private int port;
-
-    private int sslPort;
-
-    public Jetty7Runner()
-    {
-        // un-configured runner
-    }
-
-    public Jetty7Runner(String webappFolder, String contextPath, int port, int sslPort) throws Exception
-    {
-        configure(webappFolder, contextPath, port, sslPort).start();
-    }
-
-    public Jetty7Runner configure(String webappFolder, String contextPath, int port, int sslPort) throws Exception
-    {
-        this.port = port;
-
-        this.sslPort = sslPort;
-
-        String expandedPath = expand(webappFolder);
-
-        description = String.format("<Jetty7Runner: %s:%s/%s (%s)", contextPath, port, sslPort, expandedPath);
-
-        jettyServer = new Server(port);
-
-        WebAppContext webapp = new WebAppContext();
-        webapp.setContextPath(contextPath);
-        webapp.setWar(expandedPath);
-
-        // SSL support
-        File keystoreFile = new File(TapestryRunnerConstants.MODULE_BASE_DIR, "src/test/conf/keystore");
-
-        if (keystoreFile.exists())
-        {
-            SslSelectChannelConnector sslConnector = new SslSelectChannelConnector();
-
-            sslConnector.setPort(sslPort);
-
-            sslConnector.setKeystore(keystoreFile.getPath());
-
-            sslConnector.setPassword("tapestry");
-
-            sslConnector.setKeyPassword("tapestry");
-
-            jettyServer.addConnector(sslConnector);
-        }
-
-        jettyServer.setHandler(webapp);
-        return this;
-    }
-
-    public void start() throws Exception
-    {
-        jettyServer.start();
-    }
-
-    /**
-     * Immediately shuts down the server instance.
-     */
-    @Override
-    public void stop()
-    {
-        System.out.printf("Stopping Jetty instance on port %d/%d\n", port, sslPort);
-
-        try
-        {
-            // Stop immediately and not gracefully.
-            jettyServer.stop();
-        } catch (Exception ex)
-        {
-            throw new RuntimeException("Error stopping Jetty instance: " + ex.toString(), ex);
-        }
-
-        System.out.println("Jetty instance has stopped.");
-    }
-
-    public Server getServer()
-    {
-        return jettyServer;
-    }
-
-    @Override
-    public String toString()
-    {
-        return description;
-    }
-
-    /**
-     * Needed inside Maven multi-projects to expand a path relative to the module to a complete
-     * path. If the path already is absolute and points to an existing directory, it will be used
-     * unchanged.
-     *
-     * @param moduleLocalPath
-     * @return expanded path
-     * @see TapestryRunnerConstants#MODULE_BASE_DIR
-     */
-    protected String expand(String moduleLocalPath)
-    {
-        File path = new File(moduleLocalPath);
-
-        // Don't expand if the path provided already exists.
-        if (path.isAbsolute() && path.isDirectory())
-            return moduleLocalPath;
-
-        return new File(TapestryRunnerConstants.MODULE_BASE_DIR, moduleLocalPath).getPath();
-    }
-
-    /**
-     * Main entrypoint used to run the Jetty7 instance from the command line.
-     *
-     * @since 5.4
-     */
-    public static void main(String[] args) throws Exception
-    {
-        String commandName = Jetty7Runner.class.getName();
-
-        Options options = new Options();
-
-        String webapp = "src/main/webapp";
-        String context = "/";
-        int httpPort = 8080;
-        int sslPort = 8443;
-
-        options.addOption(OptionBuilder.withLongOpt("directory")
-                .withDescription("Root context directory (defaults to 'src/main/webapp')")
-                .hasArg().withArgName("DIR")
-                .create('d'))
-                .addOption(OptionBuilder.withLongOpt("context")
-                        .withDescription("Context path for application (defaults to '/')")
-                        .hasArg().withArgName("CONTEXT")
-                        .create('c'))
-                .addOption(OptionBuilder.withLongOpt("port")
-                        .withDescription("HTTP port (defaults to 8080)")
-                        .hasArg().withArgName("PORT")
-                        .create('p'))
-                .addOption(OptionBuilder.withLongOpt("secure-port")
-                        .withDescription("HTTPS port (defaults to 8443)")
-                        .hasArg().withArgName("PORT")
-                        .create('s'))
-                .addOption("h", "help", false, "Display command usage");
-
-
-        CommandLine line = new BasicParser().parse(options, args);
-
-        boolean usage = line.hasOption('h');
-
-        if (!usage)
-        {
-            if (line.hasOption('d'))
-            {
-                webapp = line.getOptionValue('d');
-            }
-
-            File folder = new File(webapp);
-
-            if (!folder.exists())
-            {
-                System.err.printf("%s: Directory `%s' does not exist.%n", commandName, webapp);
-                System.exit(-1);
-            }
-
-            if (line.hasOption('p'))
-            {
-                try
-                {
-                    httpPort = Integer.parseInt(line.getOptionValue('p'));
-                } catch (NumberFormatException e)
-                {
-                    usage = true;
-                }
-            }
-
-            if (line.hasOption('s'))
-            {
-                try
-                {
-                    sslPort = Integer.parseInt(line.getOptionValue('s'));
-                } catch (NumberFormatException e)
-                {
-                    usage = true;
-                }
-            }
-
-            if (line.hasOption('c'))
-            {
-                context = line.getOptionValue('c');
-            }
-
-        }
-
-        if (usage)
-        {
-            new HelpFormatter().printHelp(commandName, options);
-            System.exit(-1);
-        }
-
-        new Jetty7Runner(webapp, context, httpPort, sslPort);
-    }
-}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95413c0c/tapestry-runner/src/main/java/org/apache/tapestry5/test/JettyRunner.java
----------------------------------------------------------------------
diff --git a/tapestry-runner/src/main/java/org/apache/tapestry5/test/JettyRunner.java b/tapestry-runner/src/main/java/org/apache/tapestry5/test/JettyRunner.java
new file mode 100644
index 0000000..ba93d07
--- /dev/null
+++ b/tapestry-runner/src/main/java/org/apache/tapestry5/test/JettyRunner.java
@@ -0,0 +1,235 @@
+// Copyright 2009, 2010, 2011, 2013 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.test;
+
+import org.apache.commons.cli.*;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ssl.SslSocketConnector;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.webapp.WebAppContext;
+
+import java.io.File;
+
+/**
+ * Launches an instance of Jetty.
+ */
+public class JettyRunner implements ServletContainerRunner
+{
+    private Server jettyServer;
+
+    private String description;
+
+    private int port;
+
+    private int sslPort;
+
+    public JettyRunner()
+    {
+        // un-configured runner
+    }
+
+    public JettyRunner(String webappFolder, String contextPath, int port, int sslPort) throws Exception
+    {
+        configure(webappFolder, contextPath, port, sslPort).start();
+    }
+
+    public JettyRunner configure(String webappFolder, String contextPath, int port, int sslPort) throws Exception
+    {
+        this.port = port;
+
+        this.sslPort = sslPort;
+
+        String expandedPath = expand(webappFolder);
+
+        description = String.format("<JettyRunner: %s:%s/%s (%s)", contextPath, port, sslPort, expandedPath);
+
+        jettyServer = new Server(port);
+
+        WebAppContext webapp = new WebAppContext();
+        webapp.setContextPath(contextPath);
+        webapp.setWar(expandedPath);
+
+        // SSL support
+        File keystoreFile = new File(TapestryRunnerConstants.MODULE_BASE_DIR, "src/test/conf/keystore");
+
+        if (keystoreFile.exists())
+        {
+            SslContextFactory sslContextFactory = new SslContextFactory();
+
+            sslContextFactory.setKeyStorePath(keystoreFile.getAbsolutePath());
+
+            sslContextFactory.setKeyStorePassword("tapestry");
+
+            sslContextFactory.setKeyManagerPassword("tapestry");
+
+            SslSocketConnector sslConnector = new SslSocketConnector(sslContextFactory);
+
+            sslConnector.setPort(sslPort);
+
+            jettyServer.addConnector(sslConnector);
+        }
+
+        jettyServer.setHandler(webapp);
+        return this;
+    }
+
+    public void start() throws Exception
+    {
+        jettyServer.start();
+    }
+
+    /**
+     * Immediately shuts down the server instance.
+     */
+    @Override
+    public void stop()
+    {
+        System.out.printf("Stopping Jetty instance on port %d/%d\n", port, sslPort);
+
+        try
+        {
+            // Stop immediately and not gracefully.
+            jettyServer.stop();
+        } catch (Exception ex)
+        {
+            throw new RuntimeException("Error stopping Jetty instance: " + ex.toString(), ex);
+        }
+
+        System.out.println("Jetty instance has stopped.");
+    }
+
+    public Server getServer()
+    {
+        return jettyServer;
+    }
+
+    @Override
+    public String toString()
+    {
+        return description;
+    }
+
+    /**
+     * Needed inside Maven multi-projects to expand a path relative to the module to a complete
+     * path. If the path already is absolute and points to an existing directory, it will be used
+     * unchanged.
+     *
+     * @param moduleLocalPath
+     * @return expanded path
+     * @see TapestryRunnerConstants#MODULE_BASE_DIR
+     */
+    protected String expand(String moduleLocalPath)
+    {
+        File path = new File(moduleLocalPath);
+
+        // Don't expand if the path provided already exists.
+        if (path.isAbsolute() && path.isDirectory())
+            return moduleLocalPath;
+
+        return new File(TapestryRunnerConstants.MODULE_BASE_DIR, moduleLocalPath).getPath();
+    }
+
+    /**
+     * Main entrypoint used to run the Jetty instance from the command line.
+     *
+     * @since 5.4
+     */
+    public static void main(String[] args) throws Exception
+    {
+        String commandName = JettyRunner.class.getName();
+
+        Options options = new Options();
+
+        String webapp = "src/main/webapp";
+        String context = "/";
+        int httpPort = 8080;
+        int sslPort = 8443;
+
+        options.addOption(OptionBuilder.withLongOpt("directory")
+                .withDescription("Root context directory (defaults to 'src/main/webapp')")
+                .hasArg().withArgName("DIR")
+                .create('d'))
+                .addOption(OptionBuilder.withLongOpt("context")
+                        .withDescription("Context path for application (defaults to '/')")
+                        .hasArg().withArgName("CONTEXT")
+                        .create('c'))
+                .addOption(OptionBuilder.withLongOpt("port")
+                        .withDescription("HTTP port (defaults to 8080)")
+                        .hasArg().withArgName("PORT")
+                        .create('p'))
+                .addOption(OptionBuilder.withLongOpt("secure-port")
+                        .withDescription("HTTPS port (defaults to 8443)")
+                        .hasArg().withArgName("PORT")
+                        .create('s'))
+                .addOption("h", "help", false, "Display command usage");
+
+
+        CommandLine line = new BasicParser().parse(options, args);
+
+        boolean usage = line.hasOption('h');
+
+        if (!usage)
+        {
+            if (line.hasOption('d'))
+            {
+                webapp = line.getOptionValue('d');
+            }
+
+            File folder = new File(webapp);
+
+            if (!folder.exists())
+            {
+                System.err.printf("%s: Directory `%s' does not exist.%n", commandName, webapp);
+                System.exit(-1);
+            }
+
+            if (line.hasOption('p'))
+            {
+                try
+                {
+                    httpPort = Integer.parseInt(line.getOptionValue('p'));
+                } catch (NumberFormatException e)
+                {
+                    usage = true;
+                }
+            }
+
+            if (line.hasOption('s'))
+            {
+                try
+                {
+                    sslPort = Integer.parseInt(line.getOptionValue('s'));
+                } catch (NumberFormatException e)
+                {
+                    usage = true;
+                }
+            }
+
+            if (line.hasOption('c'))
+            {
+                context = line.getOptionValue('c');
+            }
+
+        }
+
+        if (usage)
+        {
+            new HelpFormatter().printHelp(commandName, options);
+            System.exit(-1);
+        }
+
+        new JettyRunner(webapp, context, httpPort, sslPort);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95413c0c/tapestry-runner/src/main/java/org/apache/tapestry5/test/Tomcat6Runner.java
----------------------------------------------------------------------
diff --git a/tapestry-runner/src/main/java/org/apache/tapestry5/test/Tomcat6Runner.java b/tapestry-runner/src/main/java/org/apache/tapestry5/test/Tomcat6Runner.java
deleted file mode 100644
index 03a4e9b..0000000
--- a/tapestry-runner/src/main/java/org/apache/tapestry5/test/Tomcat6Runner.java
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2011, 2013 The Apache Software Foundation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package org.apache.tapestry5.test;
-
-import org.apache.catalina.Context;
-import org.apache.catalina.Engine;
-import org.apache.catalina.Host;
-import org.apache.catalina.Wrapper;
-import org.apache.catalina.connector.Connector;
-import org.apache.catalina.loader.WebappLoader;
-import org.apache.catalina.servlets.DefaultServlet;
-import org.apache.catalina.startup.Embedded;
-
-import java.io.File;
-
-/**
- * Launches an instance of Tomcat 6.
- * 
- * @since 5.3
- */
-public class Tomcat6Runner implements ServletContainerRunner
-{
-    private final String description;
-    private final int port;
-    private final int sslPort;
-    private Embedded tomcatServer;
-
-    public Tomcat6Runner(String webappFolder, String contextPath, int port, int sslPort) throws Exception
-    {
-        this.port = port;
-
-        this.sslPort = sslPort;
-
-        final String expandedPath = expand(webappFolder);
-
-        description = String.format("<Tomcat6Runner:%s:%s/%s (%s)", contextPath, port, sslPort, expandedPath);
-
-        tomcatServer = new Embedded();
-
-        // Tomcat creates a folder, try to put it in an OS agnostic tmp dir
-        String tmpDir = System.getProperty("java.io.tmpdir");
-        String fileSeparator = System.getProperty("file.separator");
-        if (!tmpDir.endsWith(fileSeparator))
-            tmpDir = tmpDir + fileSeparator;
-        tomcatServer.setCatalinaHome(tmpDir + "tomcat");
-
-        final Engine engine = tomcatServer.createEngine();
-        engine.setDefaultHost("localhost");
-
-        final Host host = tomcatServer.createHost("localhost", expandedPath);
-        engine.addChild(host);
-
-        final Context context = tomcatServer.createContext(contextPath, expandedPath);
-
-        // Without a servlet the filter will not get run.
-        final Wrapper wrapper = context.createWrapper();
-        final String name = "DefaultServlet";
-        wrapper.setName(name);
-        wrapper.setServletClass(DefaultServlet.class.getName());
-        context.addChild(wrapper);
-        context.addServletMapping("/", name);
-
-        File contextConfigFile = new File(webappFolder, "META-INF/context.xml");
-
-        if (contextConfigFile.exists())
-            context.setConfigFile(contextConfigFile.getAbsolutePath());
-
-        context.setLoader(new WebappLoader(this.getClass().getClassLoader()));
-
-        host.addChild(context);
-
-        tomcatServer.addEngine(engine);
-
-        Connector http = tomcatServer.createConnector("localhost", port, false);
-        http.setAllowTrace(true);
-        tomcatServer.addConnector(http);
-
-        // SSL support
-        final File keystoreFile = new File(TapestryRunnerConstants.MODULE_BASE_DIR, "src/test/conf/keystore");
-
-        if (keystoreFile.exists())
-        {
-            final Connector https = tomcatServer.createConnector("localhost", sslPort, true);
-            https.setProperty("keystore", keystoreFile.getPath());
-            https.setProperty("keypass", "tapestry");
-            tomcatServer.addConnector(https);
-        }
-
-        tomcatServer.start();
-    }
-
-    /**
-     * Immediately shuts down the server instance.
-     */
-    @Override
-    public void stop()
-    {
-        System.out.printf("Stopping Tomcat instance on port %d/%d\n", port, sslPort);
-
-        try
-        {
-            // Stop immediately and not gracefully.
-            tomcatServer.stop();
-        }
-        catch (Exception ex)
-        {
-            throw new RuntimeException("Error stopping Tomcat6 instance: " + ex.toString(), ex);
-        }
-
-        System.out.println("Tomcat instance has stopped.");
-    }
-
-    @Override
-    public String toString()
-    {
-        return description;
-    }
-
-    /**
-     * Needed inside Maven multi-projects to expand a path relative to the module to a complete
-     * path. If the path already is absolute and points to an existing directory, it will be used
-     * unchanged.
-     * 
-     * @param moduleLocalPath
-     * @return expanded path
-     * @see TapestryRunnerConstants#MODULE_BASE_DIR
-     */
-    protected String expand(String moduleLocalPath)
-    {
-        File path = new File(moduleLocalPath);
-
-        // Don't expand if the path provided already exists.
-        if (path.isAbsolute() && path.isDirectory())
-            return moduleLocalPath;
-
-        return new File(TapestryRunnerConstants.MODULE_BASE_DIR, moduleLocalPath).getPath();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95413c0c/tapestry-runner/src/main/java/org/apache/tapestry5/test/TomcatRunner.java
----------------------------------------------------------------------
diff --git a/tapestry-runner/src/main/java/org/apache/tapestry5/test/TomcatRunner.java b/tapestry-runner/src/main/java/org/apache/tapestry5/test/TomcatRunner.java
new file mode 100644
index 0000000..f382330
--- /dev/null
+++ b/tapestry-runner/src/main/java/org/apache/tapestry5/test/TomcatRunner.java
@@ -0,0 +1,120 @@
+// Copyright 2011, 2013 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.test;
+
+import org.apache.catalina.connector.Connector;
+import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.startup.Tomcat;
+
+import java.io.File;
+
+/**
+ * Launches an instance of Tomcat.
+ *
+ * @since 5.3
+ */
+public class TomcatRunner implements ServletContainerRunner
+{
+    private final String description;
+    private final int port;
+    private final int sslPort;
+    private Tomcat tomcatServer;
+
+    public TomcatRunner(String webappFolder, String contextPath, int port, int sslPort) throws Exception
+    {
+        this.port = port;
+
+        this.sslPort = sslPort;
+
+        final String expandedPath = expand(webappFolder);
+
+        description = String.format("<TomcatRunner:%s:%s/%s (%s)", contextPath, port, sslPort, expandedPath);
+
+        tomcatServer = new Tomcat();
+
+        // Tomcat creates a folder, try to put it in an OS agnostic tmp dir
+        String tmpDir = System.getProperty("java.io.tmpdir");
+        String fileSeparator = System.getProperty("file.separator");
+        if (!tmpDir.endsWith(fileSeparator))
+            tmpDir = tmpDir + fileSeparator;
+        tomcatServer.setBaseDir(tmpDir + "tomcat");
+
+        tomcatServer.addWebapp("/", expandedPath);
+
+        tomcatServer.getConnector().setAllowTrace(true);
+
+        // SSL support
+        final File keystoreFile = new File(TapestryRunnerConstants.MODULE_BASE_DIR, "src/test/conf/keystore");
+
+        if (keystoreFile.exists())
+        {
+            final Connector https = new Connector();
+            https.setPort(sslPort);
+            https.setProperty("keystore", keystoreFile.getPath());
+            https.setProperty("keypass", "tapestry");
+            tomcatServer.getService().addConnector(https);
+        }
+
+        tomcatServer.start();
+    }
+
+    /**
+     * Immediately shuts down the server instance.
+     */
+    @Override
+    public void stop()
+    {
+        System.out.printf("Stopping Tomcat instance on port %d/%d\n", port, sslPort);
+
+        try
+        {
+            // Stop immediately and not gracefully.
+            tomcatServer.stop();
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException("Error stopping Tomcat instance: " + ex.toString(), ex);
+        }
+
+        System.out.println("Tomcat instance has stopped.");
+    }
+
+    @Override
+    public String toString()
+    {
+        return description;
+    }
+
+    /**
+     * Needed inside Maven multi-projects to expand a path relative to the module to a complete
+     * path. If the path already is absolute and points to an existing directory, it will be used
+     * unchanged.
+     *
+     * @param moduleLocalPath
+     * @return expanded path
+     * @see TapestryRunnerConstants#MODULE_BASE_DIR
+     */
+    protected String expand(String moduleLocalPath)
+    {
+        File path = new File(moduleLocalPath);
+
+        // Don't expand if the path provided already exists.
+        if (path.isAbsolute() && path.isDirectory())
+            return moduleLocalPath;
+
+        return new File(TapestryRunnerConstants.MODULE_BASE_DIR, moduleLocalPath).getPath();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95413c0c/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java
----------------------------------------------------------------------
diff --git a/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java b/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java
index 5b04def..55a9602 100644
--- a/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java
+++ b/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java
@@ -345,12 +345,12 @@ public abstract class SeleniumTestCase extends Assert implements Selenium
     {
         if (TOMCAT_6.equals(container))
         {
-            return new Tomcat6Runner(webAppFolder, contextPath, port, sslPort);
+            return new TomcatRunner(webAppFolder, contextPath, port, sslPort);
         }
 
         if (JETTY_7.equals(container))
         {
-            return new Jetty7Runner(webAppFolder, contextPath, port, sslPort);
+            return new JettyRunner(webAppFolder, contextPath, port, sslPort);
         }
 
         throw new RuntimeException("Unknown servlet container: " + container);

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95413c0c/tapestry-upload/src/test/java/org/apache/tapestry5/upload/RunJettyUpload.java
----------------------------------------------------------------------
diff --git a/tapestry-upload/src/test/java/org/apache/tapestry5/upload/RunJettyUpload.java b/tapestry-upload/src/test/java/org/apache/tapestry5/upload/RunJettyUpload.java
index 61811cb..12307a6 100644
--- a/tapestry-upload/src/test/java/org/apache/tapestry5/upload/RunJettyUpload.java
+++ b/tapestry-upload/src/test/java/org/apache/tapestry5/upload/RunJettyUpload.java
@@ -14,7 +14,7 @@
 
 package org.apache.tapestry5.upload;
 
-import org.apache.tapestry5.test.Jetty7Runner;
+import org.apache.tapestry5.test.JettyRunner;
 
 import java.io.File;
 
@@ -26,6 +26,6 @@ public class RunJettyUpload
 
         new File(workingDir, "target/tmp").mkdirs();
 
-        new Jetty7Runner("src/test/webapp", "/", 8080, 9999).start();
+        new JettyRunner("src/test/webapp", "/", 8080, 9999).start();
     }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95413c0c/tapestry-webresources/src/test/groovy/t5/webresources/tests/CssCompressorSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-webresources/src/test/groovy/t5/webresources/tests/CssCompressorSpec.groovy b/tapestry-webresources/src/test/groovy/t5/webresources/tests/CssCompressorSpec.groovy
index 55ce38d..3be1dd3 100644
--- a/tapestry-webresources/src/test/groovy/t5/webresources/tests/CssCompressorSpec.groovy
+++ b/tapestry-webresources/src/test/groovy/t5/webresources/tests/CssCompressorSpec.groovy
@@ -1,7 +1,7 @@
 package t5.webresources.tests
 
 import geb.spock.GebReportingSpec
-import org.apache.tapestry5.test.Jetty7Runner
+import org.apache.tapestry5.test.JettyRunner
 
 import com.yahoo.platform.yui.compressor.CssCompressor;
 

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95413c0c/tapestry-webresources/src/test/groovy/t5/webresources/tests/WebResourcesSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-webresources/src/test/groovy/t5/webresources/tests/WebResourcesSpec.groovy b/tapestry-webresources/src/test/groovy/t5/webresources/tests/WebResourcesSpec.groovy
index 7cefdf5..2d4b52c 100644
--- a/tapestry-webresources/src/test/groovy/t5/webresources/tests/WebResourcesSpec.groovy
+++ b/tapestry-webresources/src/test/groovy/t5/webresources/tests/WebResourcesSpec.groovy
@@ -1,7 +1,7 @@
 package t5.webresources.tests
 
 import geb.spock.GebReportingSpec
-import org.apache.tapestry5.test.Jetty7Runner
+import org.apache.tapestry5.test.JettyRunner
 import spock.lang.Shared
 
 class WebResourcesSpec extends GebReportingSpec {
@@ -10,7 +10,7 @@ class WebResourcesSpec extends GebReportingSpec {
     def runner;
 
     def setupSpec() {
-        runner = new Jetty7Runner("src/test/webapp", "/", 8080, 8081);
+        runner = new JettyRunner("src/test/webapp", "/", 8080, 8081);
 
         runner.start()
     }