You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by bd...@apache.org on 2016/10/18 18:56:49 UTC

[15/23] shiro git commit: Cleaning up jetty dependencies in tests

Cleaning up jetty dependencies in tests

Removing org.mortbay, while it would be nice to run tests against older versions, the maven plugin doesn't stop the container consistently


Project: http://git-wip-us.apache.org/repos/asf/shiro/repo
Commit: http://git-wip-us.apache.org/repos/asf/shiro/commit/e0cfce91
Tree: http://git-wip-us.apache.org/repos/asf/shiro/tree/e0cfce91
Diff: http://git-wip-us.apache.org/repos/asf/shiro/diff/e0cfce91

Branch: refs/heads/master
Commit: e0cfce915658176cb864c935320840174a321264
Parents: b2f5db9
Author: Brian Demers <bd...@apache.org>
Authored: Mon Oct 10 14:50:20 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Tue Oct 18 13:38:06 2016 -0400

----------------------------------------------------------------------
 pom.xml                                         |   5 +-
 samples/guice/pom.xml                           |  89 +++++------
 .../samples/guice/AbstractContainerIT.java      | 142 ++++++++++++++++++
 .../samples/guice/AbstractContainerTest.java    |  89 -----------
 .../samples/guice/ContainerIntegrationIT.java   |  79 ++++++++++
 .../samples/guice/ContainerIntegrationTest.java |  79 ----------
 samples/servlet-plugin/pom.xml                  |   5 -
 samples/web/pom.xml                             | 150 ++++++-------------
 .../apache/shiro/test/AbstractContainerIT.java  | 145 ++++++++++++++++++
 .../shiro/test/ContainerIntegrationIT.java      |   7 +-
 10 files changed, 458 insertions(+), 332 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/e0cfce91/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index ac78c2b..8674575 100644
--- a/pom.xml
+++ b/pom.xml
@@ -84,8 +84,8 @@
         <!-- Don't change this version without also changing the shiro-hazelcast and shiro-features OSGi metadata: -->
         <hazelcast.version>2.4.1</hazelcast.version>
         <hsqldb.version>1.8.0.7</hsqldb.version>
-        <jdk.version>1.5</jdk.version>
-        <jetty.version>6.1.26</jetty.version>
+        <jdk.version>1.6</jdk.version>
+        <jetty.version>9.3.0.M1</jetty.version>
         <openid4j.version>0.9.5</openid4j.version>
         <!-- Don't change this version without also changing the shiro-quartz and shiro-features
              modules' OSGi metadata: -->
@@ -560,6 +560,7 @@
             <groupId>org.hamcrest</groupId>
             <artifactId>java-hamcrest</artifactId>
             <version>2.0.0.0</version>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.easymock</groupId>

http://git-wip-us.apache.org/repos/asf/shiro/blob/e0cfce91/samples/guice/pom.xml
----------------------------------------------------------------------
diff --git a/samples/guice/pom.xml b/samples/guice/pom.xml
index c6ee28a..0727392 100644
--- a/samples/guice/pom.xml
+++ b/samples/guice/pom.xml
@@ -40,27 +40,25 @@
 	                <forkMode>never</forkMode>
 	            </configuration>
 	        </plugin>
-	        <plugin>
-	            <groupId>org.mortbay.jetty</groupId>
-	            <artifactId>maven-jetty-plugin</artifactId>
-	            <version>${jetty.version}</version>
-	            <configuration>
-	                <contextPath>/</contextPath>
-	                <connectors>
-	                    <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
-	                        <port>9080</port>
-	                        <maxIdleTime>60000</maxIdleTime>
-	                    </connector>
-	                </connectors>
-	                <requestLog implementation="org.mortbay.jetty.NCSARequestLog">
-	                    <filename>./target/yyyy_mm_dd.request.log</filename>
-	                    <retainDays>90</retainDays>
-	                    <append>true</append>
-	                    <extended>false</extended>
-	                    <logTimeZone>GMT</logTimeZone>
-	                </requestLog>
-	            </configuration>
-	        </plugin>
+			<plugin>
+				<groupId>org.eclipse.jetty</groupId>
+				<artifactId>jetty-maven-plugin</artifactId>
+				<version>${jetty.version}</version>
+				<configuration>
+					<contextPath>/</contextPath>
+					<httpConnector>
+						<port>9080</port>
+						<idleTimeout>60000</idleTimeout>
+					</httpConnector>
+					<requestLog implementation="org.eclipse.jetty.server.NCSARequestLog">
+						<filename>./target/yyyy_mm_dd.request.log</filename>
+						<retainDays>90</retainDays>
+						<append>true</append>
+						<extended>false</extended>
+						<logTimeZone>GMT</logTimeZone>
+					</requestLog>
+				</configuration>
+			</plugin>
 	    </plugins>
 	</build>
 
