();
+
+ public JettyPolicyConfigurator()
+ {
+
+ }
+
+ public void addPolicy( String policy )
+ {
+ _policies.add(policy);
+ }
+
+ public void addProperty( String name, String value )
+ {
+ _properties.put(name,value);
+ }
+
+ public void initialize()
+ {
+ System.out.println("Initializing Jetty Policy");
+
+ JettyPolicy jpolicy = new JettyPolicy( _policies, _properties );
+ Policy.setPolicy(jpolicy);
+ System.setSecurityManager(new SecurityManager());
+ }
+
+}
diff --git a/jetty-rewrite/pom.xml b/jetty-rewrite/pom.xml
index af06f3668e1..651e3226cdc 100644
--- a/jetty-rewrite/pom.xml
+++ b/jetty-rewrite/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
4.0.0
jetty-rewrite
diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml
index 26b6d607ba1..04e3856c314 100644
--- a/jetty-security/pom.xml
+++ b/jetty-security/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
4.0.0
jetty-security
diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml
index dd2dd1fb3a4..7d6c692bf82 100644
--- a/jetty-server/pom.xml
+++ b/jetty-server/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
4.0.0
jetty-server
diff --git a/jetty-servlet/pom.xml b/jetty-servlet/pom.xml
index 6280c65d32d..a9d1938e861 100644
--- a/jetty-servlet/pom.xml
+++ b/jetty-servlet/pom.xml
@@ -3,7 +3,7 @@
jetty-project
org.eclipse.jetty
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
4.0.0
jetty-servlet
diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml
index 56e9a8a5e91..093c2cbe2ef 100644
--- a/jetty-servlets/pom.xml
+++ b/jetty-servlets/pom.xml
@@ -3,7 +3,7 @@
jetty-project
org.eclipse.jetty
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
4.0.0
jetty-servlets
diff --git a/jetty-start/pom.xml b/jetty-start/pom.xml
index 5edab24bfc0..27b583c8551 100644
--- a/jetty-start/pom.xml
+++ b/jetty-start/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
4.0.0
jetty-start
diff --git a/jetty-util/pom.xml b/jetty-util/pom.xml
index e17138337b5..864d26de187 100644
--- a/jetty-util/pom.xml
+++ b/jetty-util/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
4.0.0
jetty-util
diff --git a/jetty-webapp-verifier/.gitignore b/jetty-webapp-verifier/.gitignore
new file mode 100644
index 00000000000..9c65b190a85
--- /dev/null
+++ b/jetty-webapp-verifier/.gitignore
@@ -0,0 +1,9 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.patch
+*.diff
+*.log
+cobertura.ser
diff --git a/jetty-webapp-verifier/pom.xml b/jetty-webapp-verifier/pom.xml
new file mode 100644
index 00000000000..93caf632458
--- /dev/null
+++ b/jetty-webapp-verifier/pom.xml
@@ -0,0 +1,111 @@
+
+ 4.0.0
+
+ org.eclipse.jetty
+ jetty-project
+ 7.0.1-SNAPSHOT
+
+ org.eclipse.jetty
+ jetty-webapp-verifier
+ Jetty :: Webapp Verifier Tool
+ jar
+
+ target/war-files
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ copy
+ generate-resources
+
+ copy
+
+
+
+
+ org.eclipse.jetty.tests
+ test-webapp-logging-java
+ ${project.version}
+ war
+ ${war.file.repo}
+ test-webapp-logging-java.war
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ package
+
+ single
+
+
+
+ config.xml
+
+
+
+
+
+
+
+
+
+ org.eclipse.jetty
+ jetty-xml
+ ${version}
+
+
+ junit
+ junit
+ test
+
+
+
+ asm
+ asm
+ 3.1
+ true
+
+
+ asm
+ asm-tree
+ 3.1
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-project-info-reports-plugin
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+
+ org.apache.maven.plugins
+ maven-jxr-plugin
+
+
+ org.codehaus.mojo
+ cobertura-maven-plugin
+
+
+
+
diff --git a/jetty-webapp-verifier/src/main/config/etc/jetty-waver-default-ruleset.xml b/jetty-webapp-verifier/src/main/config/etc/jetty-waver-default-ruleset.xml
new file mode 100644
index 00000000000..fe7e5ccfa3d
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/config/etc/jetty-waver-default-ruleset.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+ -
+
+
+ /WEB-INF/web.xml
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/AbstractArchiveScanningRule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/AbstractArchiveScanningRule.java
new file mode 100644
index 00000000000..4cbc5708098
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/AbstractArchiveScanningRule.java
@@ -0,0 +1,94 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+import java.io.File;
+import java.util.Enumeration;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * AbstractArchiveScanningRule for Rules that scan the archive contents.
+ */
+public abstract class AbstractArchiveScanningRule extends AbstractRule
+{
+ public abstract String getDescription();
+
+ public abstract String getName();
+
+ @Override
+ public void visitWebInfLibJar(String path, File archive, JarFile jar)
+ {
+ scanClassesInArchive(path,jar);
+ }
+
+ @Override
+ public void visitWebInfLibZip(String path, File archive, ZipFile zip)
+ {
+ scanClassesInArchive(path,zip);
+ }
+
+ private String asClassname(String path)
+ {
+ StringBuffer name = new StringBuffer();
+ for (char c : path.toCharArray())
+ {
+ if (c == '/')
+ {
+ name.append(".");
+ }
+ else
+ {
+ name.append(c);
+ }
+ }
+ if (name.toString().endsWith(".class"))
+ {
+ name.delete(name.length() - 6,name.length() - 1);
+ }
+ return name.toString();
+ }
+
+ private void scanClassesInArchive(String path, ZipFile zip)
+ {
+ String className;
+ Enumeration extends ZipEntry> entries = zip.entries();
+ while (entries.hasMoreElements())
+ {
+ ZipEntry entry = entries.nextElement();
+ if (entry.getName().endsWith(".class"))
+ {
+ className = asClassname(entry.getName());
+ visitArchiveClass(path + "!/" + entry.getName(),className,zip,entry);
+ }
+ else
+ {
+ visitArchiveResource(path + "!/" + entry.getName(),zip,entry);
+ }
+ }
+ }
+
+ public void visitArchiveResource(String path, ZipFile zip, ZipEntry entry)
+ {
+ /* override to do something with */
+ }
+
+ public void visitArchiveClass(String path, String className, ZipFile archive, ZipEntry archiveEntry)
+ {
+ /* override to do something with */
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/AbstractRule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/AbstractRule.java
new file mode 100644
index 00000000000..c8a52952e8b
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/AbstractRule.java
@@ -0,0 +1,215 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+import java.io.File;
+import java.util.jar.JarFile;
+import java.util.zip.ZipFile;
+
+public abstract class AbstractRule implements Rule
+{
+ private ViolationListener violationListener;
+ private File rootDir;
+
+ protected void error(String path, String detail)
+ {
+ Violation violation = new Violation(Severity.ERROR,path,detail);
+ violation.setVerifierInfo(this);
+ violationListener.reportViolation(violation);
+ }
+
+ protected void exception(String path, String detail, Throwable t)
+ {
+ Violation violation = new Violation(Severity.ERROR,path,detail,t);
+ violation.setVerifierInfo(this);
+ violationListener.reportViolation(violation);
+ }
+
+ protected String getWebappRelativePath(File dir)
+ {
+ if (rootDir == null)
+ {
+ throw new RuntimeException("rootDir is not initialized, can't get relative path. "
+ + "Did you overide .visitWebappStart() and not call super.visitWebappStart()?");
+ }
+ return rootDir.toURI().relativize(dir.toURI()).toASCIIString();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jetty.webapp.verifier.Rule#setViolationListener(ViolationListener)
+ */
+ public void setViolationListener(ViolationListener listener)
+ {
+ this.violationListener = listener;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jetty.webapp.verifier.Rule#initialize()
+ */
+ public void initialize() throws Throwable
+ {
+ /* override to implement */
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jetty.webapp.verifier.Rule#visitDirectoryEnd(java.lang.String, java.io.File)
+ */
+ public void visitDirectoryEnd(String path, File dir)
+ {
+ /* override to implement */
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jetty.webapp.verifier.Rule#visitDirectoryStart(java.lang.String, java.io.File)
+ */
+ public void visitDirectoryStart(String path, File dir)
+ {
+ /* override to implement */
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jetty.webapp.verifier.Rule#visitFile(java.lang.String, java.io.File, java.io.File)
+ */
+ public void visitFile(String path, File dir, File file)
+ {
+ /* override to implement */
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jetty.webapp.verifier.Rule#visitWebappEnd(java.lang.String, java.io.File)
+ */
+ public void visitWebappEnd(String path, File dir)
+ {
+ /* override to implement */
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * NOTE: be sure to call super.{@link #visitWebappStart(String, File)} in your overriden method.
+ *
+ * @see org.eclipse.jetty.webapp.verifier.Rule#visitWebappStart(java.lang.String, java.io.File)
+ */
+ public void visitWebappStart(String path, File dir)
+ {
+ if (path.equals(ROOT_PATH))
+ {
+ rootDir = new File(path);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jetty.webapp.verifier.Rule#visitWebInfClass(java.lang.String, java.lang.String,
+ * java.io.File)
+ */
+ public void visitWebInfClass(String path, String className, File classFile)
+ {
+ /* override to implement */
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jetty.webapp.verifier.Rule#visitWebInfClassesEnd(java.lang.String, java.io.File)
+ */
+ public void visitWebInfClassesEnd(String path, File dir)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jetty.webapp.verifier.Rule#visitWebInfClassesStart(java.lang.String, java.io.File)
+ */
+ public void visitWebInfClassesStart(String path, File dir)
+ {
+ /* override to implement */
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jetty.webapp.verifier.Rule#visitWebInfClassResource(java.lang.String, java.lang.String,
+ * java.io.File)
+ */
+ public void visitWebInfClassResource(String path, String resourcePath, File resourceFile)
+ {
+ /* override to implement */
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jetty.webapp.verifier.Rule#visitWebInfLibEnd(java.lang.String, java.io.File)
+ */
+ public void visitWebInfLibEnd(String path, File dir)
+ {
+ /* override to implement */
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jetty.webapp.verifier.Rule#visitWebInfLibJar(String, File, JarFile)
+ */
+ public void visitWebInfLibJar(String path, File archive, JarFile jar)
+ {
+ /* override to implement */
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jetty.webapp.verifier.Rule#visitWebInfLibStart(java.lang.String, java.io.File)
+ */
+ public void visitWebInfLibStart(String path, File dir)
+ {
+ /* override to implement */
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jetty.webapp.verifier.Rule#visitWebInfLibZip(String, File, ZipFile)
+ */
+ public void visitWebInfLibZip(String path, File archive, ZipFile zip)
+ {
+ /* override to implement */
+ }
+
+ protected void warning(String path, String detail)
+ {
+ Violation violation = new Violation(Severity.WARNING,path,detail);
+ violation.setVerifierInfo(this);
+ violationListener.reportViolation(violation);
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/Rule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/Rule.java
new file mode 100644
index 00000000000..a21b9ad9b4b
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/Rule.java
@@ -0,0 +1,222 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+import java.io.File;
+import java.net.URLClassLoader;
+import java.util.jar.JarFile;
+import java.util.zip.ZipFile;
+
+/**
+ *
+ * Rule is the interface that the {@link WebappVerifier} uses to notify Rule implementations of events in the Iteration
+ * of a Webapp contents.
+ *
+ *
+ *
+ * The visitor pattern used here has the following order ..
+ *
+ *
+ *
+ * 1) [1] {@link #visitWebappStart(String, File)}
+ * Iterate Contents:
+ * 2) [1..n] {@link #visitDirectoryStart(String, File)}
+ * 3) [0..n] {@link #visitFile(String, File, File)}
+ * 4) [1..n] {@link #visitDirectoryEnd(String, File)}
+ * Iterate WEB-INF/classes:
+ * 5) [0..1] {@link #visitWebInfClassesStart(String, File)}
+ * 6) [0..n] {@link #visitWebInfClass(String, String, File)}
+ * 7) [0..n] {@link #visitWebInfClassResource(String, String, File)}
+ * 8) [0..1] {@link #visitWebInfClassesEnd(String, File)}
+ * Iterate WEB-INF/lib:
+ * 9) [0..1] {@link #visitWebInfLibStart(String, File)}
+ * 10) [0..n] {@link #visitWebInfLibJar(String, File, JarFile)}
+ * 11) [0..n] {@link #visitWebInfLibZip(String, File, ZipFile)}
+ * 12) [0..1] {@link #visitWebInfLibEnd(String, File)}
+ * 13) [1] {@link #visitWebappEnd(String, File)}
+ *
+ */
+public interface Rule
+{
+ public static final String ROOT_PATH = "";
+
+ /**
+ * A short name for the rule.
+ */
+ public String getName();
+
+ /**
+ * A Description of the purpose of the rule. What does it check for? Why?
+ */
+ public String getDescription();
+
+ /**
+ * Initialization logic for the rule, exceptions from initialization will be logged as a {@link Severity#ERROR}
+ * level {@link Violation} with the {@link Violation#getThrowable()} set.
+ *
+ * If you want more meaningful violation messages than default, be sure to capture your own initialization related
+ * failures and report them to the {@link ViolationListener} at a {@link Severity#ERROR} level.
+ */
+ public void initialize() throws Throwable;
+
+ /**
+ * Set the listener to report violations back to.
+ */
+ public void setViolationListener(ViolationListener listener);
+
+ /**
+ * The iteration of the webapp has begun.
+ *
+ * @param path
+ * the war relative path to this directory.
+ * @param dir
+ * the real File System directory to the webapp work directory
+ */
+ public void visitWebappStart(String path, File dir);
+
+ /**
+ * A visit of a directory has begun.
+ *
+ * @param path
+ * the war relative path to this directory.
+ * @param dir
+ * the real File System directory object for this directory.
+ */
+ public void visitDirectoryStart(String path, File dir);
+
+ /**
+ * A visit of a file.
+ *
+ * @param path
+ * the war relative path to this file.
+ * @param dir
+ * the real File System directory object for this file. This is the same directory as seen in
+ * {@link #visitDirectoryStart(String, File)} and {@link #visitDirectoryEnd(String, File)}
+ * @param file
+ * the real File System {@link File} object to this file
+ */
+ public void visitFile(String path, File dir, File file);
+
+ /**
+ * A visit of a directory has ended.
+ *
+ * @param path
+ * the war relative path to this directory.
+ * @param dir
+ * the real File System directory.
+ */
+ public void visitDirectoryEnd(String path, File dir);
+
+ /**
+ * The visit to WEB-INF/classes is starting
+ *
+ * @param path
+ * the war relative path to the WEB-INF/classes dir. (Note: Will always be "WEB-INF/classes")
+ * @param dir
+ * the real File System directory.
+ */
+ public void visitWebInfClassesStart(String path, File dir);
+
+ /**
+ * A visit of a Class found in WEB-INF/classes.
+ *
+ * @param path
+ * the war relative path to this directory.
+ * @param className
+ * the full classname of the class found. TODO: Base this off of class bytecode?
+ * @param classFile
+ * the real File System directory object for this directory.
+ */
+ public void visitWebInfClass(String path, String className, File classFile);
+
+ /**
+ * A visit of a Resource available in "WEB-INF/classes" which is not a Class (such as an XML file or a properties
+ * file)
+ *
+ * @param path
+ * the war relative path to this directory.
+ * @param resourcePath
+ * the full resourcePath to the file found. Returned in a format that is compatible to
+ * {@link URLClassLoader#findResource(String)} call.
+ * @param resourceFile
+ * the real File System directory object for this directory.
+ */
+ public void visitWebInfClassResource(String path, String resourcePath, File resourceFile);
+
+ /**
+ * The visit to WEB-INF/classes has ended
+ *
+ * @param path
+ * the war relative path to the WEB-INF/classes dir. (Note: Will always be "WEB-INF/classes")
+ * @param dir
+ * the real File System directory.
+ */
+ public void visitWebInfClassesEnd(String path, File dir);
+
+ /**
+ * The visit to WEB-INF/lib is starting.
+ *
+ * @param path
+ * the war relative path to the WEB-INF/lib dir. (Note: Will always be "WEB-INF/lib")
+ * @param dir
+ * the real File System directory.
+ */
+ public void visitWebInfLibStart(String path, File dir);
+
+ /**
+ * A visit to a JAR archive in the WEB-INF/lib directory.
+ *
+ * @param path
+ * the war relative path to the JAR archive in the WEB-INF/lib dir.
+ * @param archive
+ * the real File System file.
+ * @param jar
+ * the {@link JarFile}
+ */
+ public void visitWebInfLibJar(String path, File archive, JarFile jar);
+
+ /**
+ * A visit to an archive in the WEB-INF/lib directory has begun.
+ *
+ * @param path
+ * the war relative path to the archive in the WEB-INF/lib dir.
+ * @param archive
+ * the real File System file.
+ * @param zip
+ * the {@link ZipFile}
+ */
+ public void visitWebInfLibZip(String path, File archive, ZipFile zip);
+
+ /**
+ * The visit to WEB-INF/lib has ended.
+ *
+ * @param path
+ * the war relative path to the WEB-INF/lib dir. (Note: Will always be "WEB-INF/lib")
+ * @param dir
+ * the real File System directory.
+ */
+ public void visitWebInfLibEnd(String path, File dir);
+
+ /**
+ * The iteration of the webapp has ended.
+ *
+ * @param path
+ * the war relative path to this directory.
+ * @param dir
+ * the real File System directory to the webapp work directory
+ */
+ public void visitWebappEnd(String path, File dir);
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/RuleSet.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/RuleSet.java
new file mode 100644
index 00000000000..5dfd32e8d07
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/RuleSet.java
@@ -0,0 +1,89 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jetty.xml.XmlConfiguration;
+
+/**
+ * RuleSet holds the set of configured {@link Rule}s that the WebappVerifier will use.
+ */
+public class RuleSet
+{
+ private String name;
+ private List rules = new ArrayList();
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public List getRules()
+ {
+ return rules;
+ }
+
+ public void setRules(List rules)
+ {
+ this.rules = rules;
+ }
+
+ public void setRules(Rule[] ruleArray)
+ {
+ this.rules.clear();
+ this.rules.addAll(Arrays.asList(ruleArray));
+ }
+
+ public void addRule(Rule rule)
+ {
+ this.rules.add(rule);
+ }
+
+ public WebappVerifier createWebappVerifier(URI webappURI)
+ {
+ WebappVerifier webappVerifier = new WebappVerifier(webappURI);
+ webappVerifier.setRules(rules);
+ return webappVerifier;
+ }
+
+ public static RuleSet load(URL configuration) throws Exception
+ {
+ XmlConfiguration xml;
+ xml = new XmlConfiguration(configuration);
+ return (RuleSet)xml.configure();
+ }
+
+ public static RuleSet load(URI configuration) throws Exception
+ {
+ return load(configuration.toURL());
+ }
+
+ public static RuleSet load(File configuration) throws Exception
+ {
+ return load(configuration.toURL());
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/Severity.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/Severity.java
new file mode 100644
index 00000000000..8435c5c05b4
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/Severity.java
@@ -0,0 +1,39 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+public enum Severity
+{
+ WARNING, ERROR;
+
+ public static Severity parse(String value)
+ {
+ if (value == null)
+ {
+ return null;
+ }
+
+ for (Severity sev : Severity.values())
+ {
+ if (sev.name().equalsIgnoreCase(value))
+ {
+ return sev;
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/Violation.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/Violation.java
new file mode 100644
index 00000000000..66be3fa299f
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/Violation.java
@@ -0,0 +1,186 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+public class Violation
+{
+ private String path;
+
+ private Severity severity;
+
+ private String detail;
+
+ private Throwable throwable;
+
+ private String ruleId;
+
+ private Class extends Rule> ruleClass;
+
+ public Violation(Severity severity, String path, String detail)
+ {
+ this.severity = severity;
+ this.path = path;
+ this.detail = detail;
+ }
+
+ public Violation(Severity severity, String path, String detail, Rule verifier)
+ {
+ this.severity = severity;
+ this.path = path;
+ this.detail = detail;
+ setVerifierInfo(verifier);
+ }
+
+ public Violation(Severity severity, String path, String detail, Throwable throwable)
+ {
+ this.severity = severity;
+ this.path = path;
+ this.detail = detail;
+ this.throwable = throwable;
+ }
+
+ public void setVerifierInfo(Rule verifier)
+ {
+ this.ruleId = verifier.getName();
+ this.ruleClass = verifier.getClass();
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuffer msg = new StringBuffer();
+ msg.append("Violation[");
+ msg.append("severity=").append(severity.name());
+ msg.append(",path=").append(path);
+ msg.append(",detail=").append(detail);
+ if (ruleId != null)
+ {
+ msg.append(",verifierId=").append(ruleId);
+ }
+ if (ruleClass != null)
+ {
+ msg.append(",verifierClass=").append(ruleClass.getName());
+ }
+ if (throwable != null)
+ {
+ msg.append(",throwable=").append(throwable.getClass().getName());
+ }
+ msg.append("]");
+ return msg.toString();
+ }
+
+ public String toDelimString()
+ {
+ StringBuffer msg = new StringBuffer();
+ msg.append(severity.name());
+ msg.append("|").append(path);
+ msg.append("|").append(detail);
+ return msg.toString();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((detail == null)?0:detail.hashCode());
+ result = prime * result + ((path == null)?0:path.hashCode());
+ result = prime * result + ((severity == null)?0:severity.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ if (obj == null)
+ {
+ return false;
+ }
+ if (getClass() != obj.getClass())
+ {
+ return false;
+ }
+ Violation other = (Violation)obj;
+ if (detail == null)
+ {
+ if (other.detail != null)
+ {
+ return false;
+ }
+ }
+ else if (!detail.equals(other.detail))
+ {
+ return false;
+ }
+ if (path == null)
+ {
+ if (other.path != null)
+ {
+ return false;
+ }
+ }
+ else if (!path.equals(other.path))
+ {
+ return false;
+ }
+ if (severity == null)
+ {
+ if (other.severity != null)
+ {
+ return false;
+ }
+ }
+ else if (!severity.equals(other.severity))
+ {
+ return false;
+ }
+ return true;
+ }
+
+ public Class extends Rule> getRuleClass()
+ {
+ return ruleClass;
+ }
+
+ public String getRuleId()
+ {
+ return ruleId;
+ }
+
+ public String getDetail()
+ {
+ return detail;
+ }
+
+ public String getPath()
+ {
+ return path;
+ }
+
+ public Severity getSeverity()
+ {
+ return severity;
+ }
+
+ public Throwable getThrowable()
+ {
+ return throwable;
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/ViolationComparator.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/ViolationComparator.java
new file mode 100644
index 00000000000..24ea663f227
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/ViolationComparator.java
@@ -0,0 +1,49 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+import java.text.CollationKey;
+import java.text.Collator;
+import java.util.Comparator;
+
+public class ViolationComparator implements Comparator
+{
+ private static ViolationComparator INSTANCE = new ViolationComparator();
+
+ public static ViolationComparator getInstance()
+ {
+ return INSTANCE;
+ }
+
+ private Collator collator = Collator.getInstance();
+
+ public int compare(Violation o1, Violation o2)
+ {
+ CollationKey pathKey1 = collator.getCollationKey(o1.getPath());
+ CollationKey pathKey2 = collator.getCollationKey(o2.getPath());
+
+ int diff = pathKey1.compareTo(pathKey2);
+ if (diff != 0)
+ {
+ // different paths.
+ return diff;
+ }
+
+ CollationKey detailKey1 = collator.getCollationKey(o1.getDetail());
+ CollationKey detailKey2 = collator.getCollationKey(o2.getDetail());
+ return detailKey1.compareTo(detailKey2);
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/ViolationListener.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/ViolationListener.java
new file mode 100644
index 00000000000..e2ab668ecae
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/ViolationListener.java
@@ -0,0 +1,21 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+public interface ViolationListener
+{
+ void reportViolation(Violation violation);
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/WebappVerifier.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/WebappVerifier.java
new file mode 100644
index 00000000000..25044c18912
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/WebappVerifier.java
@@ -0,0 +1,570 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.JarFile;
+import java.util.zip.ZipFile;
+
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.resource.JarResource;
+import org.eclipse.jetty.util.resource.Resource;
+
+/**
+ * The Webapp Verifier is a component that can be configured to run and arbitrary number of {@link Rule}s that analyze
+ * the contents of a war file and report rule violations.
+ */
+public class WebappVerifier implements ViolationListener
+{
+ /**
+ *
+ * Represents the source webappURI.
+ *
+ *
+ * Can be http, file, jar, etc ...
+ *
+ *
+ * Verification does not occur directly against this URI.
+ *
+ */
+ private URI _webappURI;
+
+ /**
+ * Represents the local webapp file directory, often times points to the working (unpacked) webapp directory.
+ *
+ * NOTE: if _webappURI is a "file://" access URI, and points to a directory, then the _webappDir will point to the
+ * the same place, otherwise it will point to the webapp directory.
+ */
+ private File _webappDir;
+ private File _workdir;
+ private List _rules;
+ private Map> _violations;
+
+ /**
+ * Instantiate a WebappVerifier, against the specific webappURI, using the default workdir.
+ *
+ * @param webappURI
+ * the webappURI to verify
+ */
+ public WebappVerifier(URI webappURI)
+ {
+ this._webappURI = webappURI;
+ this._workdir = new File(System.getProperty("java.io.tmpdir"),"jetty-waver");
+ this._rules = new ArrayList();
+ this._violations = new HashMap>();
+ }
+
+ public void addRule(Rule rule)
+ {
+ _rules.add(rule);
+ try
+ {
+ rule.setViolationListener(this);
+ rule.initialize();
+ }
+ catch (Throwable t)
+ {
+ // Capture any errors out of initialize or setViolationListener() that might occur.
+ String msg = String.format("Unable to add rule [%s]: %s",rule.getName(),t.getMessage());
+ reportException(Rule.ROOT_PATH,msg,rule,t);
+ }
+ }
+
+ private String cleanFilename(URI uri)
+ {
+ // Need a filename to store this download to.
+ String destname = uri.getPath();
+ int idx = destname.lastIndexOf('/');
+ if (idx > 0)
+ {
+ destname = destname.substring(idx);
+ }
+ destname = destname.trim().toLowerCase();
+
+ if (destname.length() <= 0)
+ {
+ // whoops, there's nothing left.
+ // could be caused by urls that point to paths.
+ destname = new SimpleDateFormat("yyyy-MM-dd_hh-mm-ss").format(new Date());
+ }
+
+ // Neuter illegal characters
+ char cleaned[] = new char[destname.length()];
+ for (int i = 0; i < destname.length(); i++)
+ {
+ char c = destname.charAt(i);
+ if (c == '|' || c == '/' || c == '\\' || c == '*' || c == '?' || c == ':' || c == '#')
+ {
+ cleaned[i] = '_';
+ }
+ else
+ {
+ cleaned[i] = c;
+ }
+ }
+
+ destname = new String(cleaned);
+
+ if (!destname.endsWith(".war"))
+ {
+ destname += ".war";
+ }
+
+ return destname;
+ }
+
+ private File download(URI uri) throws MalformedURLException, IOException
+ {
+ // Establish destfile
+ File destfile = new File(_workdir,cleanFilename(uri));
+
+ InputStream in = null;
+ FileOutputStream out = null;
+ try
+ {
+ in = uri.toURL().openStream();
+ out = new FileOutputStream(destfile);
+ IO.copy(in,out);
+ }
+ finally
+ {
+ IO.close(in);
+ }
+ return destfile;
+ }
+
+ private File establishLocalWebappDir() throws URISyntaxException, IOException
+ {
+ if ("file".equals(_webappURI.getScheme()))
+ {
+ File path = new File(_webappURI);
+ if (path.isDirectory())
+ {
+ return path;
+ }
+ return unpack(path);
+ }
+
+ File downloadedFile = download(_webappURI);
+ return unpack(downloadedFile);
+ }
+
+ public List getRules()
+ {
+ return _rules;
+ }
+
+ public Collection getViolations()
+ {
+ // TODO: Icky! I need a better way of getting the list of raw
+ // violations, complete, without path mapping in place.
+ // Yet, I need path mapping as well, right?
+ List violations = new ArrayList();
+ for (List pathviol : _violations.values())
+ {
+ violations.addAll(pathviol);
+ }
+ return violations;
+ }
+
+ public File getWebappDir()
+ {
+ return _webappDir;
+ }
+
+ private String getWebappRelativePath(File dir)
+ {
+ return _webappDir.toURI().relativize(dir.toURI()).toASCIIString();
+ }
+
+ public File getWorkDir()
+ {
+ return _workdir;
+ }
+
+ /**
+ * Tests a filesystem path for webapp expected files, like "WEB-INF/web.xml"
+ */
+ private boolean isValidWebapp(File path)
+ {
+ File webXml = new File(path,"WEB-INF" + File.separator + "web.xml");
+ if (!webXml.exists())
+ {
+ reportViolation(Severity.ERROR,Rule.ROOT_PATH,"Missing WEB-INF/web.xml");
+ return false;
+ }
+
+ if (!webXml.isFile())
+ {
+ reportViolation(Severity.ERROR,Rule.ROOT_PATH,"The WEB-INF/web.xml is not a File");
+ return false;
+ }
+
+ return true;
+ }
+
+ private void reportException(String path, String detail, Rule rule, Throwable t)
+ {
+ Violation viol = new Violation(Severity.ERROR,path,detail,t);
+ viol.setVerifierInfo(rule);
+ reportViolation(viol);
+ }
+
+ public void reportViolation(Severity error, String path, String detail)
+ {
+ reportViolation(new Violation(error,path,detail));
+ }
+
+ public void reportViolation(Violation violation)
+ {
+ List pathviol = _violations.get(violation.getPath());
+ if (pathviol == null)
+ {
+ pathviol = new ArrayList();
+ }
+ pathviol.add(violation);
+ _violations.put(violation.getPath(),pathviol);
+ }
+
+ public void setRules(Collection rules)
+ {
+ this._rules.clear();
+ // Add each rule separately, to establish initialization & listeners
+ for (Rule verifier : rules)
+ {
+ addRule(verifier);
+ }
+ }
+
+ public void setWorkDir(File workDir)
+ {
+ this._workdir = workDir;
+ }
+
+ private File unpack(File path) throws URISyntaxException, IOException
+ {
+ String destname = path.getName().substring(0,path.getName().length() - 4);
+ File destDir = new File(_workdir,destname);
+ URI warURI = new URI("jar",path.toURI() + "!/",null);
+ JarResource warResource = (JarResource)Resource.newResource(warURI);
+ warResource.extract(destDir,false);
+ return destDir;
+ }
+
+ public void visitAll()
+ {
+ try
+ {
+ _webappDir = establishLocalWebappDir();
+
+ // Issue start.
+ for (Rule rule : _rules)
+ {
+ rule.visitWebappStart(Rule.ROOT_PATH,_webappDir);
+ }
+
+ if (isValidWebapp(_webappDir))
+ {
+ // Iterate through content
+ visitContents();
+ // Iterate through WEB-INF/classes
+ visitWebInfClasses();
+ // Iterate through WEB-INF/lib
+ visitWebInfLib();
+ }
+
+ // Issue end.
+ for (Rule rule : _rules)
+ {
+ rule.visitWebappEnd(Rule.ROOT_PATH,_webappDir);
+ }
+ }
+ catch (IOException e)
+ {
+ reportViolation(new Violation(Severity.ERROR,Rule.ROOT_PATH,e.getMessage(),e));
+ }
+ catch (URISyntaxException e)
+ {
+ reportViolation(new Violation(Severity.ERROR,Rule.ROOT_PATH,e.getMessage(),e));
+ }
+ }
+
+ private void visitWebInfClasses()
+ {
+ File classesDir = new File(_webappDir,"WEB-INF" + File.separator + "classes");
+ if (!classesDir.exists())
+ {
+ // skip this path.
+ return;
+ }
+
+ String classesPath = getWebappRelativePath(classesDir);
+
+ if (!classesDir.isDirectory())
+ {
+ reportViolation(Severity.ERROR,classesPath,"WEB-INF/classes is not a Directory?");
+ return;
+ }
+
+ // Issue start.
+ for (Rule rule : _rules)
+ {
+ rule.visitWebInfClassesStart(classesPath,classesDir);
+ }
+
+ visitClassesDir(classesDir,classesDir);
+
+ // Issue end.
+ for (Rule rule : _rules)
+ {
+ rule.visitWebInfClassesEnd(classesPath,classesDir);
+ }
+ }
+
+ private void visitClassesDir(File classesRoot, File classesDir)
+ {
+ File files[] = classesDir.listFiles();
+ for (File file : files)
+ {
+ if (file.isFile())
+ {
+ if (file.getName().endsWith(".class"))
+ {
+ visitClass(classesRoot,file);
+ }
+ else
+ {
+ visitClassResource(classesRoot,file);
+ }
+ }
+ else if (file.isDirectory())
+ {
+ // recurse
+ visitClassesDir(classesRoot,file);
+ }
+ }
+ }
+
+ private void visitClassResource(File classesRoot, File file)
+ {
+ String path = getWebappRelativePath(file);
+ String resourcePath = classesRoot.toURI().relativize(file.toURI()).toASCIIString();
+ for (Rule rule : _rules)
+ {
+ rule.visitWebInfClassResource(path,resourcePath,file);
+ }
+ }
+
+ private void visitClass(File classesRoot, File file)
+ {
+ String path = getWebappRelativePath(file);
+ String className = classesRoot.toURI().relativize(file.toURI()).toASCIIString();
+ className = className.replace("/",".");
+ if (className.endsWith(".class"))
+ {
+ className = className.substring(0,className.length() - 6);
+ }
+ for (Rule rule : _rules)
+ {
+ rule.visitWebInfClass(path,className,file);
+ }
+ }
+
+ private void visitWebInfLib()
+ {
+ File libDir = new File(_webappDir,"WEB-INF" + File.separator + "lib");
+ if (!libDir.exists())
+ {
+ // skip this path.
+ return;
+ }
+
+ String libPath = getWebappRelativePath(libDir);
+
+ if (!libDir.isDirectory())
+ {
+ reportViolation(Severity.ERROR,libPath,"WEB-INF/lib is not a Directory?");
+ return;
+ }
+
+ // Issue start.
+ for (Rule rule : _rules)
+ {
+ rule.visitWebInfLibStart(libPath,libDir);
+ }
+
+ // Iterator through contents of WEB-INF/lib
+ File archives[] = libDir.listFiles();
+ for (File archive : archives)
+ {
+ if (!archive.isFile())
+ {
+ reportViolation(Severity.WARNING,Rule.ROOT_PATH,"Found non-file in WEB-INF/lib. Remove it, "
+ + "as it cannot be accessed by the Servlet container or the Webapp: " + archive);
+ continue;
+ }
+
+ if (archive.getName().toLowerCase().endsWith(".jar"))
+ {
+ visitWebInfLibJar(libPath,archive);
+ continue;
+ }
+
+ if (archive.getName().toLowerCase().endsWith(".zip"))
+ {
+ visitWebInfLibZip(libPath,archive);
+ continue;
+ }
+
+ reportViolation(Severity.WARNING,Rule.ROOT_PATH,"Found non-archive in WEB-INF/lib. Remove it, "
+ + "as it cannot be accessed by the Servlet container or the Webapp: " + archive);
+ }
+
+ // Issue end.
+ for (Rule rule : _rules)
+ {
+ rule.visitWebInfLibEnd(libPath,libDir);
+ }
+ }
+
+ private void visitWebInfLibJar(String libPath, File archive)
+ {
+ String jarPath = libPath + archive.getName();
+
+ // Issue visit on Jar
+ for (Rule rule : _rules)
+ {
+ JarFile jar = null;
+ try
+ {
+ jar = new JarFile(archive);
+ rule.visitWebInfLibJar(jarPath,archive,jar);
+ }
+ catch (Throwable t)
+ {
+ reportViolation(new Violation(Severity.ERROR,jarPath,t.getMessage(),t));
+ }
+ finally
+ {
+ if (jar != null)
+ {
+ try
+ {
+ jar.close();
+ }
+ catch (IOException ignore)
+ {
+ /* ignore */
+ }
+ }
+ }
+ }
+ }
+
+ private void visitWebInfLibZip(String libPath, File archive)
+ {
+ String zipPath = libPath + archive.getName();
+
+ // Issue visit on Zip
+ for (Rule rule : _rules)
+ {
+ ZipFile zip = null;
+ try
+ {
+ zip = new ZipFile(archive);
+ rule.visitWebInfLibZip(zipPath,archive,zip);
+ }
+ catch (Throwable t)
+ {
+ reportViolation(new Violation(Severity.ERROR,zipPath,t.getMessage(),t));
+ }
+ finally
+ {
+ if (zip != null)
+ {
+ try
+ {
+ zip.close();
+ }
+ catch (IOException ignore)
+ {
+ /* ignore */
+ }
+ }
+ }
+ }
+ }
+
+ private void visitContents()
+ {
+ visitDirectoryRecursively(_webappDir);
+ }
+
+ private void visitDirectoryRecursively(File dir)
+ {
+ String path = getWebappRelativePath(dir);
+
+ // Start Dir
+ for (Rule rule : this._rules)
+ {
+ rule.visitDirectoryStart(path,dir);
+ }
+
+ File entries[] = dir.listFiles();
+
+ // Individual Files
+ for (File file : entries)
+ {
+ if (file.isFile())
+ {
+ String filepath = path + file.getName();
+ for (Rule rule : this._rules)
+ {
+ rule.visitFile(filepath,dir,file);
+ }
+ }
+ }
+
+ // Sub dirs
+ for (File file : entries)
+ {
+ if (file.isDirectory())
+ {
+ visitDirectoryRecursively(file);
+ }
+ }
+
+ // End Dir
+ for (Rule rule : this._rules)
+ {
+ rule.visitDirectoryEnd(path,dir);
+ }
+ }
+
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/ForbiddenClassesRule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/ForbiddenClassesRule.java
new file mode 100644
index 00000000000..6e845725c10
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/ForbiddenClassesRule.java
@@ -0,0 +1,90 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.jetty.webapp.verifier.AbstractArchiveScanningRule;
+
+/**
+ * ForbiddenClassesVerifier checks the various classes available to the Webapp to ensure that they do not contain and
+ * forbidden classes.
+ */
+public class ForbiddenClassesRule extends AbstractArchiveScanningRule
+{
+ private Map classPatterns = new HashMap();
+
+ public void addClassPattern(String classPattern)
+ {
+ StringBuffer regex = new StringBuffer();
+ for (char c : classPattern.toCharArray())
+ {
+ if (c == '.')
+ {
+ regex.append("\\.");
+ }
+ else if (c == '*')
+ {
+ regex.append(".*");
+ }
+ else
+ {
+ regex.append(c);
+ }
+ }
+ classPatterns.put(classPattern,Pattern.compile(regex.toString()));
+ }
+
+ @Override
+ public String getDescription()
+ {
+ return "Ensures that forbidden packages are not present in the war file";
+ }
+
+ @Override
+ public String getName()
+ {
+ return "forbidden-class";
+ }
+
+ private void validateClassname(String path, String className)
+ {
+ for (Map.Entry pattern : this.classPatterns.entrySet())
+ {
+ if (pattern.getValue().matcher(className).matches())
+ {
+ error(path,"Class forbidden by pattern: " + pattern.getKey());
+ }
+ }
+ }
+
+ @Override
+ public void visitWebInfClass(String path, String className, File classFile)
+ {
+ validateClassname(path,className);
+ }
+
+ @Override
+ public void visitArchiveClass(String path, String className, ZipFile archive, ZipEntry archiveEntry)
+ {
+ validateClassname(path,className);
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/ForbiddenContentsRule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/ForbiddenContentsRule.java
new file mode 100644
index 00000000000..c3d2fdedb8a
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/ForbiddenContentsRule.java
@@ -0,0 +1,58 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jetty.webapp.verifier.AbstractRule;
+import org.eclipse.jetty.webapp.verifier.support.PathGlob;
+
+/**
+ * ForbiddenContentsVerifier ensures that content matching a pattern does not exist in the webapp.
+ */
+public class ForbiddenContentsRule extends AbstractRule
+{
+ private List _patterns = new ArrayList();
+
+ public void addPattern(String pattern)
+ {
+ _patterns.add(pattern);
+ }
+
+ public String getDescription()
+ {
+ return "Checks for forbidden content";
+ }
+
+ public String getName()
+ {
+ return "forbidden-content";
+ }
+
+ @Override
+ public void visitFile(String path, File dir, File file)
+ {
+ for (String pattern : _patterns)
+ {
+ if (PathGlob.match(pattern,path))
+ {
+ error(path,"Forbidden content detected");
+ }
+ }
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/JarSignatureRule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/JarSignatureRule.java
new file mode 100644
index 00000000000..91fc2122082
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/JarSignatureRule.java
@@ -0,0 +1,231 @@
+// ========================================================================
+// Copyright (c) 2009-2009 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.webapp.verifier.AbstractRule;
+
+/**
+ * Signed Jar Verifier
+ */
+public class JarSignatureRule extends AbstractRule
+{
+ private String _keystoreLocation = System.getProperty("java.home") + "/lib/security/cacerts";
+ private String _type = "JKS"; // default
+ private String _alias = "verisignclass3ca"; // default
+ private KeyStore _keystore;
+
+ private static X509Certificate[] _trustedCertificates;
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.webapp.verifier.AbstractRule#getDescription()
+ */
+ public String getDescription()
+ {
+ return "verifies that the given keystore contains the certificates required for all jar files present";
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.webapp.verifier.AbstractRule#getName()
+ */
+ public String getName()
+ {
+ return "jar-signature";
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param jar
+ * @return
+ */
+ private List resolveJar(JarFile jar)
+ {
+ List entries = new ArrayList();
+
+ Enumeration e = jar.entries();
+
+ while (e.hasMoreElements())
+ {
+ JarEntry jarEntry = e.nextElement();
+ try
+ {
+ entries.add(jarEntry); // for further verification
+ IO.toString(jar.getInputStream(jar.getEntry(jarEntry.getName())));
+ }
+ catch (IOException e1)
+ {
+ throw new SecurityException(e1);
+ }
+ }
+
+ return entries;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the _keystore.
+ *
+ * @param keystore
+ * the _keystore to set
+ */
+ public void setKeystoreLocation( String keyStoreLocation )
+ {
+ _keystoreLocation = keyStoreLocation;
+ }
+
+ @Override
+ public void initialize()
+ {
+ try
+ {
+ _keystore = KeyStore.getInstance(_type);
+
+ InputStream istream = new File( _keystoreLocation ).toURL().openStream();
+
+ _keystore.load(istream,null);
+
+ _trustedCertificates = new X509Certificate[]
+ { (X509Certificate)_keystore.getCertificate(_alias) };
+
+ }
+ catch (Throwable t)
+ {
+ exception(_keystoreLocation, t.getMessage(), t);
+ }
+ }
+
+ public void setType(String type)
+ {
+ _type = type;
+ }
+
+ /**
+ * @see org.eclipse.jetty.webapp.verifier.Rule#visitWebInfLibJar(java.lang.String, java.io.File, java.util.jar.JarFile)
+ */
+ @Override
+ public void visitWebInfLibJar(String path, File archive, JarFile jar)
+ {
+
+ try
+ {
+ if (jar.getManifest() == null)
+ {
+ error(jar.toString(),"missing manifest.mf, can not be signed");
+ }
+
+ List entries = resolveJar(jar);
+
+ for (JarEntry jarEntry : entries)
+ {
+ if (!jarEntry.isDirectory() && !jarEntry.getName().startsWith("META-INF"))
+ {
+ Certificate[] certs = jarEntry.getCertificates();
+
+ if (certs == null || certs.length == 0)
+ {
+ error(jarEntry.getName(),"entry has not been signed");
+ }
+ else
+ {
+ X509Certificate[] chainRoots = getChainRoots(certs);
+ boolean signed = false;
+
+ for (int i = 0; i < chainRoots.length; i++)
+ {
+ if (isTrusted(chainRoots[i]))
+ {
+ signed = true;
+ break;
+ }
+ }
+ if (!signed)
+ {
+ error(jarEntry.getName(),"Untrusted provider's JAR");
+ }
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ exception(jar.getName(), e.getMessage(), e);
+ }
+ }
+
+ private boolean isTrusted(X509Certificate certificate)
+ {
+ for (int i = 0; i < _trustedCertificates.length; i++)
+ {
+ if (certificate.getSubjectDN().equals(_trustedCertificates[i].getSubjectDN()))
+ {
+ if (certificate.equals(_trustedCertificates[i]))
+ {
+ return true;
+ }
+ }
+ }
+
+ for (int i = 0; i < _trustedCertificates.length; i++)
+ {
+ if (certificate.getIssuerDN().equals(_trustedCertificates[i].getSubjectDN()))
+ {
+ try
+ {
+ certificate.verify(_trustedCertificates[i].getPublicKey());
+ return true;
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns a array of certificates with the root certificate of each chain
+ *
+ * @param certificates an array of X509 certificate's
+ * @return an array of X509 certificate's with the root certificate of each chain
+ */
+ private X509Certificate[] getChainRoots(Certificate[] certificates)
+ {
+ List chainRoots = new ArrayList();
+
+ for (int i = 0; i < certificates.length - 1; i++)
+ {
+ if (!((X509Certificate)certificates[i + 1]).getSubjectDN().equals(((X509Certificate)certificates[i]).getIssuerDN()))
+ {
+ chainRoots.add((X509Certificate)certificates[i]);
+ }
+ }
+
+ chainRoots.add((X509Certificate)certificates[certificates.length - 1]);
+
+ return chainRoots.toArray(new X509Certificate[chainRoots.size()]);
+ }
+
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/JavaSupportLevelRule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/JavaSupportLevelRule.java
new file mode 100644
index 00000000000..cf93c409385
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/JavaSupportLevelRule.java
@@ -0,0 +1,166 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.jetty.webapp.verifier.AbstractArchiveScanningRule;
+import org.eclipse.jetty.webapp.verifier.rules.asm.ASMUtil;
+import org.eclipse.jetty.webapp.verifier.rules.asm.AbstractClassVisitor;
+
+/**
+ * Ensure all compiled classes within webapp are within the supported JVM range.
+ */
+public class JavaSupportLevelRule extends AbstractArchiveScanningRule
+{
+ class ClassVersionVisitor extends AbstractClassVisitor
+ {
+ private double classVersion = -1;
+
+ public double getClassVersion()
+ {
+ return classVersion;
+ }
+
+ @Override
+ public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
+ {
+ this.classVersion = getJavaClassVersion(version);
+ }
+
+ private double getJavaClassVersion(int version)
+ {
+ int major = version & 0xFFFF;
+ int minor = version >>> 16;
+
+ // Java Versions to Class Version (major.minor)
+ // Java 1.6 = 50.0
+ // Java 1.5 = 49.0
+ // Java 1.4 = 48.0
+ // Java 1.3 = 47.0
+ // Java 1.2 = 46.0
+ // Java 1.1 = 45.3
+
+ // TODO: check these since they are > instead of >=
+ if (major >= 50)
+ {
+ return 1.6;
+ }
+ else if (major >= 49)
+ {
+ return 1.5;
+ }
+ else if (major >= 48)
+ {
+ return 1.4;
+ }
+ else if (major >= 47)
+ {
+ return 1.3;
+ }
+ else if (major >= 46)
+ {
+ return 1.2;
+ }
+ else if (major >= 45)
+ {
+ if (minor >= 3)
+ {
+ return 1.1;
+ }
+ return 1.0;
+ }
+
+ return 0.0;
+ }
+
+ public void reset()
+ {
+ this.classVersion = (-1);
+ }
+ }
+
+ private double supportedVersion = 1.5;
+ private ClassVersionVisitor visitor;
+
+ @Override
+ public String getDescription()
+ {
+ return "Ensure all compiled classes within webapp are within the supported JVM";
+ }
+
+ @Override
+ public String getName()
+ {
+ return "java-support-level";
+ }
+
+ public double getSupportedVersion()
+ {
+ return supportedVersion;
+ }
+
+ public void setSupportedVersion(double supportedVersion)
+ {
+ this.supportedVersion = supportedVersion;
+ }
+
+ @Override
+ public void visitWebappStart(String path, File dir)
+ {
+ visitor = new ClassVersionVisitor();
+ }
+
+
+ @Override
+ public void visitWebInfClass(String path, String className, File classFile)
+ {
+ try
+ {
+ visitor.reset();
+ ASMUtil.visitClassFile(classFile,visitor,0);
+ if (visitor.classVersion > supportedVersion)
+ {
+ error(path,"Class is compiled for java version [" + visitor.classVersion + "] which is over supported java version [" + supportedVersion + "]");
+ }
+ }
+ catch (IOException e)
+ {
+ exception(path,"Unable to read class",e);
+ }
+ }
+
+ @Override
+ public void visitArchiveClass(String path, String className, ZipFile archive, ZipEntry archiveEntry)
+ {
+ try
+ {
+ visitor.reset();
+ ASMUtil.visitClass(archive.getInputStream(archiveEntry),visitor,0);
+ if (visitor.classVersion > supportedVersion)
+ {
+ error(path,"Class is compiled for java version [" + visitor.classVersion + "] which is over supported java version [" + supportedVersion + "]");
+ }
+ }
+ catch (IOException e)
+ {
+ exception(path,"Unable to read class",e);
+ }
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/JspPrecompileRule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/JspPrecompileRule.java
new file mode 100644
index 00000000000..73bfb552a43
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/JspPrecompileRule.java
@@ -0,0 +1,43 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import java.io.File;
+
+import org.eclipse.jetty.webapp.verifier.AbstractRule;
+
+/**
+ * Perform a JSP pre-compile to ensure all JSPs are valid.
+ */
+public class JspPrecompileRule extends AbstractRule
+{
+ public String getDescription()
+ {
+ return "Perform JSP precompile to ensure all jsps are valid";
+ }
+
+ public String getName()
+ {
+ return "jsp-precompile";
+ }
+
+ @Override
+ public void visitWebappStart(String path, File dir)
+ {
+ // TODO: implement rule.
+ error(path,"Rule [" + getClass().getName() + "] not yet implemented");
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/JspSupportLevelRule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/JspSupportLevelRule.java
new file mode 100644
index 00000000000..15181ade9b4
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/JspSupportLevelRule.java
@@ -0,0 +1,43 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import java.io.File;
+
+import org.eclipse.jetty.webapp.verifier.AbstractRule;
+
+/**
+ * Ensure any included JSPs are supported by the Container.
+ */
+public class JspSupportLevelRule extends AbstractRule
+{
+ public String getDescription()
+ {
+ return "Ensure include JSP are supported by the Container";
+ }
+
+ public String getName()
+ {
+ return "jsp-support-level";
+ }
+
+ @Override
+ public void visitWebappStart(String path, File dir)
+ {
+ // TODO: implement rule.
+ error(path,"Rule [" + getClass().getName() + "] not yet implemented");
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/NoJspRule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/NoJspRule.java
new file mode 100644
index 00000000000..d296f39a916
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/NoJspRule.java
@@ -0,0 +1,46 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import java.io.File;
+
+import org.eclipse.jetty.webapp.verifier.AbstractRule;
+
+/**
+ * Prevent inclusion of *.jsp in webapp.
+ */
+public class NoJspRule extends AbstractRule
+{
+ public String getDescription()
+ {
+ return "Prevent inclusion of JSPs in webapp";
+ }
+
+ public String getName()
+ {
+ return "no-jsp";
+ }
+
+ @Override
+ public void visitFile(String path, File dir, File file)
+ {
+ String name = file.getName().toLowerCase();
+ if (name.endsWith(".jsp") || name.endsWith(".jspf"))
+ {
+ error(path,"No JSP's are allowed");
+ }
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/NoNativeRule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/NoNativeRule.java
new file mode 100644
index 00000000000..ee6f1176f87
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/NoNativeRule.java
@@ -0,0 +1,68 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import java.io.File;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.jetty.webapp.verifier.AbstractArchiveScanningRule;
+import org.eclipse.jetty.webapp.verifier.support.PathGlob;
+
+/**
+ * Prevent use of native code in webapp.
+ */
+public class NoNativeRule extends AbstractArchiveScanningRule
+{
+ private String[] nativePatterns =
+ { "*.so", "*.so.*", "*.o", "*.dll", "*.com", "*.exe" };
+
+ @Override
+ public String getDescription()
+ {
+ return "Prevent use of native code in webapp";
+ }
+
+ @Override
+ public String getName()
+ {
+ return "no-native";
+ }
+
+ @Override
+ public void visitFile(String path, File dir, File file)
+ {
+ for (String pattern : nativePatterns)
+ {
+ if (PathGlob.match(pattern,path))
+ {
+ error(path,"Native code is forbidden");
+ }
+ }
+ }
+
+ @Override
+ public void visitArchiveResource(String path, ZipFile zip, ZipEntry entry)
+ {
+ for (String pattern : nativePatterns)
+ {
+ if (PathGlob.match(pattern,entry.getName()))
+ {
+ error(path,"Native code is forbidden");
+ }
+ }
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/NoScriptingRule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/NoScriptingRule.java
new file mode 100644
index 00000000000..2cbfd45efa0
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/NoScriptingRule.java
@@ -0,0 +1,235 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.jetty.webapp.verifier.AbstractRule;
+
+/**
+ * NoScriptingRule ensure that no scripting languages are used in the webapp.
+ *
+ * Checks for actual script files in webapp filesystem, and existance of popular scripting language libraries as well.
+ */
+public class NoScriptingRule extends AbstractRule
+{
+ class Forbidden
+ {
+ public String key;
+ public String msg;
+
+ public Forbidden(String key, String msg)
+ {
+ super();
+ this.key = key;
+ this.msg = msg;
+ }
+ }
+
+ private boolean allowJRuby = false;
+ private boolean allowBeanshell = false;
+ private boolean allowGroovy = false;
+ private boolean allowJython = false;
+ private boolean allowShell = false;
+ private List forbiddenFileExtensions = new ArrayList();
+ private List forbiddenClassIds = new ArrayList();
+
+ public boolean isAllowShell()
+ {
+ return allowShell;
+ }
+
+ public void setAllowShell(boolean allowShell)
+ {
+ this.allowShell = allowShell;
+ }
+
+ public boolean isAllowJRuby()
+ {
+ return allowJRuby;
+ }
+
+ public void setAllowJRuby(boolean allowJruby)
+ {
+ this.allowJRuby = allowJruby;
+ }
+
+ public boolean isAllowBeanshell()
+ {
+ return allowBeanshell;
+ }
+
+ public void setAllowBeanshell(boolean allowBeanshell)
+ {
+ this.allowBeanshell = allowBeanshell;
+ }
+
+ public boolean isAllowGroovy()
+ {
+ return allowGroovy;
+ }
+
+ public void setAllowGroovy(boolean allowGroovy)
+ {
+ this.allowGroovy = allowGroovy;
+ }
+
+ public boolean isAllowJython()
+ {
+ return allowJython;
+ }
+
+ public void setAllowJython(boolean allowJython)
+ {
+ this.allowJython = allowJython;
+ }
+
+ public String getDescription()
+ {
+ return "Do not allow scripting languages in webapp";
+ }
+
+ public String getName()
+ {
+ return "forbidden-scripting";
+ }
+
+ @Override
+ public void initialize() throws Throwable
+ {
+ forbiddenFileExtensions.clear();
+ forbiddenClassIds.clear();
+ if (!allowJRuby)
+ {
+ String msg = "JRuby scripting not allowed";
+ forbiddenFileExtensions.add(new Forbidden(".rb",msg));
+ forbiddenFileExtensions.add(new Forbidden(".rhtml",msg));
+ msg = "JRuby dependencies are not allowed";
+ forbiddenClassIds.add(new Forbidden(".jruby.",msg));
+ }
+
+ if (!allowJython)
+ {
+ String msg = "Jython and Python scripting not allowed";
+ forbiddenFileExtensions.add(new Forbidden(".py",msg));
+ forbiddenFileExtensions.add(new Forbidden(".pyc",msg));
+ msg = "Jython dependencies are not allowed";
+ forbiddenClassIds.add(new Forbidden("org.python.",msg));
+ }
+
+ if (!allowGroovy)
+ {
+ String msg = "Groovy scripting not allowed";
+ forbiddenFileExtensions.add(new Forbidden(".groovy",msg));
+ msg = "Groovy dependencies are not allowed";
+ forbiddenClassIds.add(new Forbidden(".groovy.",msg));
+ }
+
+ if (!allowShell)
+ {
+ String msg = "Shell scripting not allowed";
+ forbiddenFileExtensions.add(new Forbidden(".sh",msg));
+ forbiddenFileExtensions.add(new Forbidden(".bat",msg));
+ forbiddenFileExtensions.add(new Forbidden(".cmd",msg));
+ forbiddenFileExtensions.add(new Forbidden(".vbs",msg));
+ }
+ }
+
+ @Override
+ public void visitFile(String path, File dir, File file)
+ {
+ String name = file.getName().toLowerCase();
+ for (Forbidden forbidden : forbiddenFileExtensions)
+ {
+ if (name.endsWith(forbidden.key))
+ {
+ error(path,forbidden.msg);
+ }
+ }
+ }
+
+ @Override
+ public void visitWebInfClass(String path, String className, File classFile)
+ {
+ validateClassname(path,className);
+ }
+
+ private void validateClassname(String path, String className)
+ {
+ for (Forbidden forbidden : forbiddenClassIds)
+ {
+ if (className.contains(forbidden.key))
+ {
+ error(path,forbidden.msg);
+ }
+ }
+ }
+
+ @Override
+ public void visitWebInfClassResource(String path, String resourcePath, File resourceFile)
+ {
+ super.visitWebInfClassResource(path,resourcePath,resourceFile);
+ }
+
+ @Override
+ public void visitWebInfLibJar(String path, File archive, JarFile jar)
+ {
+ iterateArchive(path,archive,jar);
+ }
+
+ private void iterateArchive(String path, File archive, ZipFile zip)
+ {
+ try
+ {
+ Enumeration extends ZipEntry> entries = zip.entries();
+ while (entries.hasMoreElements())
+ {
+ ZipEntry entry = entries.nextElement();
+ if (entry.getName().endsWith(".class"))
+ {
+ checkArchiveClassname(path,archive,entry.getName());
+ }
+ }
+ }
+ catch (Throwable t)
+ {
+ exception(path,"Unable to iterate archive: Contents invalid?: " + t.getMessage(),t);
+ }
+ }
+
+ private void checkArchiveClassname(String path, File archive, String name)
+ {
+ String className = name.replace("/",".");
+ if (className.endsWith(".class"))
+ {
+ className = className.substring(0,className.length() - 6);
+ }
+
+ validateClassname(path + "!/" + name,className);
+ }
+
+ @Override
+ public void visitWebInfLibZip(String path, File archive, ZipFile zip)
+ {
+ iterateArchive(path,archive,zip);
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/NoSourceControlRule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/NoSourceControlRule.java
new file mode 100644
index 00000000000..2b07684f3c8
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/NoSourceControlRule.java
@@ -0,0 +1,151 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.jetty.webapp.verifier.AbstractArchiveScanningRule;
+
+/**
+ * Prevent inclusion of Source Control files & directories that might reveal hostnames, userids, and passwords to the
+ * source control. (CVS, .svn/, .git/)
+ */
+public class NoSourceControlRule extends AbstractArchiveScanningRule
+{
+ class ScmName
+ {
+ String scm;
+ String name;
+
+ public ScmName(String scm, String name)
+ {
+ this.scm = scm;
+ this.name = name;
+ }
+ }
+
+ private static List scmDirNames = new ArrayList();
+ private static List scmFileNames = new ArrayList();
+
+ public NoSourceControlRule()
+ {
+ super();
+
+ // The order of patterns is most likely to least likely
+
+ scmDirNames.add(new ScmName("Subversion",".svn")); // Standard Unix format
+ scmDirNames.add(new ScmName("Subversion","_svn")); // Alternate Windows format
+ scmDirNames.add(new ScmName("CVS","CVS"));
+ scmFileNames.add(new ScmName("CVS",".cvsignore"));
+ scmDirNames.add(new ScmName("Git",".git"));
+ scmFileNames.add(new ScmName("Git",".gitignore"));
+ scmDirNames.add(new ScmName("RCS","RCS"));
+ scmDirNames.add(new ScmName("SCCS","SCCS"));
+ scmFileNames.add(new ScmName("Visual SourceSafe","vssver.scc"));
+ scmDirNames.add(new ScmName("Arch",".arch-ids"));
+ scmDirNames.add(new ScmName("Bazaar",".bzr"));
+ scmFileNames.add(new ScmName("SurroundSCM",".MySCMServerInfo"));
+ scmDirNames.add(new ScmName("Mercurial",".hg"));
+ scmDirNames.add(new ScmName("BitKeeper","BitKeeper"));
+ scmDirNames.add(new ScmName("BitKeeper","ChangeSet"));
+ scmDirNames.add(new ScmName("Darcs","_darcs"));
+ scmDirNames.add(new ScmName("Darcs",".darcsrepo"));
+ scmFileNames.add(new ScmName("Darcs",".darcs-temp-mail"));
+ }
+
+ @Override
+ public String getDescription()
+ {
+ return "Prevent inclusion of source control files in webapp";
+ }
+
+ @Override
+ public String getName()
+ {
+ return "no-source-control";
+ }
+
+ @Override
+ public void visitDirectoryStart(String path, File dir)
+ {
+ for (ScmName scmName : scmDirNames)
+ {
+ if (dir.getName().equalsIgnoreCase(scmName.name))
+ {
+ error(path,scmName.scm + " Source Control directories are not allowed");
+ }
+ }
+ }
+
+ @Override
+ public void visitFile(String path, File dir, File file)
+ {
+ for (ScmName scmName : scmFileNames)
+ {
+ if (file.getName().equalsIgnoreCase(scmName.name))
+ {
+ error(path,scmName.scm + " Source Control file are not allowed");
+ }
+ }
+ }
+
+ @Override
+ public void visitArchiveResource(String path, ZipFile zip, ZipEntry entry)
+ {
+ String basename = toBaseName(entry);
+
+ if (entry.isDirectory())
+ {
+ for (ScmName scmName : scmDirNames)
+ {
+ if (basename.equalsIgnoreCase(scmName.name))
+ {
+ error(path,scmName.scm + " Source Control directories are not allowed");
+ }
+ }
+ }
+ else
+ {
+ for (ScmName scmName : scmFileNames)
+ {
+ if (basename.equalsIgnoreCase(scmName.name))
+ {
+ error(path,scmName.scm + " Source Control file are not allowed");
+ }
+ }
+ }
+ }
+
+ private String toBaseName(ZipEntry entry)
+ {
+ String name =entry.getName();
+ if (name.endsWith("/"))
+ {
+ name = name.substring(0,name.length() - 1);
+ }
+
+ int idx = name.lastIndexOf('/');
+ if (idx >= 0)
+ {
+ return name.substring(idx + 1);
+ }
+ return name;
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/NoSourceRule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/NoSourceRule.java
new file mode 100644
index 00000000000..48f2f0c5e07
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/NoSourceRule.java
@@ -0,0 +1,70 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import java.io.File;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.jetty.webapp.verifier.AbstractArchiveScanningRule;
+import org.eclipse.jetty.webapp.verifier.support.PathGlob;
+
+/**
+ *
+ * Prevent inclusion of source files in webapp. (*.java)
+ *
+ */
+public class NoSourceRule extends AbstractArchiveScanningRule
+{
+ private String[] sourcePatterns =
+ { "*.java" };
+
+ @Override
+ public String getDescription()
+ {
+ return "Prevent inclusion of source files in webapp";
+ }
+
+ @Override
+ public String getName()
+ {
+ return "no-source";
+ }
+
+ @Override
+ public void visitFile(String path, File dir, File file)
+ {
+ for (String pattern : sourcePatterns)
+ {
+ if (PathGlob.match(pattern,path))
+ {
+ error(path,"Source code is forbidden");
+ }
+ }
+ }
+
+ @Override
+ public void visitArchiveResource(String path, ZipFile zip, ZipEntry entry)
+ {
+ for (String pattern : sourcePatterns)
+ {
+ if (PathGlob.match(pattern,entry.getName()))
+ {
+ error(path,"Source code is forbidden");
+ }
+ }
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/RequiredContentsRule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/RequiredContentsRule.java
new file mode 100644
index 00000000000..75efa42adcf
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/RequiredContentsRule.java
@@ -0,0 +1,64 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jetty.webapp.verifier.AbstractRule;
+
+/**
+ * ForbiddenContentsVerifier ensures that content matching a pattern does not exist in the webapp.
+ */
+public class RequiredContentsRule extends AbstractRule
+{
+ private List _paths = new ArrayList();
+
+ public void addPath(String path)
+ {
+ _paths.add(path);
+ }
+
+ public String getDescription()
+ {
+ return "Ensures that requred content is present";
+ }
+
+ public String getName()
+ {
+ return "required-content";
+ }
+
+ @Override
+ public void visitDirectoryEnd(String path, File dir)
+ {
+ if (path.equals(ROOT_PATH))
+ {
+ File root = new File(path);
+
+ for (String expectedPath : _paths)
+ {
+ File file = new File(root,expectedPath);
+ if (!file.exists())
+ {
+ error(getWebappRelativePath(file),"Required content not found");
+ }
+ }
+ }
+ }
+
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/SaneArchiveRule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/SaneArchiveRule.java
new file mode 100644
index 00000000000..56a0ce22cb5
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/SaneArchiveRule.java
@@ -0,0 +1,59 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import java.io.File;
+
+import org.eclipse.jetty.webapp.verifier.AbstractRule;
+
+/**
+ *
+ * Sanity check of archive (both war itself, as well as libs) to ensure that various entries within are sane.
+ *
+ *
+ *
+ * Example checks:
+ *
+ *
+ *
+ * - Entries cannot contain references to parent "../../my_file.txt"
+ * - Cannot contain multiple entries of the same name with different case.
+ *
+ * - /index.jsp
+ * - /Index.jsp
+ *
+ * -
+ *
+ */
+public class SaneArchiveRule extends AbstractRule
+{
+ public String getDescription()
+ {
+ return "Basic archive (jar & war) sanity checks";
+ }
+
+ public String getName()
+ {
+ return "sane-archive";
+ }
+
+ @Override
+ public void visitWebappStart(String path, File dir)
+ {
+ // TODO: implement rule.
+ error(path,"Rule [" + getClass().getName() + "] not yet implemented");
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/ServletSupportLevelRule.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/ServletSupportLevelRule.java
new file mode 100644
index 00000000000..29c95312b3a
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/ServletSupportLevelRule.java
@@ -0,0 +1,374 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.jetty.webapp.verifier.AbstractRule;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+/**
+ * Ensure declared servlet level (servlet spec version) in webapp conforms to supported level.
+ */
+public class ServletSupportLevelRule extends AbstractRule
+{
+ private static final String XSI_NS = "http://www.w3.org/2001/XMLSchema-instance";
+
+ class ServletId
+ {
+ String version;
+ String name;
+ String type;
+
+ public ServletId(String version, String type, String name)
+ {
+ super();
+ this.version = version;
+ this.type = type;
+ this.name = name;
+ }
+ }
+
+ private String supportedVersion = "2.5";
+ private String fileSep = System.getProperty("file.separator","/");
+ private List dtdPublicIds = new ArrayList();
+ private List dtdSystemIds = new ArrayList();
+ private List nsIds = new ArrayList();
+ private List schemaIds = new ArrayList();
+ private String validVersions[] =
+ { "2.5", "2.4", "2.3", "2.2" };
+
+ public ServletSupportLevelRule()
+ {
+ // Servlet 2.5
+ schemaIds.add(new ServletId("2.5","Schema","http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd"));
+ nsIds.add(new ServletId("2.5","XML Namespace","http://java.sun.com/xml/ns/javaee"));
+
+ // Servlet 2.4
+ schemaIds.add(new ServletId("2.4","Schema","http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"));
+ nsIds.add(new ServletId("2.4","XML Namespace","http://java.sun.com/xml/ns/j2ee"));
+
+ // Servlet 2.3
+ dtdPublicIds.add(new ServletId("2.3","DOCTYPE Public ID","-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"));
+ dtdSystemIds.add(new ServletId("2.3","DOCTYPE System ID","http://java.sun.com/dtd/web-app_2_3.dtd"));
+
+ // Servlet 2.2
+ dtdPublicIds.add(new ServletId("2.2","DOCTYPE Public ID","-//Sun Microsystems, Inc.//DTD WebApplication 2.2//EN"));
+ dtdSystemIds.add(new ServletId("2.2","DOCTYPE System ID","http://java.sun.com/j2ee/dtds/web-app_2.2.dtd"));
+ }
+
+ public String getDescription()
+ {
+ return "Ensure webapp works within supported servlet spec";
+ }
+
+ public String getName()
+ {
+ return "servlet-support-level";
+ }
+
+ public String getSupportedVersion()
+ {
+ return supportedVersion;
+ }
+
+ public void setSupportedVersion(String supportedLevel)
+ {
+ this.supportedVersion = supportedLevel;
+ }
+
+ @Override
+ public void visitWebappStart(String path, File dir)
+ {
+ super.visitWebappStart(path,dir);
+
+ File webXmlFile = new File(dir,"WEB-INF/web.xml".replaceAll("/",fileSep));
+ String webxmlpath = getWebappRelativePath(webXmlFile);
+
+ if (!webXmlFile.exists())
+ {
+ error(webxmlpath,"web.xml does not exist");
+ return;
+ }
+
+ // Using JAXP to parse the web.xml (SAX pls)
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setValidating(false);
+ factory.setNamespaceAware(true);
+
+ try
+ {
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ Document doc = builder.parse(webXmlFile);
+
+ List detectedIds = collectServletIds(webxmlpath,doc);
+ Set versions = new TreeSet();
+ for (ServletId id : detectedIds)
+ {
+ versions.add(id.version);
+ }
+
+ if (versions.size() > 1)
+ {
+ String msg = String.format("Found %d versions defined [%s], expected 1",versions.size(),join(versions,", "));
+ error(webxmlpath,msg);
+ for (ServletId id : detectedIds)
+ {
+ reportConflicting(webxmlpath,id,detectedIds);
+ }
+ }
+
+ reportOverVersion(webxmlpath,detectedIds);
+ }
+ catch (ParserConfigurationException e)
+ {
+ exception(webxmlpath,"[internal] Unable to establish XML parser",e);
+ }
+ catch (SAXException e)
+ {
+ exception(webxmlpath,"Unable to parse web.xml",e);
+ }
+ catch (IOException e)
+ {
+ exception(webxmlpath,"Unable to parse web.xml",e);
+ }
+ }
+
+ private void reportOverVersion(String webxmlpath, List detectedIds)
+ {
+ double supportedVer = Double.parseDouble(this.supportedVersion);
+
+ for (ServletId id : detectedIds)
+ {
+ try
+ {
+ double detectedVersion = Double.parseDouble(id.version);
+ if (detectedVersion > supportedVer)
+ {
+ String msg = String.format("Specified servlet version %s of %s is over the configured supported servlet version %s",id.version,id.type,
+ supportedVersion);
+ error(webxmlpath,msg);
+ }
+ }
+ catch (NumberFormatException e)
+ {
+ error(webxmlpath,String.format("Unable to parse version [%s] of %s, not a double",id.version,id.type));
+ }
+ }
+
+ }
+
+ private void reportConflicting(String webxmlpath, ServletId mainId, List otherIds)
+ {
+ for (ServletId id : otherIds)
+ {
+ if (id.version.equals(mainId.version) == false)
+ {
+ String msg = String.format("version %s of %s conflicts with version %s of %s",mainId.version,mainId.type,id.version,id.type);
+ error(webxmlpath,msg);
+ }
+ }
+ }
+
+ private String join(Collection> coll, String delim)
+ {
+ StringBuffer msg = new StringBuffer();
+
+ Iterator> it = coll.iterator();
+ while (it.hasNext())
+ {
+ msg.append(String.valueOf(it.next()));
+ if (it.hasNext())
+ {
+ msg.append(delim);
+ }
+ }
+
+ return msg.toString();
+ }
+
+ private List collectServletIds(String webxmlpath, Document doc)
+ {
+ List ids = new ArrayList();
+
+ // Check for DOCTYPE defined ids.
+ DocumentType doctype = doc.getDoctype();
+ if (doctype != null)
+ {
+ if ("web-app".equals(doctype.getName()))
+ {
+ boolean valid = false;
+ for (ServletId id : dtdPublicIds)
+ {
+ if (id.name.equals(doctype.getPublicId()))
+ {
+ ids.add(id);
+ valid = true;
+ }
+ }
+
+ if (!valid)
+ {
+ error(webxmlpath,"Invalid DOCTYPE public ID: " + doctype.getPublicId());
+ }
+
+ valid = false;
+ for (ServletId id : dtdSystemIds)
+ {
+ if (id.name.equals(doctype.getSystemId()))
+ {
+ ids.add(id);
+ valid = true;
+ }
+ }
+
+ if (!valid)
+ {
+ error(webxmlpath,"Invalid DOCTYPE system ID: " + doctype.getSystemId());
+ }
+ }
+ else
+ {
+ error(webxmlpath,"Invalid DOCTYPE detected, expected 'web-app', but found '" + doctype.getName() + "' instaed.");
+ }
+ }
+
+ // Check for Root Element Namespace ids.
+ Element root = doc.getDocumentElement();
+
+ if ("web-app".equals(root.getTagName()))
+ {
+ String actualXmlNs = root.getAttribute("xmlns");
+ String actualXsi = root.getAttribute("xmlns:xsi");
+ String actualSchema = root.getAttribute("xsi:schemaLocation");
+ String actualVersion = root.getAttribute("version");
+
+ if (hasAnyValue(actualXmlNs,actualXsi,actualSchema,actualVersion))
+ {
+ if ((actualXmlNs == null) || (actualXmlNs == ""))
+ {
+ error(webxmlpath,"Attribute must exist with a valid value");
+ }
+ else
+ {
+ boolean valid = false;
+ for (ServletId id : nsIds)
+ {
+ if (id.name.equals(actualXmlNs))
+ {
+ ids.add(id);
+ valid = true;
+ }
+ }
+
+ if (!valid)
+ {
+ String msg = String.format("Invalid xmlns value for ",actualXmlNs);
+ error(webxmlpath,msg);
+ }
+ }
+
+ if ((actualXsi == null) || (actualXsi == ""))
+ {
+ error(webxmlpath,"Attribute must exist with a valid value");
+ }
+ else if (!XSI_NS.equals(actualXsi))
+ {
+ String msg = String.format("Attribute mismatch expecting but found ",XSI_NS,actualXsi);
+ error(webxmlpath,msg);
+ }
+
+ if ((actualSchema == null) || (actualSchema == ""))
+ {
+ error(webxmlpath,"Attribute must exist with a valid value");
+ }
+ else
+ {
+ boolean valid = false;
+ for (ServletId id : schemaIds)
+ {
+ if (id.name.equals(actualSchema))
+ {
+ ids.add(id);
+ valid = true;
+ }
+ }
+
+ if (!valid)
+ {
+ String msg = String.format("Invalid schemaLocation value ",actualSchema);
+ error(webxmlpath,msg);
+ }
+ }
+
+ if ((actualVersion == null) || (actualVersion == ""))
+ {
+ error(webxmlpath,"Attribute must exist with a valid value");
+ }
+ else
+ {
+ boolean valid = false;
+ for (String version : validVersions)
+ {
+ if (version.equals(actualVersion))
+ {
+ ids.add(new ServletId(version,"version attribute",null));
+ valid = true;
+ }
+ }
+
+ if (!valid)
+ {
+ String msg = String.format("Invalid version value ",actualVersion);
+ error(webxmlpath,msg);
+ }
+ }
+ }
+ }
+ else
+ {
+ error(webxmlpath,"Invalid web.xml, root element expectd to be , but was <" + root.getTagName() + ">");
+ }
+
+ return ids;
+ }
+
+ private boolean hasAnyValue(String... values)
+ {
+ for (String value : values)
+ {
+ if ((value != null) && (value.length() > 0))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/asm/ASMUtil.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/asm/ASMUtil.java
new file mode 100644
index 00000000000..9267c57ea7f
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/asm/ASMUtil.java
@@ -0,0 +1,54 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules.asm;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.jetty.util.IO;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+
+/**
+ * Some simple utility methods for working with ASM in a common way.
+ */
+public class ASMUtil
+{
+ public static void visitClassFile(File classFile, ClassVisitor visitor, int flags) throws IOException
+ {
+ FileInputStream fin = null;
+ ClassReader creader = null;
+
+ try
+ {
+ fin = new FileInputStream(classFile);
+ creader = new ClassReader(fin);
+ creader.accept(visitor,flags);
+ }
+ finally
+ {
+ IO.close(fin);
+ }
+ }
+
+ public static void visitClass(InputStream stream, ClassVisitor visitor, int flags) throws IOException
+ {
+ ClassReader creader = new ClassReader(stream);
+ creader.accept(visitor,flags);
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/asm/AbstractClassVisitor.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/asm/AbstractClassVisitor.java
new file mode 100644
index 00000000000..1ec62be77d1
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/rules/asm/AbstractClassVisitor.java
@@ -0,0 +1,77 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules.asm;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * Abstact implementation of {@link ClassVisitor} to make asm use within Rules easier.
+ */
+public abstract class AbstractClassVisitor implements ClassVisitor
+{
+
+ public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
+ {
+ /* Override Ready */
+ }
+
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible)
+ {
+ /* Override Ready */
+ return null;
+ }
+
+ public void visitAttribute(Attribute attr)
+ {
+ /* Override Ready */
+ }
+
+ public void visitEnd()
+ {
+ /* Override Ready */
+ }
+
+ public FieldVisitor visitField(int access, String name, String desc, String signature, Object value)
+ {
+ /* Override Ready */
+ return null;
+ }
+
+ public void visitInnerClass(String name, String outerName, String innerName, int access)
+ {
+ /* Override Ready */
+ }
+
+ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
+ {
+ /* Override Ready */
+ return null;
+ }
+
+ public void visitOuterClass(String owner, String name, String desc)
+ {
+ /* Override Ready */
+ }
+
+ public void visitSource(String source, String debug)
+ {
+ /* Override Ready */
+ }
+}
diff --git a/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/support/PathGlob.java b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/support/PathGlob.java
new file mode 100644
index 00000000000..12dd2e16369
--- /dev/null
+++ b/jetty-webapp-verifier/src/main/java/org/eclipse/jetty/webapp/verifier/support/PathGlob.java
@@ -0,0 +1,58 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.support;
+
+public class PathGlob
+{
+ /**
+ * @return true if match.
+ */
+ public static boolean match(String pathSpec, String path) throws IllegalArgumentException
+ {
+ return match(pathSpec,path,false);
+ }
+
+ /**
+ * @return true if match.
+ */
+ public static boolean match(String pathSpec, String path, boolean noDefault) throws IllegalArgumentException
+ {
+ char c = pathSpec.charAt(0);
+ if (c == '/')
+ {
+ if (!noDefault && pathSpec.length() == 1 || pathSpec.equals(path))
+ return true;
+
+ if (isPathWildcardMatch(pathSpec,path))
+ return true;
+ }
+ else if (c == '*')
+ return path.regionMatches(path.length() - pathSpec.length() + 1,pathSpec,1,pathSpec.length() - 1);
+ return false;
+ }
+
+ private static boolean isPathWildcardMatch(String pathSpec, String path)
+ {
+ // For a spec of "/foo/*" match "/foo" , "/foo/..." but not "/foobar"
+ int cpl = pathSpec.length() - 2;
+ if (pathSpec.endsWith("/*") && path.regionMatches(0,pathSpec,0,cpl))
+ {
+ if (path.length() == cpl || '/' == path.charAt(cpl))
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/artifacts/.gitignore b/jetty-webapp-verifier/src/test/artifacts/.gitignore
new file mode 100644
index 00000000000..bf5aabfefa2
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/.gitignore
@@ -0,0 +1,11 @@
+target/
+.classpath
+.project
+.settings/
+*.tar.gz
+*.zip
+bsh*
+jruby*
+jython*
+groovy*
+*.swp
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-lib/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-lib/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-lib/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-lib/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-lib/pom.xml
new file mode 100644
index 00000000000..3d7601f2e1b
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-lib/pom.xml
@@ -0,0 +1,9 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-groovy-lib
+ jar
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Groovy Lib
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-lib/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-lib/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory
new file mode 100644
index 00000000000..8af8bb9660d
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-lib/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory
@@ -0,0 +1 @@
+org.codehaus.groovy.jsr223.GroovyScriptEngineFactory
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-lib/src/main/resources/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-lib/src/main/resources/README.txt
new file mode 100644
index 00000000000..906d0a4f50f
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-lib/src/main/resources/README.txt
@@ -0,0 +1,4 @@
+This dummy lib is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+It is neither a valid JAR file, nor contains valid Groovy implementations,
+in either scripting, source or binary form.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-webapp/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-webapp/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-webapp/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-webapp/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-webapp/pom.xml
new file mode 100644
index 00000000000..82ecbe4dad0
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-webapp/pom.xml
@@ -0,0 +1,22 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-groovy-webapp
+ war
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Groovy Webapp
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+
+ org.eclipse.jetty.tests
+ dummy-groovy-lib
+ 1.0-SNAPSHOT
+
+
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-webapp/src/main/webapp/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-webapp/src/main/webapp/README.txt
new file mode 100644
index 00000000000..f27b3191d90
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-webapp/src/main/webapp/README.txt
@@ -0,0 +1,4 @@
+This is a webapp is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+It is neither a valid WAR file, nor contains valid Groovy implementations,
+in either scripting, source or binary form.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..9f88c1f9632
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,7 @@
+
+
+
+ Archetype Created Web Application
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-webapp/src/main/webapp/dummy.groovy b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-webapp/src/main/webapp/dummy.groovy
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-webapp/src/main/webapp/other/lib.groovy b/jetty-webapp-verifier/src/test/artifacts/dummy-groovy-webapp/src/main/webapp/other/lib.groovy
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java11-lib/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-java11-lib/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java11-lib/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java11-lib/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-java11-lib/pom.xml
new file mode 100644
index 00000000000..302fcaf410b
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java11-lib/pom.xml
@@ -0,0 +1,20 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-java11-lib
+ jar
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Java1.1 Lib
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.1
+
+
+
+
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java11-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyLib.java b/jetty-webapp-verifier/src/test/artifacts/dummy-java11-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyLib.java
new file mode 100644
index 00000000000..d9a8203d145
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java11-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyLib.java
@@ -0,0 +1,27 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.testcase.verifier;
+
+/**
+ * Dummy class for testcase purposes.
+ */
+public class DummyLib
+{
+ public void dummyTestClassNotIntendedForUse()
+ {
+ /* not intended for use - only used for test case purposes */
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java11-lib/src/main/resources/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-java11-lib/src/main/resources/README.txt
new file mode 100644
index 00000000000..62c883903b9
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java11-lib/src/main/resources/README.txt
@@ -0,0 +1,3 @@
+This dummy lib is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+This JAR file is not for use outside of the /jetty-webapp-verifier/ test cases.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java12-lib/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-java12-lib/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java12-lib/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java12-lib/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-java12-lib/pom.xml
new file mode 100644
index 00000000000..c2b6cc3872d
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java12-lib/pom.xml
@@ -0,0 +1,20 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-java12-lib
+ jar
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Java1.2 Lib
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.2
+
+
+
+
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java12-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyUpdatedLib.java b/jetty-webapp-verifier/src/test/artifacts/dummy-java12-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyUpdatedLib.java
new file mode 100644
index 00000000000..30e35fa1e6e
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java12-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyUpdatedLib.java
@@ -0,0 +1,27 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.testcase.verifier;
+
+/**
+ * Dummy class for testcase purposes.
+ */
+public class DummyUpdatedLib
+{
+ public void dummyTestClassNotIntendedForUse()
+ {
+ /* not intended for use - only used for test case purposes */
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java12-lib/src/main/resources/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-java12-lib/src/main/resources/README.txt
new file mode 100644
index 00000000000..62c883903b9
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java12-lib/src/main/resources/README.txt
@@ -0,0 +1,3 @@
+This dummy lib is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+This JAR file is not for use outside of the /jetty-webapp-verifier/ test cases.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java13-lib/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-java13-lib/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java13-lib/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java13-lib/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-java13-lib/pom.xml
new file mode 100644
index 00000000000..29683ed739e
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java13-lib/pom.xml
@@ -0,0 +1,20 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-java13-lib
+ jar
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Java1.3 Lib
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.3
+
+
+
+
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java13-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyCurrentLib.java b/jetty-webapp-verifier/src/test/artifacts/dummy-java13-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyCurrentLib.java
new file mode 100644
index 00000000000..25f060c490d
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java13-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyCurrentLib.java
@@ -0,0 +1,27 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.testcase.verifier;
+
+/**
+ * Dummy class for testcase purposes.
+ */
+public class DummyCurrentLib
+{
+ public void dummyTestClassNotIntendedForUse()
+ {
+ /* not intended for use - only used for test case purposes */
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java13-lib/src/main/resources/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-java13-lib/src/main/resources/README.txt
new file mode 100644
index 00000000000..62c883903b9
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java13-lib/src/main/resources/README.txt
@@ -0,0 +1,3 @@
+This dummy lib is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+This JAR file is not for use outside of the /jetty-webapp-verifier/ test cases.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java14-lib/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-java14-lib/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java14-lib/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java14-lib/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-java14-lib/pom.xml
new file mode 100644
index 00000000000..f469224ddb7
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java14-lib/pom.xml
@@ -0,0 +1,20 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-java14-lib
+ jar
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Java1.4 Lib
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.4
+
+
+
+
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java14-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyFreshLib.java b/jetty-webapp-verifier/src/test/artifacts/dummy-java14-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyFreshLib.java
new file mode 100644
index 00000000000..b93f2cfd982
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java14-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyFreshLib.java
@@ -0,0 +1,27 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.testcase.verifier;
+
+/**
+ * Dummy class for testcase purposes.
+ */
+public class DummyFreshLib
+{
+ public void dummyTestClassNotIntendedForUse()
+ {
+ /* not intended for use - only used for test case purposes */
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java14-lib/src/main/resources/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-java14-lib/src/main/resources/README.txt
new file mode 100644
index 00000000000..62c883903b9
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java14-lib/src/main/resources/README.txt
@@ -0,0 +1,3 @@
+This dummy lib is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+This JAR file is not for use outside of the /jetty-webapp-verifier/ test cases.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java15-lib/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-java15-lib/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java15-lib/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java15-lib/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-java15-lib/pom.xml
new file mode 100644
index 00000000000..e12af4a27c4
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java15-lib/pom.xml
@@ -0,0 +1,20 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-java15-lib
+ jar
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Java1.5 Lib
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.5
+
+
+
+
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java15-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyLatestLib.java b/jetty-webapp-verifier/src/test/artifacts/dummy-java15-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyLatestLib.java
new file mode 100644
index 00000000000..be05acc114a
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java15-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyLatestLib.java
@@ -0,0 +1,27 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.testcase.verifier;
+
+/**
+ * Dummy class for testcase purposes.
+ */
+public class DummyLatestLib
+{
+ public void dummyTestClassNotIntendedForUse()
+ {
+ /* not intended for use - only used for test case purposes */
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java15-lib/src/main/resources/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-java15-lib/src/main/resources/README.txt
new file mode 100644
index 00000000000..62c883903b9
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java15-lib/src/main/resources/README.txt
@@ -0,0 +1,3 @@
+This dummy lib is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+This JAR file is not for use outside of the /jetty-webapp-verifier/ test cases.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java16-lib/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-java16-lib/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java16-lib/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java16-lib/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-java16-lib/pom.xml
new file mode 100644
index 00000000000..6ff141d7504
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java16-lib/pom.xml
@@ -0,0 +1,20 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-java16-lib
+ jar
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Java1.6 Lib
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.6
+
+
+
+
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java16-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyModernLib.java b/jetty-webapp-verifier/src/test/artifacts/dummy-java16-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyModernLib.java
new file mode 100644
index 00000000000..1e4c0352dcd
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java16-lib/src/main/java/org/eclipse/jetty/testcase/verifier/DummyModernLib.java
@@ -0,0 +1,27 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.testcase.verifier;
+
+/**
+ * Dummy class for testcase purposes.
+ */
+public class DummyModernLib
+{
+ public void dummyTestClassNotIntendedForUse()
+ {
+ /* not intended for use - only used for test case purposes */
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-java16-lib/src/main/resources/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-java16-lib/src/main/resources/README.txt
new file mode 100644
index 00000000000..62c883903b9
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-java16-lib/src/main/resources/README.txt
@@ -0,0 +1,3 @@
+This dummy lib is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+This JAR file is not for use outside of the /jetty-webapp-verifier/ test cases.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-javaversions-webapp/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-javaversions-webapp/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-javaversions-webapp/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-javaversions-webapp/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-javaversions-webapp/pom.xml
new file mode 100644
index 00000000000..c38b9b4035a
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-javaversions-webapp/pom.xml
@@ -0,0 +1,84 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-javaversions-webapp
+ war
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Java Versions Webapp
+
+
+ org.eclipse.jetty.tests
+ dummy-java11-lib
+ 1.0-SNAPSHOT
+
+
+ org.eclipse.jetty.tests
+ dummy-java12-lib
+ 1.0-SNAPSHOT
+
+
+ org.eclipse.jetty.tests
+ dummy-java13-lib
+ 1.0-SNAPSHOT
+
+
+ org.eclipse.jetty.tests
+ dummy-java14-lib
+ 1.0-SNAPSHOT
+
+
+ org.eclipse.jetty.tests
+ dummy-java15-lib
+ 1.0-SNAPSHOT
+
+
+ org.eclipse.jetty.tests
+ dummy-java16-lib
+ 1.0-SNAPSHOT
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ explode-jars-to-classes
+ process-resources
+
+ unpack-dependencies
+
+
+ **/*.class
+ ${project.build.directory}/${project.artifactId}-${project.version}/WEB-INF/classes
+
+
+
+
+
+
+
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-javaversions-webapp/src/main/webapp/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-javaversions-webapp/src/main/webapp/README.txt
new file mode 100644
index 00000000000..ba2e2233228
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-javaversions-webapp/src/main/webapp/README.txt
@@ -0,0 +1,4 @@
+This is a webapp is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+It is neither a valid WAR file, nor contains valid JRuby implementations,
+in either scripting, source or binary form.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-javaversions-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-javaversions-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..9f88c1f9632
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-javaversions-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,7 @@
+
+
+
+ Archetype Created Web Application
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-lib/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-lib/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-lib/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-lib/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-lib/pom.xml
new file mode 100644
index 00000000000..6fec6b3db33
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-lib/pom.xml
@@ -0,0 +1,9 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-jruby-lib
+ jar
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy JRuby Lib
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-lib/src/main/resources/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-lib/src/main/resources/README.txt
new file mode 100644
index 00000000000..73178116f20
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-lib/src/main/resources/README.txt
@@ -0,0 +1,4 @@
+This dummy lib is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+It is neither a valid JAR file, nor contains valid JRuby implementations,
+in either scripting, source or binary form.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-lib/src/main/resources/builtin/javasupport.rb b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-lib/src/main/resources/builtin/javasupport.rb
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/pom.xml
new file mode 100644
index 00000000000..1f04225a007
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/pom.xml
@@ -0,0 +1,22 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-jruby-webapp
+ war
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy JRuby Webapp
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+
+ org.eclipse.jetty.tests
+ dummy-jruby-lib
+ 1.0-SNAPSHOT
+
+
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/src/main/webapp/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/src/main/webapp/README.txt
new file mode 100644
index 00000000000..ba2e2233228
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/src/main/webapp/README.txt
@@ -0,0 +1,4 @@
+This is a webapp is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+It is neither a valid WAR file, nor contains valid JRuby implementations,
+in either scripting, source or binary form.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..9f88c1f9632
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,7 @@
+
+
+
+ Archetype Created Web Application
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/src/main/webapp/example.rb b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/src/main/webapp/example.rb
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/src/main/webapp/other/lib.rb b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/src/main/webapp/other/lib.rb
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/src/main/webapp/output.rhtml b/jetty-webapp-verifier/src/test/artifacts/dummy-jruby-webapp/src/main/webapp/output.rhtml
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/pom.xml
new file mode 100644
index 00000000000..28076c9057d
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/pom.xml
@@ -0,0 +1,9 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-jython-lib
+ jar
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Jython Lib
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/src/main/java/org/python/Version.java b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/src/main/java/org/python/Version.java
new file mode 100644
index 00000000000..bf6af0b796b
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/src/main/java/org/python/Version.java
@@ -0,0 +1,28 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+package org.python;
+
+/**
+ * Dummy class for testcase purposes.
+ */
+public class Version
+{
+ public void dummyTestClassNotIntendedForUse()
+ {
+ /* not intended for use - only used for test case purposes */
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/src/main/java/org/python/core/JythonInitializer.java b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/src/main/java/org/python/core/JythonInitializer.java
new file mode 100644
index 00000000000..c9f720aa1d1
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/src/main/java/org/python/core/JythonInitializer.java
@@ -0,0 +1,28 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+package org.python.core;
+
+/**
+ * Dummy class for testcase purposes.
+ */
+public class JythonInitializer
+{
+ public void dummyTestClassNotIntendedForUse()
+ {
+ /* not intended for use - only used for test case purposes */
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/src/main/java/org/python/util/Generic.java b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/src/main/java/org/python/util/Generic.java
new file mode 100644
index 00000000000..b692781f8e6
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/src/main/java/org/python/util/Generic.java
@@ -0,0 +1,28 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+package org.python.util;
+
+/**
+ * Dummy class for testcase purposes.
+ */
+public class Generic
+{
+ public void dummyTestClassNotIntendedForUse()
+ {
+ /* not intended for use - only used for test case purposes */
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/src/main/resources/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/src/main/resources/README.txt
new file mode 100644
index 00000000000..bc6accef097
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-lib/src/main/resources/README.txt
@@ -0,0 +1,4 @@
+This dummy lib is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+It is neither a valid JAR file, nor contains valid Jython implementations,
+in either scripting, source or binary form.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/pom.xml
new file mode 100644
index 00000000000..c37cae0b537
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/pom.xml
@@ -0,0 +1,22 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-jython-webapp
+ war
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Jython Webapp
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+
+ org.eclipse.jetty.tests
+ dummy-jython-lib
+ 1.0-SNAPSHOT
+
+
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/src/main/webapp/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/src/main/webapp/README.txt
new file mode 100644
index 00000000000..ba2e2233228
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/src/main/webapp/README.txt
@@ -0,0 +1,4 @@
+This is a webapp is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+It is neither a valid WAR file, nor contains valid JRuby implementations,
+in either scripting, source or binary form.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..9f88c1f9632
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,7 @@
+
+
+
+ Archetype Created Web Application
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/src/main/webapp/dummy.py b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/src/main/webapp/dummy.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/src/main/webapp/dummy.pyc b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/src/main/webapp/dummy.pyc
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/src/main/webapp/other/lib.py b/jetty-webapp-verifier/src/test/artifacts/dummy-jython-webapp/src/main/webapp/other/lib.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/pom.xml
new file mode 100644
index 00000000000..af7f08ef7c0
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/pom.xml
@@ -0,0 +1,17 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-nativeaccess-webapp
+ war
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Native Access Webapp
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/README.txt
new file mode 100644
index 00000000000..ba2e2233228
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/README.txt
@@ -0,0 +1,4 @@
+This is a webapp is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+It is neither a valid WAR file, nor contains valid JRuby implementations,
+in either scripting, source or binary form.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..9f88c1f9632
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,7 @@
+
+
+
+ Archetype Created Web Application
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/dummy.exe b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/dummy.exe
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/dummy.o b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/dummy.o
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/dummy.so b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/dummy.so
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/executable b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/executable
new file mode 100755
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/other/lib.dll b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/other/lib.dll
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/other/lib.o b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/other/lib.o
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/other/lib.so b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/other/lib.so
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/other/lib.so.0.5.7 b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/other/lib.so.0.5.7
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/other/lib.so.1 b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/other/lib.so.1
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/other/lib.so.5 b/jetty-webapp-verifier/src/test/artifacts/dummy-nativeaccess-webapp/src/main/webapp/other/lib.so.5
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-scm-lib/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-scm-lib/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-scm-lib/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-scm-lib/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-scm-lib/pom.xml
new file mode 100644
index 00000000000..992cccb5e29
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-scm-lib/pom.xml
@@ -0,0 +1,84 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-scm-lib
+ pom
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy SCM Lib
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+
+
+ create-scm-files
+ generate-resources
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+
+
+ attach-scm-lib
+ package
+
+ attach-artifact
+
+
+
+
+ ${project.build.directory}/${project.artifactId}-${project.version}.jar
+ jar
+
+
+
+
+
+
+
+
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-scm-lib/src/main/resources/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-scm-lib/src/main/resources/README.txt
new file mode 100644
index 00000000000..62c883903b9
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-scm-lib/src/main/resources/README.txt
@@ -0,0 +1,3 @@
+This dummy lib is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+This JAR file is not for use outside of the /jetty-webapp-verifier/ test cases.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-scm-webapp/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-scm-webapp/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-scm-webapp/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-scm-webapp/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-scm-webapp/pom.xml
new file mode 100644
index 00000000000..f2a20367d62
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-scm-webapp/pom.xml
@@ -0,0 +1,116 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-scm-webapp
+ pom
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy SCM Webapp
+
+
+ org.eclipse.jetty.tests
+ dummy-scm-lib
+ 1.0-SNAPSHOT
+
+
+
+ ${project.build.directory}/generated-webapp
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+
+
+ create-scm-files
+ generate-resources
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ create-war
+ package
+
+ run
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ copy-deps
+ process-resources
+
+ copy-dependencies
+
+
+ ${war_work_dir}/WEB-INF/lib
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+
+
+ attach-scm-lib
+ process-resources
+
+ attach-artifact
+
+
+
+
+ ${project.build.directory}/${project.artifactId}-${project.version}.war
+ war
+
+
+
+
+
+
+
+
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-scm-webapp/src/main/webapp/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-scm-webapp/src/main/webapp/README.txt
new file mode 100644
index 00000000000..ba2e2233228
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-scm-webapp/src/main/webapp/README.txt
@@ -0,0 +1,4 @@
+This is a webapp is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+It is neither a valid WAR file, nor contains valid JRuby implementations,
+in either scripting, source or binary form.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-scm-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-scm-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..9f88c1f9632
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-scm-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,7 @@
+
+
+
+ Archetype Created Web Application
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-servlet23-webapp/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet23-webapp/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet23-webapp/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-servlet23-webapp/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet23-webapp/pom.xml
new file mode 100644
index 00000000000..fb11c34596d
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet23-webapp/pom.xml
@@ -0,0 +1,9 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-servlet23-webapp
+ war
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Servlet 2.3 Webapp
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-servlet23-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet23-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..8e33e5df0f9
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet23-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,7 @@
+
+
+
+ Web Application with Servlet 2.3
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-servlet24-webapp/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet24-webapp/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet24-webapp/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-servlet24-webapp/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet24-webapp/pom.xml
new file mode 100644
index 00000000000..124277c0623
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet24-webapp/pom.xml
@@ -0,0 +1,9 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-servlet24-webapp
+ war
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Servlet 2.4 Webapp
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-servlet24-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet24-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..84d45f90325
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet24-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ Web Application for Servlet 2.4
+
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-servlet25-webapp/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet25-webapp/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet25-webapp/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-servlet25-webapp/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet25-webapp/pom.xml
new file mode 100644
index 00000000000..53f45ba3b9c
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet25-webapp/pom.xml
@@ -0,0 +1,9 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-servlet25-webapp
+ war
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Servlet 2.5 Webapp
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-servlet25-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet25-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..d06d132c1c6
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-servlet25-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,9 @@
+
+
+
+ Web Application for Servlet 2.5
+
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed1-webapp/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed1-webapp/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed1-webapp/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed1-webapp/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed1-webapp/pom.xml
new file mode 100644
index 00000000000..60dd7e54cf4
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed1-webapp/pom.xml
@@ -0,0 +1,9 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-servletmixed1-webapp
+ war
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Servlet Mixed 2.3+2.4 Webapp
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed1-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed1-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..7380f0f453e
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed1-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,9 @@
+
+
+
+
+ Web Application with Mixed Servlet 2.3+2.4
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed2-webapp/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed2-webapp/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed2-webapp/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed2-webapp/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed2-webapp/pom.xml
new file mode 100644
index 00000000000..28905a1b9f1
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed2-webapp/pom.xml
@@ -0,0 +1,9 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-servletmixed2-webapp
+ war
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Servlet Mixed 2.3+2.5 Webapp
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed2-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed2-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..655af0b40d0
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-servletmixed2-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ Web Application with Mixed Servlet 2.3+2.5
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/.gitignore b/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/.gitignore
new file mode 100644
index 00000000000..8baee4f43cf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/.gitignore
@@ -0,0 +1,8 @@
+target/
+.classpath
+.project
+.settings
+*.swp
+*.log
+*.patch
+*.diff
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/pom.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/pom.xml
new file mode 100644
index 00000000000..419a4ce698f
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/pom.xml
@@ -0,0 +1,17 @@
+
+ 4.0.0
+ org.eclipse.jetty.tests
+ dummy-shellscripts-webapp
+ war
+ 1.0-SNAPSHOT
+ Jetty :: Webapp Verifier :: Dummy Shellscripts Webapp
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/README.txt b/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/README.txt
new file mode 100644
index 00000000000..f9b06ce72d7
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/README.txt
@@ -0,0 +1,4 @@
+This is a webapp is a TEST RESOURCE, used by the jetty project at http://www.eclipse.org/jetty/
+
+It is neither a valid WAR file, nor contains valid Shell Script implementations,
+in either scripting, source or binary form.
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..9f88c1f9632
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,7 @@
+
+
+
+ Archetype Created Web Application
+
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/dummy.bat b/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/dummy.bat
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/dummy.cmd b/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/dummy.cmd
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/dummy.sh b/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/dummy.sh
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/dummy.vbs b/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/dummy.vbs
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/other/lib.bat b/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/other/lib.bat
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/other/lib.cmd b/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/other/lib.cmd
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/other/lib.sh b/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/other/lib.sh
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/other/lib.vbs b/jetty-webapp-verifier/src/test/artifacts/dummy-shellscripts-webapp/src/main/webapp/other/lib.vbs
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-webapp-verifier/src/test/artifacts/pom.xml b/jetty-webapp-verifier/src/test/artifacts/pom.xml
new file mode 100644
index 00000000000..2378b4f5d16
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/artifacts/pom.xml
@@ -0,0 +1,36 @@
+
+ 4.0.0
+
+ org.eclipse.jetty
+ jetty-project
+ 7.0.0.RC3-SNAPSHOT
+
+ org.eclipse.jetty.tests
+ jetty-webapp-verifier-artifacts
+ Jetty :: Webapp Verifier :: Artifacts Parent
+ pom
+
+ dummy-jruby-lib
+ dummy-jython-lib
+ dummy-groovy-lib
+ dummy-jruby-webapp
+ dummy-jython-webapp
+ dummy-groovy-webapp
+ dummy-shellscripts-webapp
+ dummy-nativeaccess-webapp
+ dummy-java11-lib
+ dummy-java12-lib
+ dummy-java13-lib
+ dummy-java14-lib
+ dummy-java15-lib
+ dummy-java16-lib
+ dummy-javaversions-webapp
+ dummy-scm-lib
+ dummy-scm-webapp
+ dummy-servlet23-webapp
+ dummy-servlet24-webapp
+ dummy-servlet25-webapp
+ dummy-servletmixed1-webapp
+ dummy-servletmixed2-webapp
+
+
diff --git a/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/AbstractTestWebappVerifier.java b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/AbstractTestWebappVerifier.java
new file mode 100644
index 00000000000..a3dec9785d8
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/AbstractTestWebappVerifier.java
@@ -0,0 +1,46 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+import java.io.File;
+import junit.framework.TestCase;
+
+import org.eclipse.jetty.util.IO;
+
+public class AbstractTestWebappVerifier extends TestCase
+{
+ protected File getTestWorkDir()
+ {
+ File workDir = MavenTestingUtils.toTargetFile("test-work-dir");
+ if (!workDir.exists())
+ {
+ workDir.mkdirs();
+ }
+ File testSpecificDir = new File(workDir,this.getClass().getSimpleName() + "_" + getName());
+ if (testSpecificDir.exists())
+ {
+ IO.delete(testSpecificDir);
+ }
+ testSpecificDir.mkdirs();
+ return testSpecificDir;
+ }
+
+ protected RuleSet loadRuleSet(String name) throws Exception
+ {
+ File xmlFile = MavenTestingUtils.getTestResourceFile(name);
+ return RuleSet.load(xmlFile.toURL());
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/CountingRule.java b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/CountingRule.java
new file mode 100644
index 00000000000..a9f055a691d
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/CountingRule.java
@@ -0,0 +1,126 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+import java.io.File;
+import java.util.jar.JarFile;
+import java.util.zip.ZipFile;
+
+public class CountingRule extends AbstractRule
+{
+ public int countWebappStart = 0;
+ public int countDirStart = 0;
+ public int countFile = 0;
+ public int countDirEnd = 0;
+ public int countWebInfClassesStart = 0;
+ public int countWebInfClass = 0;
+ public int countWebInfClassResource = 0;
+ public int countWebInfClassesEnd = 0;
+ public int countWebInfLibStart = 0;
+ public int countWebInfLibJar = 0;
+ public int countWebInfLibZip = 0;
+ public int countWebInfLibEnd = 0;
+ public int countWebappEnd = 0;
+
+ public String getDescription()
+ {
+ return "TestCase only rule, that counts hits to visitors";
+ }
+
+ public String getName()
+ {
+ return "test-counting";
+ }
+
+ @Override
+ public void visitDirectoryEnd(String path, File dir)
+ {
+ countDirEnd++;
+ }
+
+ @Override
+ public void visitDirectoryStart(String path, File dir)
+ {
+ countDirStart++;
+ }
+
+ @Override
+ public void visitFile(String path, File dir, File file)
+ {
+ countFile++;
+ }
+
+ @Override
+ public void visitWebappEnd(String path, File dir)
+ {
+ countWebappEnd++;
+ }
+
+ @Override
+ public void visitWebappStart(String path, File dir)
+ {
+ super.visitWebappStart(path,dir);
+ countWebappStart++;
+ }
+
+ @Override
+ public void visitWebInfClass(String path, String className, File classFile)
+ {
+ countWebInfClass++;
+ }
+
+ @Override
+ public void visitWebInfClassesEnd(String path, File dir)
+ {
+ countWebInfClassesEnd++;
+ }
+
+ @Override
+ public void visitWebInfClassesStart(String path, File dir)
+ {
+ countWebInfClassesStart++;
+ }
+
+ @Override
+ public void visitWebInfClassResource(String path, String resourcePath, File resourceFile)
+ {
+ countWebInfClassResource++;
+ }
+
+ @Override
+ public void visitWebInfLibEnd(String path, File dir)
+ {
+ countWebInfLibEnd++;
+ }
+
+ @Override
+ public void visitWebInfLibJar(String path, File archive, JarFile jar)
+ {
+ countWebInfLibJar++;
+ }
+
+ @Override
+ public void visitWebInfLibStart(String path, File dir)
+ {
+ countWebInfLibStart++;
+ }
+
+ @Override
+ public void visitWebInfLibZip(String path, File archive, ZipFile zip)
+ {
+ countWebInfLibZip++;
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/MavenTestingUtils.java b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/MavenTestingUtils.java
new file mode 100644
index 00000000000..6691f717e43
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/MavenTestingUtils.java
@@ -0,0 +1,166 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import org.eclipse.jetty.util.IO;
+
+/**
+ * Common utility methods for working with JUnit tests cases in a maven friendly way.
+ */
+public class MavenTestingUtils
+{
+ private static File basedir;
+ private static File testResourcesDir;
+ private static File targetDir;
+
+ public static File getBasedir()
+ {
+ if (basedir == null)
+ {
+ String cwd = System.getProperty("basedir");
+
+ if (cwd == null)
+ {
+ cwd = System.getProperty("user.dir");
+ }
+
+ basedir = new File(cwd);
+ }
+
+ return basedir;
+ }
+
+ /**
+ * Get the directory to the /target directory for this project.
+ *
+ * @return the directory path to the target directory.
+ */
+ public static File getTargetDir()
+ {
+ if (targetDir == null)
+ {
+ targetDir = new File(basedir,"target");
+ PathAssert.assertDirExists("Target Dir",targetDir);
+ }
+ return targetDir;
+ }
+
+ /**
+ * Get a file from the src/test/resource directory.
+ *
+ * @param name
+ * the name of the path to get (it must exist as a file)
+ * @return the file in src/test/resource
+ */
+ public static File getTestResourceFile(String name)
+ {
+ File file = new File(getTestResourcesDir(),name);
+ PathAssert.assertFileExists("Test Resource File",file);
+ return file;
+ }
+
+ /**
+ * Get a dir from the src/test/resource directory.
+ *
+ * @param name
+ * the name of the path to get (it must exist as a dir)
+ * @return the dir in src/test/resource
+ */
+ public static File getTestResourceDir(String name)
+ {
+ File dir = new File(getTestResourcesDir(),name);
+ PathAssert.assertDirExists("Test Resource Dir",dir);
+ return dir;
+ }
+
+ /**
+ * Get a path resource (File or Dir) from the src/test/resource directory.
+ *
+ * @param name
+ * the name of the path to get (it must exist)
+ * @return the path in src/test/resource
+ */
+ public static File getTestResourcePath(String name)
+ {
+ File path = new File(getTestResourcesDir(),name);
+ PathAssert.assertExists("Test Resource Path",path);
+ return path;
+ }
+
+ /**
+ * Get the directory to the src/test/resource directory
+ *
+ * @return the directory {@link File} to the src/test/resources directory
+ */
+ public static File getTestResourcesDir()
+ {
+ if (testResourcesDir == null)
+ {
+ testResourcesDir = new File(basedir,"src/test/resources".replace("/",File.separator));
+ PathAssert.assertDirExists("Test Resources Dir",testResourcesDir);
+ }
+ return testResourcesDir;
+ }
+
+ /**
+ * Create a {@link File} object for a path in the /target directory.
+ *
+ * @param path
+ * the path desired, no validation of existence is performed.
+ * @return the File to the path.
+ */
+ public static File toTargetFile(String path)
+ {
+ return new File(getTargetDir(),path.replace("/",File.separator));
+ }
+
+ /**
+ * Read the contents of a file into a String and return it.
+ *
+ * @param file
+ * the file to read.
+ * @return the contents of the file.
+ * @throws IOException
+ * if unable to read the file.
+ */
+ public static String readToString(File file) throws IOException
+ {
+ FileReader reader = null;
+ try
+ {
+ reader = new FileReader(file);
+ return IO.toString(reader);
+ }
+ finally
+ {
+ IO.close(reader);
+ }
+ }
+
+ public static File toTargetTestingDir()
+ {
+ File dir = new File(getTargetDir(),"testing");
+ if (!dir.exists())
+ {
+ dir.mkdirs();
+ }
+ return dir;
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/PathAssert.java b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/PathAssert.java
new file mode 100644
index 00000000000..ff3012bc930
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/PathAssert.java
@@ -0,0 +1,40 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+import java.io.File;
+
+import junit.framework.Assert;
+
+public class PathAssert
+{
+ public static void assertDirExists(String msg, File path)
+ {
+ assertExists(msg,path);
+ Assert.assertTrue(msg + " path should be a Dir : " + path.getAbsolutePath(),path.isDirectory());
+ }
+
+ public static void assertFileExists(String msg, File path)
+ {
+ assertExists(msg,path);
+ Assert.assertTrue(msg + " path should be a File : " + path.getAbsolutePath(),path.isFile());
+ }
+
+ public static void assertExists(String msg, File path)
+ {
+ Assert.assertTrue(msg + " path should exist: " + path.getAbsolutePath(),path.exists());
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/RuleAssert.java b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/RuleAssert.java
new file mode 100644
index 00000000000..5b9f25ba33f
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/RuleAssert.java
@@ -0,0 +1,184 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import junit.framework.Assert;
+
+import org.eclipse.jetty.util.IO;
+
+/**
+ * Rule based assertions.
+ */
+public class RuleAssert
+{
+ private static Pattern expectedViolationPattern;
+
+ /**
+ *
+ * Perform a static Rule assertion.
+ *
+ *
+ *
+ * You will need the following files.
+ *
+ *
+ *
+ * src/test/resources/${prefix}.setup.txt
- contains 1 line, which is the src/test/resources
+ * relative path to the webapp you want to test, (it can be a WAR file, or an exploded webapp directory
+ *
+ * src/test/resources/${prefix}.config.xml
- contains an XMLConfiguration suitable XML file for
+ * loading into a RuleSet. Represents the configuration that will be used for this test.
+ *
+ * src/test/resources/${prefix}.expectations.txt
- contains a list of expected Violations (1
+ * violation per line), with the expected values pipe "|"
delimited. Example: pattern is
+ * "${severity}|${path}|${detail}"
, where a representative line
+ * "ERROR|/WEB-INF|Missing required web.xml"
would mean a violation of type {@link Severity#ERROR},
+ * with path "/WEB-INF"
, and detail "Missing required web.xml"
+ *
+ *
+ * @param prefix
+ * the prefix of the integration files in src/test/resources that you want to use.
+ * @throws Exception
+ */
+ public static void assertIntegration(String prefix) throws Exception
+ {
+ // Load the 3 integration files.
+ File setupFile = MavenTestingUtils.getTestResourceFile(prefix + ".setup.txt");
+ File configFile = MavenTestingUtils.getTestResourceFile(prefix + ".config.xml");
+ File expectationFile = MavenTestingUtils.getTestResourceFile(prefix + ".expectations.txt");
+
+ // Establish Webapp to use
+ String webappName = MavenTestingUtils.readToString(setupFile).trim();
+ File webappPath = MavenTestingUtils.getTestResourcePath(webappName);
+ URI webappURI = webappPath.toURI();
+
+ // Load RuleSet configuration
+ RuleSet ruleset = RuleSet.load(configFile);
+
+ // Run Verification
+ WebappVerifier verifier = ruleset.createWebappVerifier(webappURI);
+ verifier.setWorkDir(MavenTestingUtils.toTargetTestingDir());
+ verifier.visitAll();
+
+ // Compare violations
+ assertViolations(loadExpectedViolations(expectationFile),verifier.getViolations());
+ }
+
+ public static void assertViolations(Collection expectedColl, Collection actualColl)
+ {
+ List actualViolations = new ArrayList(actualColl);
+ List expectedViolations = new ArrayList(expectedColl);
+
+ Collections.sort(actualViolations,ViolationComparator.getInstance());
+ Collections.sort(expectedViolations,ViolationComparator.getInstance());
+
+ // Compare expected vs actual
+ if (expectedViolations.size() != actualViolations.size())
+ {
+ dumpViolations("Expected",expectedViolations);
+ dumpViolations("Actual",actualViolations);
+ Assert.assertEquals("Violation count",expectedViolations.size(),actualViolations.size());
+ }
+
+ for (int i = 0, n = expectedViolations.size(); i < n; i++)
+ {
+ Violation expected = expectedViolations.get(i);
+ Violation actual = actualViolations.get(i);
+
+ Assert.assertEquals("Violation[" + i + "].path",expected.getPath(),actual.getPath());
+ Assert.assertEquals("Violation[" + i + "].detail",expected.getDetail(),actual.getDetail());
+ Assert.assertEquals("Violation[" + i + "].severity",expected.getSeverity(),actual.getSeverity());
+ // TODO: add check on Violation.throwable
+ // TODO: add check on Violation.verifierId
+ // TODO: add check on Violation.verifierClass
+ }
+ }
+
+ public static void dumpViolations(String msg, Collection violations)
+ {
+ System.out.println();
+ System.out.printf("/* Violations Dump: %s */%n",msg);
+ for (Violation violation : violations)
+ {
+ System.out.println(violation.toDelimString());
+ }
+ }
+
+ public static Collection loadExpectedViolations(File expectationFile) throws IOException
+ {
+ FileReader reader = null;
+ BufferedReader buf = null;
+ try
+ {
+ List ret = new ArrayList();
+ reader = new FileReader(expectationFile);
+ buf = new BufferedReader(reader);
+
+ String line;
+
+ while ((line = buf.readLine()) != null)
+ {
+ if (line.charAt(0) == '#')
+ {
+ // a comment.
+ continue;
+ }
+
+ // Parse line
+ Violation violation = parseViolation(line);
+
+ Assert.assertNotNull("Unable to parse expected violation line: " + line,violation);
+
+ // Add to list
+ ret.add(violation);
+ }
+
+ return ret;
+ }
+ finally
+ {
+ IO.close(buf);
+ IO.close(reader);
+ }
+ }
+
+ protected static Violation parseViolation(String line)
+ {
+ expectedViolationPattern = Pattern.compile("^([^|]*)\\|([^|]*)\\|(.*)$");
+ Matcher mat = expectedViolationPattern.matcher(line);
+ if (mat.matches())
+ {
+ Severity severity = Severity.parse(mat.group(1));
+ String path = mat.group(2);
+ String detail = mat.group(3);
+ return new Violation(severity,path,detail);
+ }
+ else
+ return null;
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/RuleAssertTest.java b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/RuleAssertTest.java
new file mode 100644
index 00000000000..cc3d837bb18
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/RuleAssertTest.java
@@ -0,0 +1,33 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+import junit.framework.TestCase;
+
+public class RuleAssertTest extends TestCase
+{
+ public void testParseLine()
+ {
+ Violation v;
+
+ v = RuleAssert.parseViolation("ERROR|/WEB-INF|Missing web.xml");
+
+ assertNotNull("Verifier should not be null",v);
+ assertEquals("Verifier.severity",Severity.ERROR,v.getSeverity());
+ assertEquals("Verifier.path","/WEB-INF",v.getPath());
+ assertEquals("Verifier.detail","Missing web.xml",v.getDetail());
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/RuleSetTest.java b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/RuleSetTest.java
new file mode 100644
index 00000000000..5c19012f12f
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/RuleSetTest.java
@@ -0,0 +1,36 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+import org.eclipse.jetty.webapp.verifier.rules.ForbiddenContentsRule;
+import org.eclipse.jetty.webapp.verifier.rules.RequiredContentsRule;
+
+public class RuleSetTest extends AbstractTestWebappVerifier
+{
+ public void testLoad() throws Exception
+ {
+ RuleSet suite = loadRuleSet("basic-ruleset.xml");
+ assertNotNull("Should have a valid RuleSet.",suite);
+
+ assertNotNull("verifier list should not be null",suite.getRules());
+ assertEquals("Should have 2 verifier",2,suite.getRules().size());
+
+ Rule verifier = suite.getRules().get(0);
+ assertEquals("Verifier[0]",ForbiddenContentsRule.class.getName(),verifier.getClass().getName());
+ verifier = suite.getRules().get(1);
+ assertEquals("Verifier[1]",RequiredContentsRule.class.getName(),verifier.getClass().getName());
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/WebappVerifierTest.java b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/WebappVerifierTest.java
new file mode 100644
index 00000000000..a5301492a31
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/WebappVerifierTest.java
@@ -0,0 +1,63 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier;
+
+import java.util.Collection;
+
+public class WebappVerifierTest extends AbstractTestWebappVerifier
+{
+ public void testVerifierVisitation() throws Exception
+ {
+ CountingRule counts = new CountingRule();
+
+ // Create Webapp Specific Verifier from Verifier Suite
+ WebappVerifier verifier = new WebappVerifier(MavenTestingUtils.toTargetFile("war-files/test-webapp-logging-java.war").toURI());
+ verifier.addRule(counts);
+ verifier.setWorkDir(getTestWorkDir());
+
+ // Run the verification.
+ verifier.visitAll();
+
+ // Collect the violations
+ Collection violations = verifier.getViolations();
+ assertNotNull("Should never have a null set of Violations",violations);
+ assertEquals("No violations caused",0,violations.size());
+
+ // Ensure each visitor was visited according to real contents of WAR
+ assertEquals("Counts.webappStart",1,counts.countWebappStart);
+ assertEquals("Counts.countWebappEnd",1,counts.countWebappEnd);
+
+ // Visits in Directory
+ assertEquals("Counts.countDirStart",12,counts.countDirStart);
+ assertEquals("Counts.countFile",6,counts.countFile);
+ assertEquals("Counts.countDirEnd",12,counts.countDirEnd);
+ assertEquals("Counts.countDir (Start == End)",counts.countDirStart,counts.countDirEnd);
+
+ // Visits in WEB-INF/classes
+ assertEquals("Counts.countWebInfClassesStart",1,counts.countWebInfClassesStart);
+ assertEquals("Counts.countWebInfClass",1,counts.countWebInfClass);
+ assertEquals("Counts.countWebInfClassResource",1,counts.countWebInfClassResource);
+ assertEquals("Counts.countWebInfClassesEnd",1,counts.countWebInfClassesEnd);
+ assertEquals("Counts.countWebInfClasses (Start == End)",counts.countWebInfClassesStart,counts.countWebInfClassesEnd);
+
+ // Visits in WEB-INF/lib
+ assertEquals("Counts.countWebInfLibStart",0,counts.countWebInfLibStart);
+ assertEquals("Counts.countWebInfLibJar",0,counts.countWebInfLibJar);
+ assertEquals("Counts.countWebInfLibZip",0,counts.countWebInfLibZip);
+ assertEquals("Counts.countWebInfLibEnd",0,counts.countWebInfLibEnd);
+ assertEquals("Counts.countWebInfLib (Start == End)",counts.countWebInfLibStart,counts.countWebInfLibEnd);
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/JarSignatureRuleTest.java b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/JarSignatureRuleTest.java
new file mode 100644
index 00000000000..10917769d99
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/JarSignatureRuleTest.java
@@ -0,0 +1,39 @@
+// ========================================================================
+// Copyright (c) 2009-2009 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import org.eclipse.jetty.webapp.verifier.AbstractTestWebappVerifier;
+import org.eclipse.jetty.webapp.verifier.MavenTestingUtils;
+import org.eclipse.jetty.webapp.verifier.WebappVerifier;
+import org.eclipse.jetty.webapp.verifier.rules.JarSignatureRule;
+
+/**
+ * Tests against {@link JarSignatureRule}
+ */
+public class JarSignatureRuleTest extends AbstractTestWebappVerifier
+{
+ public void testSimpleVerify() throws Exception
+ {
+ JarSignatureRule signed = new JarSignatureRule();
+
+ // Create Webapp Specific Verifier from Verifier Suite
+ WebappVerifier verifier = new WebappVerifier(MavenTestingUtils.toTargetFile("test-classes/webapps/signed-jar-test-webapp.war").toURI());
+ verifier.addRule( signed );
+ verifier.setWorkDir( getTestWorkDir() );
+
+ // Run the verification.
+ verifier.visitAll();
+
+ assertTrue( verifier.getViolations().size() == 0 );
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/JavaSupportLevelRuleTest.java b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/JavaSupportLevelRuleTest.java
new file mode 100644
index 00000000000..bf1561b6483
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/JavaSupportLevelRuleTest.java
@@ -0,0 +1,18 @@
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import org.eclipse.jetty.webapp.verifier.RuleAssert;
+
+import junit.framework.TestCase;
+
+public class JavaSupportLevelRuleTest extends TestCase
+{
+ public void testJava15() throws Exception
+ {
+ RuleAssert.assertIntegration("java_level_1.5");
+ }
+
+ public void testJava14() throws Exception
+ {
+ RuleAssert.assertIntegration("java_level_1.4");
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/NoNativeRuleTest.java b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/NoNativeRuleTest.java
new file mode 100644
index 00000000000..f082411392e
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/NoNativeRuleTest.java
@@ -0,0 +1,13 @@
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import org.eclipse.jetty.webapp.verifier.RuleAssert;
+
+import junit.framework.TestCase;
+
+public class NoNativeRuleTest extends TestCase
+{
+ public void testNoNative() throws Exception
+ {
+ RuleAssert.assertIntegration("no_native");
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/NoScriptingRuleTest.java b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/NoScriptingRuleTest.java
new file mode 100644
index 00000000000..c6c8bf32ec6
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/NoScriptingRuleTest.java
@@ -0,0 +1,42 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import org.eclipse.jetty.webapp.verifier.AbstractTestWebappVerifier;
+import org.eclipse.jetty.webapp.verifier.RuleAssert;
+
+public class NoScriptingRuleTest extends AbstractTestWebappVerifier
+{
+ public void testJRubyConfiguration() throws Exception
+ {
+ RuleAssert.assertIntegration("no_scripting_jruby");
+ }
+
+ public void testJythonConfiguration() throws Exception
+ {
+ RuleAssert.assertIntegration("no_scripting_jython");
+ }
+
+ public void testGroovyConfiguration() throws Exception
+ {
+ RuleAssert.assertIntegration("no_scripting_groovy");
+ }
+
+ public void testShellConfiguration() throws Exception
+ {
+ RuleAssert.assertIntegration("no_scripting_shell");
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/NoSourceControlRuleTest.java b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/NoSourceControlRuleTest.java
new file mode 100644
index 00000000000..f1716cbf59d
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/NoSourceControlRuleTest.java
@@ -0,0 +1,31 @@
+// ========================================================================
+// Copyright (c) Webtide LLC
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import org.eclipse.jetty.webapp.verifier.RuleAssert;
+
+import junit.framework.TestCase;
+
+/**
+ * NoSourceControlRuleTest
+ */
+public class NoSourceControlRuleTest extends TestCase
+{
+ public void testNoScm() throws Exception
+ {
+ RuleAssert.assertIntegration("no_scm");
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/ServletSupportLevelRuleTest.java b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/ServletSupportLevelRuleTest.java
new file mode 100644
index 00000000000..756a45aac0b
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/java/org/eclipse/jetty/webapp/verifier/rules/ServletSupportLevelRuleTest.java
@@ -0,0 +1,33 @@
+package org.eclipse.jetty.webapp.verifier.rules;
+
+import org.eclipse.jetty.webapp.verifier.RuleAssert;
+
+import junit.framework.TestCase;
+
+public class ServletSupportLevelRuleTest extends TestCase
+{
+ public void testServlet23Rule() throws Exception
+ {
+ RuleAssert.assertIntegration("servlet_level_2.3");
+ }
+
+ public void testServlet24Rule() throws Exception
+ {
+ RuleAssert.assertIntegration("servlet_level_2.4");
+ }
+
+ public void testServlet25Rule() throws Exception
+ {
+ RuleAssert.assertIntegration("servlet_level_2.5");
+ }
+
+ public void testServletMixed23n24Rule() throws Exception
+ {
+ RuleAssert.assertIntegration("servlet_level_mixed_2.3_2.4");
+ }
+
+ public void testServletMixed23n25Rule() throws Exception
+ {
+ RuleAssert.assertIntegration("servlet_level_mixed_2.3_2.5");
+ }
+}
diff --git a/jetty-webapp-verifier/src/test/resources/basic-ruleset.xml b/jetty-webapp-verifier/src/test/resources/basic-ruleset.xml
new file mode 100644
index 00000000000..2ac16f95f35
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/basic-ruleset.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+ -
+
+
+ *.jsp
+
+
+
+ -
+
+
+ /copyright.jsp
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/content-verifier/WEB-INF/web.xml b/jetty-webapp-verifier/src/test/resources/content-verifier/WEB-INF/web.xml
new file mode 100644
index 00000000000..12bbf745ce3
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/content-verifier/WEB-INF/web.xml
@@ -0,0 +1 @@
+
diff --git a/jetty-webapp-verifier/src/test/resources/java_level_1.4.config.xml b/jetty-webapp-verifier/src/test/resources/java_level_1.4.config.xml
new file mode 100644
index 00000000000..aa26dd24aa7
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/java_level_1.4.config.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ -
+
+ 1.4
+
+
+
+
+
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/java_level_1.4.expectations.txt b/jetty-webapp-verifier/src/test/resources/java_level_1.4.expectations.txt
new file mode 100644
index 00000000000..432b2441296
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/java_level_1.4.expectations.txt
@@ -0,0 +1,4 @@
+ERROR|WEB-INF/classes/org/eclipse/jetty/testcase/verifier/DummyLatestLib.class|Class is compiled for java version [1.5] which is over supported java version [1.4]
+ERROR|WEB-INF/classes/org/eclipse/jetty/testcase/verifier/DummyModernLib.class|Class is compiled for java version [1.6] which is over supported java version [1.4]
+ERROR|WEB-INF/lib/dummy-java15-lib-1.0-SNAPSHOT.jar!/org/eclipse/jetty/testcase/verifier/DummyLatestLib.class|Class is compiled for java version [1.5] which is over supported java version [1.4]
+ERROR|WEB-INF/lib/dummy-java16-lib-1.0-SNAPSHOT.jar!/org/eclipse/jetty/testcase/verifier/DummyModernLib.class|Class is compiled for java version [1.6] which is over supported java version [1.4]
diff --git a/jetty-webapp-verifier/src/test/resources/java_level_1.4.setup.txt b/jetty-webapp-verifier/src/test/resources/java_level_1.4.setup.txt
new file mode 100644
index 00000000000..db98daf3ecf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/java_level_1.4.setup.txt
@@ -0,0 +1 @@
+webapps/dummy-javaversions-webapp.war
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/java_level_1.5.config.xml b/jetty-webapp-verifier/src/test/resources/java_level_1.5.config.xml
new file mode 100644
index 00000000000..5f80d29608c
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/java_level_1.5.config.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ -
+
+ 1.5
+
+
+
+
+
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/java_level_1.5.expectations.txt b/jetty-webapp-verifier/src/test/resources/java_level_1.5.expectations.txt
new file mode 100644
index 00000000000..c119c45715c
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/java_level_1.5.expectations.txt
@@ -0,0 +1,2 @@
+ERROR|WEB-INF/classes/org/eclipse/jetty/testcase/verifier/DummyModernLib.class|Class is compiled for java version [1.6] which is over supported java version [1.5]
+ERROR|WEB-INF/lib/dummy-java16-lib-1.0-SNAPSHOT.jar!/org/eclipse/jetty/testcase/verifier/DummyModernLib.class|Class is compiled for java version [1.6] which is over supported java version [1.5]
diff --git a/jetty-webapp-verifier/src/test/resources/java_level_1.5.setup.txt b/jetty-webapp-verifier/src/test/resources/java_level_1.5.setup.txt
new file mode 100644
index 00000000000..db98daf3ecf
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/java_level_1.5.setup.txt
@@ -0,0 +1 @@
+webapps/dummy-javaversions-webapp.war
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/no_native.config.xml b/jetty-webapp-verifier/src/test/resources/no_native.config.xml
new file mode 100644
index 00000000000..47d49fc9c70
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_native.config.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/no_native.expectations.txt b/jetty-webapp-verifier/src/test/resources/no_native.expectations.txt
new file mode 100644
index 00000000000..b187c8eeab7
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_native.expectations.txt
@@ -0,0 +1,6 @@
+ERROR|dummy.exe|Native code is forbidden
+ERROR|dummy.o|Native code is forbidden
+ERROR|dummy.so|Native code is forbidden
+ERROR|other/lib.dll|Native code is forbidden
+ERROR|other/lib.o|Native code is forbidden
+ERROR|other/lib.so|Native code is forbidden
diff --git a/jetty-webapp-verifier/src/test/resources/no_native.setup.txt b/jetty-webapp-verifier/src/test/resources/no_native.setup.txt
new file mode 100644
index 00000000000..543f1ae3740
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_native.setup.txt
@@ -0,0 +1 @@
+webapps/dummy-nativeaccess-webapp.war
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/no_scm.config.xml b/jetty-webapp-verifier/src/test/resources/no_scm.config.xml
new file mode 100644
index 00000000000..af006caf35e
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_scm.config.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/no_scm.expectations.txt b/jetty-webapp-verifier/src/test/resources/no_scm.expectations.txt
new file mode 100644
index 00000000000..0b0f2c893b6
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_scm.expectations.txt
@@ -0,0 +1,36 @@
+ERROR|_darcs/|Darcs Source Control directories are not allowed
+ERROR|_svn/|Subversion Source Control directories are not allowed
+ERROR|.arch-ids/|Arch Source Control directories are not allowed
+ERROR|.bzr/|Bazaar Source Control directories are not allowed
+ERROR|.cvsignore|CVS Source Control file are not allowed
+ERROR|.darcsrepo/|Darcs Source Control directories are not allowed
+ERROR|.darcs-temp-mail|Darcs Source Control file are not allowed
+ERROR|.git/|Git Source Control directories are not allowed
+ERROR|.gitignore|Git Source Control file are not allowed
+ERROR|.hg/|Mercurial Source Control directories are not allowed
+ERROR|.MySCMServerInfo|SurroundSCM Source Control file are not allowed
+ERROR|.svn/|Subversion Source Control directories are not allowed
+ERROR|BitKeeper/|BitKeeper Source Control directories are not allowed
+ERROR|ChangeSet/|BitKeeper Source Control directories are not allowed
+ERROR|CVS/|CVS Source Control directories are not allowed
+ERROR|RCS/|RCS Source Control directories are not allowed
+ERROR|SCCS/|SCCS Source Control directories are not allowed
+ERROR|vssver.scc|Visual SourceSafe Source Control file are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/_darcs/|Darcs Source Control directories are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/_svn/|Subversion Source Control directories are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/.arch-ids/|Arch Source Control directories are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/.bzr/|Bazaar Source Control directories are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/.cvsignore|CVS Source Control file are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/.darcsrepo/|Darcs Source Control directories are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/.darcs-temp-mail|Darcs Source Control file are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/.git/|Git Source Control directories are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/.gitignore|Git Source Control file are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/.hg/|Mercurial Source Control directories are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/.MySCMServerInfo|SurroundSCM Source Control file are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/.svn/|Subversion Source Control directories are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/BitKeeper/|BitKeeper Source Control directories are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/ChangeSet/|BitKeeper Source Control directories are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/CVS/|CVS Source Control directories are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/RCS/|RCS Source Control directories are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/SCCS/|SCCS Source Control directories are not allowed
+ERROR|WEB-INF/lib/dummy-scm-lib-1.0-SNAPSHOT.jar!/vssver.scc|Visual SourceSafe Source Control file are not allowed
diff --git a/jetty-webapp-verifier/src/test/resources/no_scm.setup.txt b/jetty-webapp-verifier/src/test/resources/no_scm.setup.txt
new file mode 100644
index 00000000000..bc01807d23c
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_scm.setup.txt
@@ -0,0 +1 @@
+webapps/dummy-scm-webapp.war
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/no_scripting_groovy.config.xml b/jetty-webapp-verifier/src/test/resources/no_scripting_groovy.config.xml
new file mode 100644
index 00000000000..4986faf70b1
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_scripting_groovy.config.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ -
+
+ false
+
+
+
+
+
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/no_scripting_groovy.expectations.txt b/jetty-webapp-verifier/src/test/resources/no_scripting_groovy.expectations.txt
new file mode 100644
index 00000000000..5a86d668a6d
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_scripting_groovy.expectations.txt
@@ -0,0 +1,4 @@
+ERROR|dummy.groovy|Groovy scripting not allowed
+ERROR|other/lib.groovy|Groovy scripting not allowed
+ERROR|WEB-INF/lib/dummy-groovy-lib-1.0-SNAPSHOT.jar!/org/codehaus/groovy/GroovyException.class|Groovy dependencies are not allowed
+ERROR|WEB-INF/lib/dummy-groovy-lib-1.0-SNAPSHOT.jar!/org/codehaus/groovy/jsr223/GroovyScriptEngineFactory.class|Groovy dependencies are not allowed
diff --git a/jetty-webapp-verifier/src/test/resources/no_scripting_groovy.setup.txt b/jetty-webapp-verifier/src/test/resources/no_scripting_groovy.setup.txt
new file mode 100644
index 00000000000..f631249a77d
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_scripting_groovy.setup.txt
@@ -0,0 +1 @@
+webapps/dummy-groovy-webapp.war
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/no_scripting_jruby.config.xml b/jetty-webapp-verifier/src/test/resources/no_scripting_jruby.config.xml
new file mode 100644
index 00000000000..882f5c2a308
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_scripting_jruby.config.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ -
+
+ false
+
+
+
+
+
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/no_scripting_jruby.expectations.txt b/jetty-webapp-verifier/src/test/resources/no_scripting_jruby.expectations.txt
new file mode 100644
index 00000000000..92678886a36
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_scripting_jruby.expectations.txt
@@ -0,0 +1,6 @@
+ERROR|example.rb|JRuby scripting not allowed
+ERROR|other/lib.rb|JRuby scripting not allowed
+ERROR|output.rhtml|JRuby scripting not allowed
+ERROR|WEB-INF/lib/dummy-jruby-lib-1.0-SNAPSHOT.jar!/org/jruby/javasupport/JavaArray.class|JRuby dependencies are not allowed
+ERROR|WEB-INF/lib/dummy-jruby-lib-1.0-SNAPSHOT.jar!/org/jruby/Ruby.class|JRuby dependencies are not allowed
+ERROR|WEB-INF/lib/dummy-jruby-lib-1.0-SNAPSHOT.jar!/org/jruby/runtime/RubyEvent.class|JRuby dependencies are not allowed
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/no_scripting_jruby.setup.txt b/jetty-webapp-verifier/src/test/resources/no_scripting_jruby.setup.txt
new file mode 100644
index 00000000000..793c6a4e9e6
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_scripting_jruby.setup.txt
@@ -0,0 +1 @@
+webapps/dummy-jruby-webapp.war
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/no_scripting_jython.config.xml b/jetty-webapp-verifier/src/test/resources/no_scripting_jython.config.xml
new file mode 100644
index 00000000000..83d5aad8b6b
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_scripting_jython.config.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ -
+
+ false
+
+
+
+
+
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/no_scripting_jython.expectations.txt b/jetty-webapp-verifier/src/test/resources/no_scripting_jython.expectations.txt
new file mode 100644
index 00000000000..c6823a168a6
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_scripting_jython.expectations.txt
@@ -0,0 +1,6 @@
+ERROR|dummy.py|Jython and Python scripting not allowed
+ERROR|dummy.pyc|Jython and Python scripting not allowed
+ERROR|other/lib.py|Jython and Python scripting not allowed
+ERROR|WEB-INF/lib/dummy-jython-lib-1.0-SNAPSHOT.jar!/org/python/util/Generic.class|Jython dependencies are not allowed
+ERROR|WEB-INF/lib/dummy-jython-lib-1.0-SNAPSHOT.jar!/org/python/Version.class|Jython dependencies are not allowed
+ERROR|WEB-INF/lib/dummy-jython-lib-1.0-SNAPSHOT.jar!/org/python/core/JythonInitializer.class|Jython dependencies are not allowed
diff --git a/jetty-webapp-verifier/src/test/resources/no_scripting_jython.setup.txt b/jetty-webapp-verifier/src/test/resources/no_scripting_jython.setup.txt
new file mode 100644
index 00000000000..4b20b76b0d6
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_scripting_jython.setup.txt
@@ -0,0 +1 @@
+webapps/dummy-jython-webapp.war
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/no_scripting_shell.config.xml b/jetty-webapp-verifier/src/test/resources/no_scripting_shell.config.xml
new file mode 100644
index 00000000000..f97ea8bcdf1
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_scripting_shell.config.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ -
+
+ false
+
+
+
+
+
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/no_scripting_shell.expectations.txt b/jetty-webapp-verifier/src/test/resources/no_scripting_shell.expectations.txt
new file mode 100644
index 00000000000..462b265c087
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_scripting_shell.expectations.txt
@@ -0,0 +1,8 @@
+ERROR|dummy.bat|Shell scripting not allowed
+ERROR|dummy.cmd|Shell scripting not allowed
+ERROR|dummy.sh|Shell scripting not allowed
+ERROR|dummy.vbs|Shell scripting not allowed
+ERROR|other/lib.bat|Shell scripting not allowed
+ERROR|other/lib.cmd|Shell scripting not allowed
+ERROR|other/lib.sh|Shell scripting not allowed
+ERROR|other/lib.vbs|Shell scripting not allowed
diff --git a/jetty-webapp-verifier/src/test/resources/no_scripting_shell.setup.txt b/jetty-webapp-verifier/src/test/resources/no_scripting_shell.setup.txt
new file mode 100644
index 00000000000..e180fb91db1
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/no_scripting_shell.setup.txt
@@ -0,0 +1 @@
+webapps/dummy-shellscripts-webapp.war
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/servlet_level_2.3.config.xml b/jetty-webapp-verifier/src/test/resources/servlet_level_2.3.config.xml
new file mode 100644
index 00000000000..91b35b25245
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/servlet_level_2.3.config.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ -
+
+ 2.1
+
+
+
+
+
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/servlet_level_2.3.expectations.txt b/jetty-webapp-verifier/src/test/resources/servlet_level_2.3.expectations.txt
new file mode 100644
index 00000000000..20af16893fc
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/servlet_level_2.3.expectations.txt
@@ -0,0 +1,2 @@
+ERROR|target/testing/dummy-servlet23-webapp/WEB-INF/web.xml|Specified servlet version 2.3 of DOCTYPE Public ID is over the configured supported servlet version 2.1
+ERROR|target/testing/dummy-servlet23-webapp/WEB-INF/web.xml|Specified servlet version 2.3 of DOCTYPE System ID is over the configured supported servlet version 2.1
diff --git a/jetty-webapp-verifier/src/test/resources/servlet_level_2.3.setup.txt b/jetty-webapp-verifier/src/test/resources/servlet_level_2.3.setup.txt
new file mode 100644
index 00000000000..97453d84b28
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/servlet_level_2.3.setup.txt
@@ -0,0 +1 @@
+webapps/dummy-servlet23-webapp.war
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/servlet_level_2.4.config.xml b/jetty-webapp-verifier/src/test/resources/servlet_level_2.4.config.xml
new file mode 100644
index 00000000000..91b35b25245
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/servlet_level_2.4.config.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ -
+
+ 2.1
+
+
+
+
+
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/servlet_level_2.4.expectations.txt b/jetty-webapp-verifier/src/test/resources/servlet_level_2.4.expectations.txt
new file mode 100644
index 00000000000..07a9e3f6661
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/servlet_level_2.4.expectations.txt
@@ -0,0 +1,3 @@
+ERROR|target/testing/dummy-servlet24-webapp/WEB-INF/web.xml|Specified servlet version 2.4 of Schema is over the configured supported servlet version 2.1
+ERROR|target/testing/dummy-servlet24-webapp/WEB-INF/web.xml|Specified servlet version 2.4 of version attribute is over the configured supported servlet version 2.1
+ERROR|target/testing/dummy-servlet24-webapp/WEB-INF/web.xml|Specified servlet version 2.4 of XML Namespace is over the configured supported servlet version 2.1
diff --git a/jetty-webapp-verifier/src/test/resources/servlet_level_2.4.setup.txt b/jetty-webapp-verifier/src/test/resources/servlet_level_2.4.setup.txt
new file mode 100644
index 00000000000..5996e9b7e24
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/servlet_level_2.4.setup.txt
@@ -0,0 +1 @@
+webapps/dummy-servlet24-webapp.war
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/servlet_level_2.5.config.xml b/jetty-webapp-verifier/src/test/resources/servlet_level_2.5.config.xml
new file mode 100644
index 00000000000..196f3e72336
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/servlet_level_2.5.config.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ -
+
+ 2.4
+
+
+
+
+
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/servlet_level_2.5.expectations.txt b/jetty-webapp-verifier/src/test/resources/servlet_level_2.5.expectations.txt
new file mode 100644
index 00000000000..78fa619543c
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/servlet_level_2.5.expectations.txt
@@ -0,0 +1,3 @@
+ERROR|target/testing/dummy-servlet25-webapp/WEB-INF/web.xml|Specified servlet version 2.5 of Schema is over the configured supported servlet version 2.4
+ERROR|target/testing/dummy-servlet25-webapp/WEB-INF/web.xml|Specified servlet version 2.5 of version attribute is over the configured supported servlet version 2.4
+ERROR|target/testing/dummy-servlet25-webapp/WEB-INF/web.xml|Specified servlet version 2.5 of XML Namespace is over the configured supported servlet version 2.4
diff --git a/jetty-webapp-verifier/src/test/resources/servlet_level_2.5.setup.txt b/jetty-webapp-verifier/src/test/resources/servlet_level_2.5.setup.txt
new file mode 100644
index 00000000000..66caaf0dfe0
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/servlet_level_2.5.setup.txt
@@ -0,0 +1 @@
+webapps/dummy-servlet25-webapp.war
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.4.config.xml b/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.4.config.xml
new file mode 100644
index 00000000000..91b35b25245
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.4.config.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ -
+
+ 2.1
+
+
+
+
+
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.4.expectations.txt b/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.4.expectations.txt
new file mode 100644
index 00000000000..a9da5ebb15f
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.4.expectations.txt
@@ -0,0 +1,14 @@
+ERROR|target/testing/dummy-servletmixed1-webapp/WEB-INF/web.xml|Found 2 versions defined [2.3, 2.4], expected 1
+ERROR|target/testing/dummy-servletmixed1-webapp/WEB-INF/web.xml|Invalid schemaLocation value
+ERROR|target/testing/dummy-servletmixed1-webapp/WEB-INF/web.xml|Specified servlet version 2.3 of DOCTYPE Public ID is over the configured supported servlet version 2.1
+ERROR|target/testing/dummy-servletmixed1-webapp/WEB-INF/web.xml|Specified servlet version 2.3 of DOCTYPE System ID is over the configured supported servlet version 2.1
+ERROR|target/testing/dummy-servletmixed1-webapp/WEB-INF/web.xml|Specified servlet version 2.4 of version attribute is over the configured supported servlet version 2.1
+ERROR|target/testing/dummy-servletmixed1-webapp/WEB-INF/web.xml|Specified servlet version 2.4 of XML Namespace is over the configured supported servlet version 2.1
+ERROR|target/testing/dummy-servletmixed1-webapp/WEB-INF/web.xml|version 2.3 of DOCTYPE Public ID conflicts with version 2.4 of version attribute
+ERROR|target/testing/dummy-servletmixed1-webapp/WEB-INF/web.xml|version 2.3 of DOCTYPE Public ID conflicts with version 2.4 of XML Namespace
+ERROR|target/testing/dummy-servletmixed1-webapp/WEB-INF/web.xml|version 2.3 of DOCTYPE System ID conflicts with version 2.4 of version attribute
+ERROR|target/testing/dummy-servletmixed1-webapp/WEB-INF/web.xml|version 2.3 of DOCTYPE System ID conflicts with version 2.4 of XML Namespace
+ERROR|target/testing/dummy-servletmixed1-webapp/WEB-INF/web.xml|version 2.4 of version attribute conflicts with version 2.3 of DOCTYPE Public ID
+ERROR|target/testing/dummy-servletmixed1-webapp/WEB-INF/web.xml|version 2.4 of version attribute conflicts with version 2.3 of DOCTYPE System ID
+ERROR|target/testing/dummy-servletmixed1-webapp/WEB-INF/web.xml|version 2.4 of XML Namespace conflicts with version 2.3 of DOCTYPE Public ID
+ERROR|target/testing/dummy-servletmixed1-webapp/WEB-INF/web.xml|version 2.4 of XML Namespace conflicts with version 2.3 of DOCTYPE System ID
diff --git a/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.4.setup.txt b/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.4.setup.txt
new file mode 100644
index 00000000000..b473c59a4e4
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.4.setup.txt
@@ -0,0 +1 @@
+webapps/dummy-servletmixed1-webapp.war
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.5.config.xml b/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.5.config.xml
new file mode 100644
index 00000000000..91b35b25245
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.5.config.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ -
+
+ 2.1
+
+
+
+
+
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.5.expectations.txt b/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.5.expectations.txt
new file mode 100644
index 00000000000..d2326c321ca
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.5.expectations.txt
@@ -0,0 +1,15 @@
+ERROR|target/testing/dummy-servletmixed2-webapp/WEB-INF/web.xml|Attribute must exist with a valid value
+ERROR|target/testing/dummy-servletmixed2-webapp/WEB-INF/web.xml|Attribute must exist with a valid value
+ERROR|target/testing/dummy-servletmixed2-webapp/WEB-INF/web.xml|Found 2 versions defined [2.3, 2.5], expected 1
+ERROR|target/testing/dummy-servletmixed2-webapp/WEB-INF/web.xml|Specified servlet version 2.3 of DOCTYPE Public ID is over the configured supported servlet version 2.1
+ERROR|target/testing/dummy-servletmixed2-webapp/WEB-INF/web.xml|Specified servlet version 2.3 of DOCTYPE System ID is over the configured supported servlet version 2.1
+ERROR|target/testing/dummy-servletmixed2-webapp/WEB-INF/web.xml|Specified servlet version 2.5 of version attribute is over the configured supported servlet version 2.1
+ERROR|target/testing/dummy-servletmixed2-webapp/WEB-INF/web.xml|Specified servlet version 2.5 of XML Namespace is over the configured supported servlet version 2.1
+ERROR|target/testing/dummy-servletmixed2-webapp/WEB-INF/web.xml|version 2.3 of DOCTYPE Public ID conflicts with version 2.5 of version attribute
+ERROR|target/testing/dummy-servletmixed2-webapp/WEB-INF/web.xml|version 2.3 of DOCTYPE Public ID conflicts with version 2.5 of XML Namespace
+ERROR|target/testing/dummy-servletmixed2-webapp/WEB-INF/web.xml|version 2.3 of DOCTYPE System ID conflicts with version 2.5 of version attribute
+ERROR|target/testing/dummy-servletmixed2-webapp/WEB-INF/web.xml|version 2.3 of DOCTYPE System ID conflicts with version 2.5 of XML Namespace
+ERROR|target/testing/dummy-servletmixed2-webapp/WEB-INF/web.xml|version 2.5 of version attribute conflicts with version 2.3 of DOCTYPE Public ID
+ERROR|target/testing/dummy-servletmixed2-webapp/WEB-INF/web.xml|version 2.5 of version attribute conflicts with version 2.3 of DOCTYPE System ID
+ERROR|target/testing/dummy-servletmixed2-webapp/WEB-INF/web.xml|version 2.5 of XML Namespace conflicts with version 2.3 of DOCTYPE Public ID
+ERROR|target/testing/dummy-servletmixed2-webapp/WEB-INF/web.xml|version 2.5 of XML Namespace conflicts with version 2.3 of DOCTYPE System ID
diff --git a/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.5.setup.txt b/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.5.setup.txt
new file mode 100644
index 00000000000..da6d2ca5075
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/servlet_level_mixed_2.3_2.5.setup.txt
@@ -0,0 +1 @@
+webapps/dummy-servletmixed2-webapp.war
\ No newline at end of file
diff --git a/jetty-webapp-verifier/src/test/resources/webapps/README.txt b/jetty-webapp-verifier/src/test/resources/webapps/README.txt
new file mode 100644
index 00000000000..a46c58ef038
--- /dev/null
+++ b/jetty-webapp-verifier/src/test/resources/webapps/README.txt
@@ -0,0 +1,10 @@
+There are a number of Webapps in this directory.
+
+Not all of them are valid.
+But all of them are created by the jetty project.
+
+The non-eclipse names present in the various webapps, for classes, packages, etc.
+Are used for testcase reasons, and are all dummy implementations.
+
+See the /jetty-webapp-verifier-examples/ project tree in source control for the
+projects that built these webapps, and their respective WEB-INF/lib jars.
diff --git a/jetty-webapp-verifier/src/test/resources/webapps/dummy-groovy-webapp.war b/jetty-webapp-verifier/src/test/resources/webapps/dummy-groovy-webapp.war
new file mode 100644
index 00000000000..96f1eaec365
Binary files /dev/null and b/jetty-webapp-verifier/src/test/resources/webapps/dummy-groovy-webapp.war differ
diff --git a/jetty-webapp-verifier/src/test/resources/webapps/dummy-javaversions-webapp.war b/jetty-webapp-verifier/src/test/resources/webapps/dummy-javaversions-webapp.war
new file mode 100644
index 00000000000..967fd373ee2
Binary files /dev/null and b/jetty-webapp-verifier/src/test/resources/webapps/dummy-javaversions-webapp.war differ
diff --git a/jetty-webapp-verifier/src/test/resources/webapps/dummy-jruby-webapp.war b/jetty-webapp-verifier/src/test/resources/webapps/dummy-jruby-webapp.war
new file mode 100644
index 00000000000..6704458065c
Binary files /dev/null and b/jetty-webapp-verifier/src/test/resources/webapps/dummy-jruby-webapp.war differ
diff --git a/jetty-webapp-verifier/src/test/resources/webapps/dummy-jython-webapp.war b/jetty-webapp-verifier/src/test/resources/webapps/dummy-jython-webapp.war
new file mode 100644
index 00000000000..6492ba056a4
Binary files /dev/null and b/jetty-webapp-verifier/src/test/resources/webapps/dummy-jython-webapp.war differ
diff --git a/jetty-webapp-verifier/src/test/resources/webapps/dummy-nativeaccess-webapp.war b/jetty-webapp-verifier/src/test/resources/webapps/dummy-nativeaccess-webapp.war
new file mode 100644
index 00000000000..81fa93c36d8
Binary files /dev/null and b/jetty-webapp-verifier/src/test/resources/webapps/dummy-nativeaccess-webapp.war differ
diff --git a/jetty-webapp-verifier/src/test/resources/webapps/dummy-scm-webapp.war b/jetty-webapp-verifier/src/test/resources/webapps/dummy-scm-webapp.war
new file mode 100644
index 00000000000..f7622c4c782
Binary files /dev/null and b/jetty-webapp-verifier/src/test/resources/webapps/dummy-scm-webapp.war differ
diff --git a/jetty-webapp-verifier/src/test/resources/webapps/dummy-servlet23-webapp.war b/jetty-webapp-verifier/src/test/resources/webapps/dummy-servlet23-webapp.war
new file mode 100644
index 00000000000..ffd51fba646
Binary files /dev/null and b/jetty-webapp-verifier/src/test/resources/webapps/dummy-servlet23-webapp.war differ
diff --git a/jetty-webapp-verifier/src/test/resources/webapps/dummy-servlet24-webapp.war b/jetty-webapp-verifier/src/test/resources/webapps/dummy-servlet24-webapp.war
new file mode 100644
index 00000000000..57cc88c85e0
Binary files /dev/null and b/jetty-webapp-verifier/src/test/resources/webapps/dummy-servlet24-webapp.war differ
diff --git a/jetty-webapp-verifier/src/test/resources/webapps/dummy-servlet25-webapp.war b/jetty-webapp-verifier/src/test/resources/webapps/dummy-servlet25-webapp.war
new file mode 100644
index 00000000000..ba56dfb49dd
Binary files /dev/null and b/jetty-webapp-verifier/src/test/resources/webapps/dummy-servlet25-webapp.war differ
diff --git a/jetty-webapp-verifier/src/test/resources/webapps/dummy-servletmixed1-webapp.war b/jetty-webapp-verifier/src/test/resources/webapps/dummy-servletmixed1-webapp.war
new file mode 100644
index 00000000000..5ce4a90ddb9
Binary files /dev/null and b/jetty-webapp-verifier/src/test/resources/webapps/dummy-servletmixed1-webapp.war differ
diff --git a/jetty-webapp-verifier/src/test/resources/webapps/dummy-servletmixed2-webapp.war b/jetty-webapp-verifier/src/test/resources/webapps/dummy-servletmixed2-webapp.war
new file mode 100644
index 00000000000..8ecd5cd918a
Binary files /dev/null and b/jetty-webapp-verifier/src/test/resources/webapps/dummy-servletmixed2-webapp.war differ
diff --git a/jetty-webapp-verifier/src/test/resources/webapps/dummy-shellscripts-webapp.war b/jetty-webapp-verifier/src/test/resources/webapps/dummy-shellscripts-webapp.war
new file mode 100644
index 00000000000..fa7ffa3a581
Binary files /dev/null and b/jetty-webapp-verifier/src/test/resources/webapps/dummy-shellscripts-webapp.war differ
diff --git a/jetty-webapp-verifier/src/test/resources/webapps/signed-jar-test-webapp.war b/jetty-webapp-verifier/src/test/resources/webapps/signed-jar-test-webapp.war
new file mode 100644
index 00000000000..4cce7a8a205
Binary files /dev/null and b/jetty-webapp-verifier/src/test/resources/webapps/signed-jar-test-webapp.war differ
diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml
index 1bb84de46c0..ead8dfdcccf 100644
--- a/jetty-webapp/pom.xml
+++ b/jetty-webapp/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
4.0.0
jetty-webapp
@@ -101,6 +101,11 @@
jetty-xml
${project.version}
+
+ org.eclipse.jetty
+ jetty-webapp-verifier
+ ${project.version}
+
junit
junit
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java
index f39bc648fd6..8e897d257ce 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java
@@ -4,11 +4,11 @@
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
-// The Eclipse Public License is available at
+// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
-// You may elect to redistribute this code under either of these licenses.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.webapp;
@@ -19,6 +19,7 @@ import java.net.MalformedURLException;
import java.security.PermissionCollection;
import java.util.EventListener;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSessionActivationListener;
@@ -49,28 +50,29 @@ import org.eclipse.jetty.util.resource.Resource;
* {@link org.eclipse.jetty.security.ConstraintSecurityHandler}, {@link org.eclipse.jetty.server.session.SessionHandler}
* and {@link org.eclipse.jetty.servlet.ServletHandler}.
* The handlers are configured by pluggable configuration classes, with
- * the default being {@link org.eclipse.jetty.server.server.webapp.WebXmlConfiguration} and
+ * the default being {@link org.eclipse.jetty.server.server.webapp.WebXmlConfiguration} and
* {@link org.eclipse.jetty.server.server.webapp.JettyWebXmlConfiguration}.
- *
+ *
* @org.apache.xbean.XBean description="Creates a servlet web application at a given context from a resource base"
*
*
*
*/
public class WebAppContext extends ServletContextHandler
-{
+{
public static final String TEMPDIR = "javax.servlet.context.tempdir";
public final static String WEB_DEFAULTS_XML="org/eclipse/jetty/webapp/webdefault.xml";
public final static String ERROR_PAGE="org.eclipse.jetty.server.error_page";
+ public final static String SERVER_CONFIG = "org.eclipse.jetty.webapp.configuration";
- private static String[] __dftConfigurationClasses =
- {
- "org.eclipse.jetty.webapp.WebInfConfiguration",
- "org.eclipse.jetty.webapp.WebXmlConfiguration",
+ private static String[] __dftConfigurationClasses =
+ {
+ "org.eclipse.jetty.webapp.WebInfConfiguration",
+ "org.eclipse.jetty.webapp.WebXmlConfiguration",
"org.eclipse.jetty.webapp.MetaInfConfiguration",
"org.eclipse.jetty.webapp.FragmentConfiguration",
"org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
- "org.eclipse.jetty.webapp.TagLibConfiguration"
+ "org.eclipse.jetty.webapp.TagLibConfiguration"
} ;
private String[] _configurationClasses=__dftConfigurationClasses;
private Configuration[] _configurations;
@@ -84,8 +86,8 @@ public class WebAppContext extends ServletContextHandler
private boolean _parentLoaderPriority= Boolean.getBoolean("org.eclipse.jetty.server.webapp.parentLoaderPriority");
private PermissionCollection _permissions;
private String[] _systemClasses = {
- "java.", // Java SE classes (per servlet spec v2.5 / SRV.9.7.2)
- "javax.", // Java SE classes (per servlet spec v2.5 / SRV.9.7.2)
+ "java.", // Java SE classes (per servlet spec v2.5 / SRV.9.7.2)
+ "javax.", // Java SE classes (per servlet spec v2.5 / SRV.9.7.2)
"org.xml.", // needed by javax.xml
"org.w3c.", // needed by javax.xml
"org.apache.commons.logging.", // special case.
@@ -100,7 +102,7 @@ public class WebAppContext extends ServletContextHandler
"-org.eclipse.jetty.plus.jaas.", // don't hide jaas modules
"-org.eclipse.jetty.servlet.DefaultServlet", // webapp cannot change default servlets
"org.eclipse.jetty." // hide rest of jetty classes
- };
+ };
private File _tmpDir;
private String _war;
private String _extraClasspath;
@@ -117,9 +119,9 @@ public class WebAppContext extends ServletContextHandler
{
ContextHandler handler = context.getContextHandler();
if (handler instanceof WebAppContext)
- return (ContextHandler)handler;
+ return handler;
}
- return null;
+ return null;
}
/* ------------------------------------------------------------ */
@@ -162,12 +164,13 @@ public class WebAppContext extends ServletContextHandler
super(null,sessionHandler,securityHandler,servletHandler,errorHandler);
setErrorHandler(errorHandler!=null?errorHandler:new ErrorPageErrorHandler());
- }
+ }
/* ------------------------------------------------------------ */
/**
* @param servletContextName The servletContextName to set.
*/
+ @Override
public void setDisplayName(String servletContextName)
{
super.setDisplayName(servletContextName);
@@ -190,9 +193,9 @@ public class WebAppContext extends ServletContextHandler
/** Set Resource Alias.
* Resource aliases map resource uri's within a context.
* They may optionally be used by a handler when looking for
- * a resource.
- * @param alias
- * @param uri
+ * a resource.
+ * @param alias
+ * @param uri
*/
public void setResourceAlias(String alias, String uri)
{
@@ -235,6 +238,7 @@ public class WebAppContext extends ServletContextHandler
/* (non-Javadoc)
* @see org.eclipse.jetty.server.server.handler.ContextHandler#setClassLoader(java.lang.ClassLoader)
*/
+ @Override
public void setClassLoader(ClassLoader classLoader)
{
super.setClassLoader(classLoader);
@@ -243,6 +247,7 @@ public class WebAppContext extends ServletContextHandler
}
/* ------------------------------------------------------------ */
+ @Override
public Resource getResource(String uriInContext) throws MalformedURLException
{
IOException ioe= null;
@@ -299,14 +304,15 @@ public class WebAppContext extends ServletContextHandler
}
/* ------------------------------------------------------------ */
- /*
+ /*
* @see org.eclipse.thread.AbstractLifeCycle#doStart()
*/
+ @Override
protected void doStart() throws Exception
{
try
{
- // Setup configurations
+ // Setup configurations
loadConfigurations();
@@ -319,14 +325,14 @@ public class WebAppContext extends ServletContextHandler
_ownClassLoader=true;
}
- if (Log.isDebugEnabled())
+ if (Log.isDebugEnabled())
{
ClassLoader loader = getClassLoader();
Log.debug("Thread Context class loader is: " + loader);
loader=loader.getParent();
while(loader!=null)
{
- Log.debug("Parent class loader is: " + loader);
+ Log.debug("Parent class loader is: " + loader);
loader=loader.getParent();
}
}
@@ -344,7 +350,7 @@ public class WebAppContext extends ServletContextHandler
_configurations[i].postConfigure(this);
- if (isLogUrlOnStart())
+ if (isLogUrlOnStart())
dumpUrl();
}
catch (Exception e)
@@ -360,10 +366,10 @@ public class WebAppContext extends ServletContextHandler
/*
* Dumps the current web app name and URL to the log
*/
- public void dumpUrl()
+ public void dumpUrl()
{
Connector[] connectors = getServer().getConnectors();
- for (int i=0;i serverConfigs = (List)getServer().getAttribute(SERVER_CONFIG);
+ if (serverConfigs != null)
+ {
+ configsLen += serverConfigs.size();
+ }
+
+ _configurations = new Configuration[configsLen];
+ for (int i = 0; i < _configurationClasses.length; i++)
{
_configurations[i]=(Configuration)Loader.loadClass(this.getClass(), _configurationClasses[i]).newInstance();
}
+
+ if (serverConfigs != null)
+ {
+ int offset = _configurationClasses.length;
+ for (int i = 0, n = serverConfigs.size(); i < n; i++)
+ {
+ _configurations[i + offset] = serverConfigs.get(i);
+ }
+ }
}
/* ------------------------------------------------------------ */
+ @Override
protected boolean isProtectedTarget(String target)
{
while (target.startsWith("//"))
@@ -628,6 +687,7 @@ public class WebAppContext extends ServletContextHandler
/* ------------------------------------------------------------ */
+ @Override
public String toString()
{
return super.toString()+(_war==null?"":(","+_war));
@@ -656,7 +716,7 @@ public class WebAppContext extends ServletContextHandler
}
/* ------------------------------------------------------------ */
- /**
+ /**
* The default descriptor is a web.xml format file that is applied to the context before the standard WEB-INF/web.xml
* @param defaultsDescriptor The defaultsDescriptor to set.
*/
@@ -703,6 +763,7 @@ public class WebAppContext extends ServletContextHandler
}
/* ------------------------------------------------------------ */
+ @Override
public void setEventListeners(EventListener[] eventListeners)
{
if (_sessionHandler!=null)
@@ -731,9 +792,10 @@ public class WebAppContext extends ServletContextHandler
* Conveniance method that calls {@link #setEventListeners(EventListener[])}
* @param listener
*/
+ @Override
public void addEventListener(EventListener listener)
{
- setEventListeners((EventListener[])LazyList.addToArray(getEventListeners(), listener, EventListener.class));
+ setEventListeners((EventListener[])LazyList.addToArray(getEventListeners(), listener, EventListener.class));
}
@@ -775,12 +837,12 @@ public class WebAppContext extends ServletContextHandler
}
/* ------------------------------------------------------------ */
- /**
+ /**
* Set the server classes patterns.
*
* Server classes/packages are classes used to implement the server and are hidden
* from the context. If the context needs to load these classes, it must have its
- * own copy of them in WEB-INF/lib or WEB-INF/classes.
+ * own copy of them in WEB-INF/lib or WEB-INF/classes.
* A class pattern is a string of one of the forms:
* - org.package.Classname
- Match a specific class
* - org.package.
- Match a specific package hierarchy
@@ -789,7 +851,7 @@ public class WebAppContext extends ServletContextHandler
*
* @param serverClasses The serverClasses to set.
*/
- public void setServerClasses(String[] serverClasses)
+ public void setServerClasses(String[] serverClasses)
{
_serverClasses = serverClasses==null?null:(String[])serverClasses.clone();
}
@@ -882,7 +944,7 @@ public class WebAppContext extends ServletContextHandler
}
/* ------------------------------------------------------------ */
- public boolean isLogUrlOnStart()
+ public boolean isLogUrlOnStart()
{
return _logUrlOnStart;
}
@@ -893,12 +955,13 @@ public class WebAppContext extends ServletContextHandler
*
* @param logOnStart whether or not the log message is created
*/
- public void setLogUrlOnStart(boolean logOnStart)
+ public void setLogUrlOnStart(boolean logOnStart)
{
this._logUrlOnStart = logOnStart;
}
/* ------------------------------------------------------------ */
+ @Override
protected void startContext()
throws Exception
{
@@ -911,5 +974,4 @@ public class WebAppContext extends ServletContextHandler
super.startContext();
}
-
}
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebappVerifierConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebappVerifierConfiguration.java
new file mode 100644
index 00000000000..a47e2a750b8
--- /dev/null
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebappVerifierConfiguration.java
@@ -0,0 +1,97 @@
+// ========================================================================
+// Copyright (c) 2009-2009 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+package org.eclipse.jetty.webapp;
+
+import java.io.File;
+import java.net.URI;
+import java.util.Collection;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.webapp.verifier.RuleSet;
+import org.eclipse.jetty.webapp.verifier.Severity;
+import org.eclipse.jetty.webapp.verifier.Violation;
+import org.eclipse.jetty.webapp.verifier.WebappVerifier;
+
+/**
+ * WebappVerifierConfiguration
+ */
+public class WebappVerifierConfiguration implements Configuration
+{
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.webapp.Configuration#configure(org.eclipse.jetty.webapp.WebAppContext)
+ */
+ public void configure(WebAppContext context) throws Exception
+ {
+
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.webapp.Configuration#deconfigure(org.eclipse.jetty.webapp.WebAppContext)
+ */
+ public void deconfigure(WebAppContext context) throws Exception
+ {
+
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.webapp.Configuration#postConfigure(org.eclipse.jetty.webapp.WebAppContext)
+ */
+ public void postConfigure(WebAppContext context) throws Exception
+ {
+
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.webapp.Configuration#preConfigure(org.eclipse.jetty.webapp.WebAppContext)
+ */
+ public void preConfigure(WebAppContext context) throws Exception
+ {
+ if(Log.isDebugEnabled())
+ {
+ Log.debug("Configuring webapp verifier");
+ }
+
+ URI configurationUri = new File( System.getProperty( "jetty.home" )).toURI().resolve( "etc/default-webapp-verifier.xml" );
+
+ RuleSet suite = RuleSet.load( configurationUri.toURL() );
+
+ WebappVerifier verifier = suite.createWebappVerifier( new URI( context.getWar() ) );
+
+ verifier.visitAll();
+
+ Collection violations = verifier.getViolations();
+
+ boolean haltWebapp = false;
+
+ Log.info( " Webapp Verifier Report: " + violations.size() + " violations" );
+
+ for (Violation violation : violations)
+ {
+ if ( violation.getSeverity() == Severity.ERROR )
+ {
+ haltWebapp = true;
+ }
+
+ Log.info( violation.toString() );
+ }
+
+ if ( haltWebapp )
+ {
+ throw new InstantiationException( "Configuration exception: webapp failed webapp verification" );
+ }
+ }
+}
diff --git a/jetty-xml/pom.xml b/jetty-xml/pom.xml
index 5b085aa2db7..d1e38a0c1be 100644
--- a/jetty-xml/pom.xml
+++ b/jetty-xml/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
4.0.0
jetty-xml
diff --git a/pom.xml b/pom.xml
index e2e4603a59b..4a7793bc6d0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
org.eclipse.jetty
jetty-project
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
Jetty :: Project
${jetty.url}
pom
@@ -132,6 +132,7 @@
jetty-jaspi
jetty-servlet
jetty-webapp
+ jetty-webapp-verifier
jetty-servlets
jetty-deploy
jetty-ajp
diff --git a/test-continuation-jetty6/pom.xml b/test-continuation-jetty6/pom.xml
index c75b5a97db5..536d58dabdb 100644
--- a/test-continuation-jetty6/pom.xml
+++ b/test-continuation-jetty6/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
4.0.0
test-continuation-jetty6
diff --git a/test-continuation/pom.xml b/test-continuation/pom.xml
index 48aa192ef09..7a6c1199e62 100644
--- a/test-continuation/pom.xml
+++ b/test-continuation/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
4.0.0
test-continuation
diff --git a/test-jetty-servlet/pom.xml b/test-jetty-servlet/pom.xml
index 09516965400..27ef6e12ded 100644
--- a/test-jetty-servlet/pom.xml
+++ b/test-jetty-servlet/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
4.0.0
test-jetty-servlet
diff --git a/test-jetty-webapp/pom.xml b/test-jetty-webapp/pom.xml
index 3aaa1e590fc..43388db7b48 100644
--- a/test-jetty-webapp/pom.xml
+++ b/test-jetty-webapp/pom.xml
@@ -2,7 +2,7 @@
org.eclipse.jetty
jetty-project
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
4.0.0
org.eclipse.jetty
diff --git a/tests/pom.xml b/tests/pom.xml
index 8754868f45d..ca02bef2378 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -21,7 +21,7 @@
org.eclipse.jetty
jetty-project
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
org.eclipse.jetty.tests
tests-parent
diff --git a/tests/test-integration/pom.xml b/tests/test-integration/pom.xml
index 8e98e1775a7..203a37497da 100644
--- a/tests/test-integration/pom.xml
+++ b/tests/test-integration/pom.xml
@@ -20,7 +20,7 @@
org.eclipse.jetty.tests
tests-parent
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
4.0.0
test-integration
diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml
index 5565e4224f2..e8ee33cc0e4 100644
--- a/tests/test-webapps/pom.xml
+++ b/tests/test-webapps/pom.xml
@@ -21,7 +21,7 @@
org.eclipse.jetty.tests
tests-parent
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
test-webapps-parent
Jetty Tests :: WebApps :: Parent
diff --git a/tests/test-webapps/test-webapp-logging-commons/pom.xml b/tests/test-webapps/test-webapp-logging-commons/pom.xml
index 2427b6a3793..37178c84f51 100644
--- a/tests/test-webapps/test-webapp-logging-commons/pom.xml
+++ b/tests/test-webapps/test-webapp-logging-commons/pom.xml
@@ -21,7 +21,7 @@
org.eclipse.jetty.tests
test-webapps-parent
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
test-webapp-logging-commons
Jetty Tests :: WebApp :: Commons Logging
diff --git a/tests/test-webapps/test-webapp-logging-java/pom.xml b/tests/test-webapps/test-webapp-logging-java/pom.xml
index 05474728677..f7b5163ec46 100644
--- a/tests/test-webapps/test-webapp-logging-java/pom.xml
+++ b/tests/test-webapps/test-webapp-logging-java/pom.xml
@@ -21,7 +21,7 @@
org.eclipse.jetty.tests
test-webapps-parent
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
test-webapp-logging-java
Jetty Tests :: WebApp :: JavaSE Logging
diff --git a/tests/test-webapps/test-webapp-logging-log4j/pom.xml b/tests/test-webapps/test-webapp-logging-log4j/pom.xml
index cedbcc4debe..71bfcd0713a 100644
--- a/tests/test-webapps/test-webapp-logging-log4j/pom.xml
+++ b/tests/test-webapps/test-webapp-logging-log4j/pom.xml
@@ -21,7 +21,7 @@
org.eclipse.jetty.tests
test-webapps-parent
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
test-webapp-logging-log4j
Jetty Tests :: WebApp :: Log4J Logging
diff --git a/tests/test-webapps/test-webapp-logging-slf4j/pom.xml b/tests/test-webapps/test-webapp-logging-slf4j/pom.xml
index f8b1f1eaca3..8a6ce463804 100644
--- a/tests/test-webapps/test-webapp-logging-slf4j/pom.xml
+++ b/tests/test-webapps/test-webapp-logging-slf4j/pom.xml
@@ -21,7 +21,7 @@
org.eclipse.jetty.tests
test-webapps-parent
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
test-webapp-logging-slf4j
Jetty Tests :: WebApp :: Slf4J Logging
diff --git a/tests/test-webapps/test-webapp-rfc2616/pom.xml b/tests/test-webapps/test-webapp-rfc2616/pom.xml
index 39e0a79507f..a94fe7667d9 100644
--- a/tests/test-webapps/test-webapp-rfc2616/pom.xml
+++ b/tests/test-webapps/test-webapp-rfc2616/pom.xml
@@ -21,7 +21,7 @@
org.eclipse.jetty.tests
test-webapps-parent
- 7.0.0.RC6-SNAPSHOT
+ 7.0.1-SNAPSHOT
test-webapp-rfc2616
Jetty Tests :: WebApp :: RFC2616