@@ -68,6 +66,7 @@
 	    <dependency>
 	        <groupId>javax.servlet</groupId>
 	        <artifactId>jstl</artifactId>
+			<scope>compile</scope>
 	    </dependency>
 	    <dependency>
 	        <groupId>javax.servlet</groupId>
@@ -85,12 +84,6 @@
 	        <scope>runtime</scope>
 	    </dependency>
 	    <dependency>
-	        <groupId>net.sourceforge.htmlunit</groupId>
-	        <artifactId>htmlunit</artifactId>
-	        <version>2.6</version>
-	        <scope>test</scope>
-	    </dependency>
-	    <dependency>
 	        <groupId>org.apache.shiro</groupId>
 	        <artifactId>shiro-core</artifactId>
 	    </dependency>
@@ -107,26 +100,36 @@
 			<artifactId>guice-servlet</artifactId>
 		</dependency>
 	    <dependency>
-	        <groupId>org.mortbay.jetty</groupId>
-	        <artifactId>jetty</artifactId>
-	        <version>${jetty.version}</version>
-	        <scope>test</scope>
-	    </dependency>
-	    <dependency>
-	        <groupId>org.mortbay.jetty</groupId>
-	        <artifactId>jsp-2.1-jetty</artifactId>
-	        <version>${jetty.version}</version>
-	        <scope>test</scope>
-	    </dependency>
-	    <dependency>
-	        <groupId>taglibs</groupId>
-	        <artifactId>standard</artifactId>
-	    </dependency>
-	    <dependency>
 	        <groupId>org.slf4j</groupId>
 	        <artifactId>jcl-over-slf4j</artifactId>
 	        <scope>runtime</scope>
 	    </dependency>
+
+        <dependency>
+            <groupId>net.sourceforge.htmlunit</groupId>
+            <artifactId>htmlunit</artifactId>
+            <version>2.6</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>apache-jsp</artifactId>
+            <version>${jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>apache-jstl</artifactId>
+            <version>${jetty.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.github.mjeanroy</groupId>
+            <artifactId>junit-servers-jetty</artifactId>
+            <version>0.4.2</version>
+            <scope>test</scope>
+        </dependency>
 	</dependencies>
 
 </project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/e0cfce91/samples/guice/src/test/java/org/apache/shiro/samples/guice/AbstractContainerIT.java
----------------------------------------------------------------------
diff --git a/samples/guice/src/test/java/org/apache/shiro/samples/guice/AbstractContainerIT.java b/samples/guice/src/test/java/org/apache/shiro/samples/guice/AbstractContainerIT.java
new file mode 100644
index 0000000..dcd47e1
--- /dev/null
+++ b/samples/guice/src/test/java/org/apache/shiro/samples/guice/AbstractContainerIT.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.shiro.samples.guice;
+
+import com.gargoylesoftware.htmlunit.WebClient;
+import com.github.mjeanroy.junit.servers.jetty.EmbeddedJetty;
+import com.github.mjeanroy.junit.servers.jetty.EmbeddedJettyConfiguration;
+import org.eclipse.jetty.annotations.AnnotationConfiguration;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.resource.FileResource;
+import org.eclipse.jetty.webapp.Configuration;
+import org.eclipse.jetty.webapp.FragmentConfiguration;
+import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
+import org.eclipse.jetty.webapp.MetaInfConfiguration;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.webapp.WebInfConfiguration;
+import org.eclipse.jetty.webapp.WebXmlConfiguration;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+import static com.github.mjeanroy.junit.servers.commons.Strings.isNotBlank;
+import static org.eclipse.jetty.util.resource.Resource.newResource;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public abstract class AbstractContainerIT {
+
+    protected static EmbeddedJetty jetty;
+
+    protected final WebClient webClient = new WebClient();
+
+    @BeforeClass
+    public static void startContainer() throws Exception {
+
+        EmbeddedJettyConfiguration config = EmbeddedJettyConfiguration.builder()
+                .withWebapp(getWarDir())
+                .build();
+
+        jetty = new EmbeddedJetty(config) {
+
+            /**
+             * Overriding with contents of this pull request, to make fragment scanning work.
+             * https://github.com/mjeanroy/junit-servers/pull/3
+             */
+            protected WebAppContext createdWebAppContext() throws Exception {
+                final String path = configuration.getPath();
+                final String webapp = configuration.getWebapp();
+                final String classpath = configuration.getClasspath();
+
+                WebAppContext ctx = new WebAppContext();
+                ctx.setClassLoader(Thread.currentThread().getContextClassLoader());
+                ctx.setContextPath(path);
+
+                // Useful for WebXmlConfiguration
+                ctx.setBaseResource(newResource(webapp));
+
+                ctx.setConfigurations(new Configuration[]{
+                        new WebInfConfiguration(),
+                        new WebXmlConfiguration(),
+                        new AnnotationConfiguration(),
+                        new JettyWebXmlConfiguration(),
+                        new MetaInfConfiguration(),
+                        new FragmentConfiguration(),
+                });
+
+                if (isNotBlank(classpath)) {
+                    // Fix to scan Spring WebApplicationInitializer
+                    // This will add compiled classes to jetty classpath
+                    // See: http://stackoverflow.com/questions/13222071/spring-3-1-webapplicationinitializer-embedded-jetty-8-annotationconfiguration
+                    // And more precisely: http://stackoverflow.com/a/18449506/1215828
+                    File classes = new File(classpath);
+                    FileResource containerResources = new FileResource(classes.toURI());
+                    ctx.getMetaData().addContainerResource(containerResources);
+                }
+
+                Server server = getDelegate();
+
+                ctx.setParentLoaderPriority(true);
+                ctx.setWar(webapp);
+                ctx.setServer(server);
+
+                // Add server context
+                server.setHandler(ctx);
+
+                return ctx;
+            }
+        };
+
+        jetty.start();
+
+        assertTrue(jetty.isStarted());
+    }
+
+    protected static String getBaseUri() {
+        return "http://localhost:" + jetty.getPort() + "/";
+    }
+
+    protected static String getWarDir() {
+        File[] warFiles = new File("target").listFiles(new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                return name.endsWith(".war");
+            }
+        });
+
+        assertEquals("Expected only one war file in target directory, run 'mvn clean' and try again", 1, warFiles.length);
+
+        return warFiles[0].getAbsolutePath().replaceFirst("\\.war$", "");
+    }
+
+    @Before
+    public void beforeTest() {
+        webClient.setThrowExceptionOnFailingStatusCode(true);
+    }
+
+    @AfterClass
+    public static void stopContainer() {
+        if (jetty != null) {
+            jetty.stop();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/e0cfce91/samples/guice/src/test/java/org/apache/shiro/samples/guice/AbstractContainerTest.java
----------------------------------------------------------------------
diff --git a/samples/guice/src/test/java/org/apache/shiro/samples/guice/AbstractContainerTest.java b/samples/guice/src/test/java/org/apache/shiro/samples/guice/AbstractContainerTest.java
deleted file mode 100644
index 0806fcc..0000000
--- a/samples/guice/src/test/java/org/apache/shiro/samples/guice/AbstractContainerTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.shiro.samples.guice;
-
-import com.gargoylesoftware.htmlunit.WebClient;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.mortbay.jetty.Connector;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.nio.SelectChannelConnector;
-import org.mortbay.jetty.webapp.WebAppContext;
-
-import java.net.BindException;
-
-import static org.junit.Assert.assertTrue;
-
-public abstract class AbstractContainerTest {
-    public static final int MAX_PORT = 9200;
-
-    protected static PauseableServer server;
-
-    private static int port = 9180;
-
-    protected final WebClient webClient = new WebClient();
-
-    @BeforeClass
-    public static void startContainer() throws Exception {
-        while (server == null && port < MAX_PORT) {
-            try {
-                server = createAndStartServer(port);
-            } catch (BindException e) {
-                System.err.printf("Unable to listen on port %d.  Trying next port.", port);
-                port++;
-            }
-        }
-        assertTrue(server.isStarted());
-    }
-
-    private static PauseableServer createAndStartServer(final int port) throws Exception {
-        PauseableServer server = new PauseableServer();
-        Connector connector = new SelectChannelConnector();
-        connector.setPort(port);
-        server.setConnectors(new Connector[]{connector});
-        server.setHandler(new WebAppContext("src/main/webapp", "/"));
-        server.start();
-        return server;
-    }
-
-    protected static String getBaseUri() {
-        return "http://localhost:" + port + "/";
-    }
-
-    @Before
-    public void beforeTest() {
-        webClient.setThrowExceptionOnFailingStatusCode(true);
-    }
-
-    public void pauseServer(boolean paused) {
-        if (server != null) server.pause(paused);
-    }
-
-    public static class PauseableServer extends Server {
-        public synchronized void pause(boolean paused) {
-            try {
-                if (paused) for (Connector connector : getConnectors())
-                    connector.stop();
-                else for (Connector connector : getConnectors())
-                    connector.start();
-            } catch (Exception e) {
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/shiro/blob/e0cfce91/samples/guice/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationIT.java
----------------------------------------------------------------------
diff --git a/samples/guice/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationIT.java b/samples/guice/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationIT.java
new file mode 100644
index 0000000..4ebc6c7
--- /dev/null
+++ b/samples/guice/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationIT.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.shiro.samples.guice;
+
+import com.gargoylesoftware.htmlunit.ElementNotFoundException;
+import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
+import com.gargoylesoftware.htmlunit.WebAssert;
+import com.gargoylesoftware.htmlunit.html.HtmlCheckBoxInput;
+import com.gargoylesoftware.htmlunit.html.HtmlForm;
+import com.gargoylesoftware.htmlunit.html.HtmlInput;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+public class ContainerIntegrationIT extends AbstractContainerIT {
+
+    @Before
+    public void logOut() throws IOException {
+        // Make sure we are logged out
+        final HtmlPage homePage = webClient.getPage(getBaseUri());
+        try {
+            homePage.getAnchorByHref("/logout").click();
+        }
+        catch (ElementNotFoundException e) {
+            //Ignore
+        }
+    }
+
+    @Test
+    public void logIn() throws FailingHttpStatusCodeException, MalformedURLException, IOException, InterruptedException {
+
+        HtmlPage page = webClient.getPage(getBaseUri() + "login.jsp");
+        HtmlForm form = page.getFormByName("loginform");
+        form.<HtmlInput>getInputByName("username").setValueAttribute("root");
+        form.<HtmlInput>getInputByName("password").setValueAttribute("secret");
+        page = form.<HtmlInput>getInputByName("submit").click();
+        // This'll throw an expection if not logged in
+        page.getAnchorByHref("/logout");
+    }
+
+    @Test
+    public void logInAndRememberMe() throws Exception {
+        HtmlPage page = webClient.getPage(getBaseUri() + "login.jsp");
+        HtmlForm form = page.getFormByName("loginform");
+        form.<HtmlInput>getInputByName("username").setValueAttribute("root");
+        form.<HtmlInput>getInputByName("password").setValueAttribute("secret");
+        HtmlCheckBoxInput checkbox = form.getInputByName("rememberMe");
+        checkbox.setChecked(true);
+        page = form.<HtmlInput>getInputByName("submit").click();
+        jetty.stop();
+        jetty.start();
+        page = webClient.getPage(getBaseUri());
+        // page.getAnchorByHref("/logout");
+        WebAssert.assertLinkPresentWithText(page, "Log out");
+        page = page.getAnchorByHref("/account").click();
+        // login page should be shown again - user remembered but not authenticated
+        WebAssert.assertFormPresent(page, "loginform");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/e0cfce91/samples/guice/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/samples/guice/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationTest.java b/samples/guice/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationTest.java
deleted file mode 100644
index 2694b3a..0000000
--- a/samples/guice/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.shiro.samples.guice;
-
-import com.gargoylesoftware.htmlunit.ElementNotFoundException;
-import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
-import com.gargoylesoftware.htmlunit.WebAssert;
-import com.gargoylesoftware.htmlunit.html.HtmlCheckBoxInput;
-import com.gargoylesoftware.htmlunit.html.HtmlForm;
-import com.gargoylesoftware.htmlunit.html.HtmlInput;
-import com.gargoylesoftware.htmlunit.html.HtmlPage;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-
-public class ContainerIntegrationTest extends AbstractContainerTest {
-
-    @Before
-    public void logOut() throws IOException {
-        // Make sure we are logged out
-        final HtmlPage homePage = webClient.getPage(getBaseUri());
-        try {
-            homePage.getAnchorByHref("/logout").click();
-        }
-        catch (ElementNotFoundException e) {
-            //Ignore
-        }
-    }
-
-    @Test
-    public void logIn() throws FailingHttpStatusCodeException, MalformedURLException, IOException, InterruptedException {
-
-        HtmlPage page = webClient.getPage(getBaseUri() + "login.jsp");
-        HtmlForm form = page.getFormByName("loginform");
-        form.<HtmlInput>getInputByName("username").setValueAttribute("root");
-        form.<HtmlInput>getInputByName("password").setValueAttribute("secret");
-        page = form.<HtmlInput>getInputByName("submit").click();
-        // This'll throw an expection if not logged in
-        page.getAnchorByHref("/logout");
-    }
-
-    @Test
-    public void logInAndRememberMe() throws Exception {
-        HtmlPage page = webClient.getPage(getBaseUri() + "login.jsp");
-        HtmlForm form = page.getFormByName("loginform");
-        form.<HtmlInput>getInputByName("username").setValueAttribute("root");
-        form.<HtmlInput>getInputByName("password").setValueAttribute("secret");
-        HtmlCheckBoxInput checkbox = form.getInputByName("rememberMe");
-        checkbox.setChecked(true);
-        page = form.<HtmlInput>getInputByName("submit").click();
-        server.stop();
-        server.start();
-        page = webClient.getPage(getBaseUri());
-        // page.getAnchorByHref("/logout");
-        WebAssert.assertLinkPresentWithText(page, "Log out");
-        page = page.getAnchorByHref("/account").click();
-        // login page should be shown again - user remembered but not authenticated
-        WebAssert.assertFormPresent(page, "loginform");
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/shiro/blob/e0cfce91/samples/servlet-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/samples/servlet-plugin/pom.xml b/samples/servlet-plugin/pom.xml
index b969768..75c7cb6 100644
--- a/samples/servlet-plugin/pom.xml
+++ b/samples/servlet-plugin/pom.xml
@@ -31,10 +31,6 @@
     <name>Apache Shiro :: Samples :: Servlet Plugin</name>
     <packaging>war</packaging>
 
-    <properties>
-        <jetty.version>9.3.0.M1</jetty.version>
-    </properties>
-
     <build>
         <plugins>
             <plugin>
@@ -74,7 +70,6 @@
         <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>jstl</artifactId>
-            <version>1.2</version>
             <scope>runtime</scope>
         </dependency>
         <dependency>

http://git-wip-us.apache.org/repos/asf/shiro/blob/e0cfce91/samples/web/pom.xml
----------------------------------------------------------------------
diff --git a/samples/web/pom.xml b/samples/web/pom.xml
index 4629ec3..d10a98b 100644
--- a/samples/web/pom.xml
+++ b/samples/web/pom.xml
@@ -38,40 +38,6 @@
     </properties>
 
     <build>
-        <pluginManagement>
-            <plugins>
-                <plugin>
-                    <groupId>org.mortbay.jetty</groupId>
-                    <artifactId>maven-jetty-plugin</artifactId>
-                    <version>${jetty.version}</version>
-                    <configuration>
-                        <contextPath>/</contextPath>
-                        <stopPort>8005</stopPort>
-                        <stopKey>STOP</stopKey>
-                        <connectors>
-                            <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
-                                <port>${jetty.port}</port>
-                                <maxIdleTime>60000</maxIdleTime>
-                            </connector>
-                        </connectors>
-                        <requestLog implementation="org.mortbay.jetty.NCSARequestLog">
-                            <filename>./target/yyyy_mm_dd.request.log</filename>
-                            <retainDays>90</retainDays>
-                            <append>true</append>
-                            <extended>false</extended>
-                            <logTimeZone>GMT</logTimeZone>
-                        </requestLog>
-                    </configuration>
-                    <dependencies>
-                        <dependency>
-                            <groupId>org.mortbay.jetty</groupId>
-                            <artifactId>jsp-2.1-jetty</artifactId>
-                            <version>${jetty.version}</version>
-                        </dependency>
-                    </dependencies>
-                </plugin>
-            </plugins>
-        </pluginManagement>
         <plugins>
             <plugin>
                 <artifactId>maven-surefire-plugin</artifactId>
@@ -80,8 +46,23 @@
                 </configuration>
             </plugin>
             <plugin>
-                <groupId>org.mortbay.jetty</groupId>
-                <artifactId>maven-jetty-plugin</artifactId>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.version}</version>
+                <configuration>
+                    <contextPath>/</contextPath>
+                    <httpConnector>
+                        <port>9080</port>
+                        <idleTimeout>60000</idleTimeout>
+                    </httpConnector>
+                    <requestLog implementation="org.eclipse.jetty.server.NCSARequestLog">
+                        <filename>./target/yyyy_mm_dd.request.log</filename>
+                        <retainDays>90</retainDays>
+                        <append>true</append>
+                        <extended>false</extended>
+                        <logTimeZone>GMT</logTimeZone>
+                    </requestLog>
+                </configuration>
             </plugin>
         </plugins>
     </build>
@@ -122,88 +103,41 @@
             <artifactId>shiro-web</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.mortbay.jetty</groupId>
-            <artifactId>jetty</artifactId>
-            <version>${jetty.version}</version>
+            <groupId>taglibs</groupId>
+            <artifactId>standard</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>net.sourceforge.htmlunit</groupId>
+            <artifactId>htmlunit</artifactId>
+            <version>2.6</version>
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.mortbay.jetty</groupId>
-            <artifactId>jsp-2.1-jetty</artifactId>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>apache-jsp</artifactId>
             <version>${jetty.version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>taglibs</groupId>
-            <artifactId>standard</artifactId>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>apache-jstl</artifactId>
+            <version>${jetty.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>jcl-over-slf4j</artifactId>
-            <scope>runtime</scope>
+            <groupId>com.github.mjeanroy</groupId>
+            <artifactId>junit-servers-jetty</artifactId>
+            <version>0.4.2</version>
+            <scope>test</scope>
         </dependency>
-    </dependencies>
 
-    <profiles>
-        <profile>
-            <id>run-ITs</id>
-            <activation>
-                <activeByDefault>true</activeByDefault>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.mortbay.jetty</groupId>
-                        <artifactId>maven-jetty-plugin</artifactId>
-                        <executions>
-                            <!-- start jetty before ITs -->
-                            <execution>
-                                <id>start-jetty</id>
-                                <phase>pre-integration-test</phase>
-                                <goals>
-                                    <goal>run</goal>
-                                </goals>
-                                <configuration>
-                                    <scanIntervalSeconds>0</scanIntervalSeconds>
-                                    <daemon>true</daemon>
-                                </configuration>
-                            </execution>
-                            <!-- Stop jetty after ITs -->
-                            <execution>
-                                <id>stop-jetty</id>
-                                <phase>post-integration-test</phase>
-                                <goals>
-                                    <goal>stop</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-antrun-plugin</artifactId>
-                        <version>1.8</version>
-                        <executions>
-                            <execution>
-                                <id>sleep-for-a-while</id>
-                                <phase>post-integration-test</phase>
-                                <configuration>
-                                    <target>
-                                        <!-- This is dirty looking, but this old version needs it or the shutdown
-                                        hook will print exceptions, the build will still pass, so it is mostly cosmetic.
-                                        -->
-                                        <echo>Waiting for Jetty to stop</echo>
-                                        <sleep seconds="${jetty.postIT.sleep}" />
-                                    </target>
-                                </configuration>
-                                <goals>
-                                    <goal>run</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
+    </dependencies>
 
 </project>

http://git-wip-us.apache.org/repos/asf/shiro/blob/e0cfce91/samples/web/src/test/java/org/apache/shiro/test/AbstractContainerIT.java
----------------------------------------------------------------------
diff --git a/samples/web/src/test/java/org/apache/shiro/test/AbstractContainerIT.java b/samples/web/src/test/java/org/apache/shiro/test/AbstractContainerIT.java
new file mode 100644
index 0000000..4e3e598
--- /dev/null
+++ b/samples/web/src/test/java/org/apache/shiro/test/AbstractContainerIT.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.shiro.test;
+
+import com.gargoylesoftware.htmlunit.WebClient;
+import com.github.mjeanroy.junit.servers.jetty.EmbeddedJetty;
+import com.github.mjeanroy.junit.servers.jetty.EmbeddedJettyConfiguration;
+import org.eclipse.jetty.annotations.AnnotationConfiguration;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.resource.FileResource;
+import org.eclipse.jetty.webapp.Configuration;
+import org.eclipse.jetty.webapp.FragmentConfiguration;
+import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
+import org.eclipse.jetty.webapp.MetaInfConfiguration;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.webapp.WebInfConfiguration;
+import org.eclipse.jetty.webapp.WebXmlConfiguration;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+import static com.github.mjeanroy.junit.servers.commons.Strings.isNotBlank;
+import static org.eclipse.jetty.util.resource.Resource.newResource;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public abstract class AbstractContainerIT {
+
+    private static EmbeddedJetty jetty;
+
+    private static int port = 0;
+
+    protected final WebClient webClient = new WebClient();
+
+    @BeforeClass
+    public static void startContainer() throws Exception {
+
+        EmbeddedJettyConfiguration config = EmbeddedJettyConfiguration.builder()
+                .withWebapp(getWarDir())
+                .build();
+
+        jetty = new EmbeddedJetty(config) {
+
+            /**
+             * Overriding with contents of this pull request, to make fragment scanning work.
+             * https://github.com/mjeanroy/junit-servers/pull/3
+             */
+            protected WebAppContext createdWebAppContext() throws Exception {
+                final String path = configuration.getPath();
+                final String webapp = configuration.getWebapp();
+                final String classpath = configuration.getClasspath();
+
+                WebAppContext ctx = new WebAppContext();
+                ctx.setClassLoader(Thread.currentThread().getContextClassLoader());
+                ctx.setContextPath(path);
+
+                // Useful for WebXmlConfiguration
+                ctx.setBaseResource(newResource(webapp));
+
+                ctx.setConfigurations(new Configuration[]{
+                        new WebInfConfiguration(),
+                        new WebXmlConfiguration(),
+                        new AnnotationConfiguration(),
+                        new JettyWebXmlConfiguration(),
+                        new MetaInfConfiguration(),
+                        new FragmentConfiguration(),
+                });
+
+                if (isNotBlank(classpath)) {
+                    // Fix to scan Spring WebApplicationInitializer
+                    // This will add compiled classes to jetty classpath
+                    // See: http://stackoverflow.com/questions/13222071/spring-3-1-webapplicationinitializer-embedded-jetty-8-annotationconfiguration
+                    // And more precisely: http://stackoverflow.com/a/18449506/1215828
+                    File classes = new File(classpath);
+                    FileResource containerResources = new FileResource(classes.toURI());
+                    ctx.getMetaData().addContainerResource(containerResources);
+                }
+
+                Server server = getDelegate();
+
+                ctx.setParentLoaderPriority(true);
+                ctx.setWar(webapp);
+                ctx.setServer(server);
+
+                // Add server context
+                server.setHandler(ctx);
+
+                return ctx;
+            }
+        };
+
+        jetty.start();
+        port = jetty.getPort();
+
+        assertTrue(jetty.isStarted());
+    }
+
+    protected static String getBaseUri() {
+        return "http://localhost:" + port + "/";
+    }
+
+    protected static String getWarDir() {
+        File[] warFiles = new File("target").listFiles(new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                return name.endsWith(".war");
+            }
+        });
+
+        assertEquals("Expected only one war file in target directory, run 'mvn clean' and try again", 1, warFiles.length);
+
+        return warFiles[0].getAbsolutePath().replaceFirst("\\.war$", "");
+    }
+
+    @Before
+    public void beforeTest() {
+        webClient.setThrowExceptionOnFailingStatusCode(true);
+    }
+
+    @AfterClass
+    public static void stopContainer() {
+        if (jetty != null) {
+            jetty.stop();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/e0cfce91/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java
----------------------------------------------------------------------
diff --git a/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java b/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java
index 0d077e9..52709ee 100644
--- a/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java
+++ b/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java
@@ -30,7 +30,7 @@ import org.junit.Test;
 import java.io.IOException;
 import java.net.MalformedURLException;
 
-public class ContainerIntegrationIT {
+public class ContainerIntegrationIT extends AbstractContainerIT {
 
     protected final WebClient webClient = new WebClient();
 
@@ -46,11 +46,6 @@ public class ContainerIntegrationIT {
         }
     }
 
-    protected static String getBaseUri() {
-        String port = System.getProperty("jetty.port", "9080");
-        return "http://localhost:" + port + "/";
-    }
-
     @Test
     public void logIn() throws FailingHttpStatusCodeException, MalformedURLException, IOException, InterruptedException {