diff --git a/Jenkinsfile b/Jenkinsfile
index 595cb39b2eb..2c342706781 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -54,7 +54,7 @@ pipeline {
agent { node { label 'linux' } }
options { timeout(time: 30, unit: 'MINUTES') }
steps {
- mavenBuild("jdk8", "install javadoc:javadoc -DskipTests", "maven3", true)
+ mavenBuild("jdk11", "install javadoc:javadoc -DskipTests", "maven3", true)
warnings consoleParsers: [[parserName: 'Maven'], [parserName: 'JavaDoc'], [parserName: 'Java']]
}
}
diff --git a/jetty-jmh/pom.xml b/jetty-jmh/pom.xml
index 6e882632b61..3ee37a274e2 100644
--- a/jetty-jmh/pom.xml
+++ b/jetty-jmh/pom.xml
@@ -94,12 +94,6 @@
jetty-http
${project.version}
-
- org.eclipse.jetty
- jetty-http
- ${project.version}
- tests
-
javax.servlet
javax.servlet-api
diff --git a/jetty-jmh/src/main/java/org/eclipse/jetty/http/jmh/MultiPartBenchmark.java b/jetty-jmh/src/main/java/org/eclipse/jetty/http/jmh/MultiPartBenchmark.java
index 2867de517d9..754d3cc6801 100644
--- a/jetty-jmh/src/main/java/org/eclipse/jetty/http/jmh/MultiPartBenchmark.java
+++ b/jetty-jmh/src/main/java/org/eclipse/jetty/http/jmh/MultiPartBenchmark.java
@@ -18,9 +18,18 @@
package org.eclipse.jetty.http.jmh;
-import org.eclipse.jetty.http.MultiPartCaptureTest.MultipartExpectations;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
import org.eclipse.jetty.http.MultiPartFormInputStream;
+import org.eclipse.jetty.toolchain.test.Hex;
import org.eclipse.jetty.toolchain.test.IO;
+import org.eclipse.jetty.util.QuotedStringTokenizer;
+import org.eclipse.jetty.util.StringUtil;
+import org.hamcrest.Matchers;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Level;
@@ -40,16 +49,25 @@ import org.openjdk.jmh.runner.options.OptionsBuilder;
import javax.servlet.MultipartConfigElement;
import javax.servlet.http.Part;
+
+import java.io.BufferedReader;
import java.io.File;
+import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
+import java.security.DigestOutputStream;
+import java.security.MessageDigest;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
import java.util.Random;
import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
@State(Scope.Benchmark)
@Threads(4)
@@ -277,6 +295,191 @@ public class MultiPartBenchmark
new Runner(opt).run();
}
+
+
+ public static class MultipartExpectations
+ {
+ public final String contentType;
+ public final int partCount;
+ public final List partFilenames = new ArrayList<>();
+ public final List partSha1sums = new ArrayList<>();
+ public final List partContainsContents = new ArrayList<>();
+
+ public MultipartExpectations(Path expectationsPath) throws IOException
+ {
+ String parsedContentType = null;
+ String parsedPartCount = "-1";
+
+ try (BufferedReader reader = Files.newBufferedReader(expectationsPath))
+ {
+ String line;
+ while ((line = reader.readLine()) != null)
+ {
+ line = line.trim();
+ if (StringUtil.isBlank(line) || line.startsWith("#"))
+ {
+ // skip blanks and comments
+ continue;
+ }
+
+ String split[] = line.split("\\|");
+ switch (split[0])
+ {
+ case "Request-Header":
+ if(split[1].equalsIgnoreCase("Content-Type"))
+ {
+ parsedContentType = split[2];
+ }
+ break;
+ case "Content-Type":
+ parsedContentType = split[1];
+ break;
+ case "Parts-Count":
+ parsedPartCount = split[1];
+ break;
+ case "Part-ContainsContents":
+ {
+ NameValue pair = new NameValue();
+ pair.name = split[1];
+ pair.value = split[2];
+ partContainsContents.add(pair);
+ break;
+ }
+ case "Part-Filename":
+ {
+ NameValue pair = new NameValue();
+ pair.name = split[1];
+ pair.value = split[2];
+ partFilenames.add(pair);
+ break;
+ }
+ case "Part-Sha1sum":
+ {
+ NameValue pair = new NameValue();
+ pair.name = split[1];
+ pair.value = split[2];
+ partSha1sums.add(pair);
+ break;
+ }
+ default:
+ throw new IOException("Bad Line in " + expectationsPath + ": " + line);
+ }
+ }
+ }
+
+ Objects.requireNonNull(parsedContentType, "Missing required 'Content-Type' declaration: " + expectationsPath);
+ this.contentType = parsedContentType;
+ this.partCount = Integer.parseInt(parsedPartCount);
+ }
+
+ private void checkParts(Collection parts, Function getPart) throws Exception
+ {
+ // Evaluate Count
+ if (partCount >= 0)
+ {
+ assertThat("Mulitpart.parts.size", parts.size(), is(partCount));
+ }
+
+ String defaultCharset = UTF_8.toString();
+ Part charSetPart = getPart.apply("_charset_");
+ if(charSetPart != null)
+ {
+ defaultCharset = org.eclipse.jetty.util.IO.toString(charSetPart.getInputStream());
+ }
+
+
+ // Evaluate expected Contents
+ for (NameValue expected : partContainsContents)
+ {
+ Part part = getPart.apply(expected.name);
+ assertThat("Part[" + expected.name + "]", part, is(notNullValue()));
+ try (InputStream partInputStream = part.getInputStream())
+ {
+ String charset = getCharsetFromContentType(part.getContentType(), defaultCharset);
+ String contents = org.eclipse.jetty.util.IO.toString(partInputStream, charset);
+ assertThat("Part[" + expected.name + "].contents", contents, containsString(expected.value));
+ }
+ }
+
+ // Evaluate expected filenames
+ for (NameValue expected : partFilenames)
+ {
+ Part part = getPart.apply(expected.name);
+ assertThat("Part[" + expected.name + "]", part, is(notNullValue()));
+ assertThat("Part[" + expected.name + "]", part.getSubmittedFileName(), is(expected.value));
+ }
+
+ // Evaluate expected contents checksums
+ for (NameValue expected : partSha1sums)
+ {
+ Part part = getPart.apply(expected.name);
+ assertThat("Part[" + expected.name + "]", part, is(notNullValue()));
+ MessageDigest digest = MessageDigest.getInstance("SHA1");
+ try (InputStream partInputStream = part.getInputStream();
+ NoOpOutputStream noop = new NoOpOutputStream();
+ DigestOutputStream digester = new DigestOutputStream(noop, digest))
+ {
+ org.eclipse.jetty.util.IO.copy(partInputStream, digester);
+ String actualSha1sum = Hex.asHex(digest.digest()).toLowerCase(Locale.US);
+ assertThat("Part[" + expected.name + "].sha1sum", actualSha1sum, Matchers.equalToIgnoringCase(expected.value));
+ }
+ }
+ }
+
+ private String getCharsetFromContentType(String contentType, String defaultCharset)
+ {
+ if(StringUtil.isBlank(contentType))
+ {
+ return defaultCharset;
+ }
+
+ QuotedStringTokenizer tok = new QuotedStringTokenizer(contentType, ";", false, false);
+ while(tok.hasMoreTokens())
+ {
+ String str = tok.nextToken().trim();
+ if(str.startsWith("charset="))
+ {
+ return str.substring("charset=".length());
+ }
+ }
+
+ return defaultCharset;
+ }
+ }
+
+ static class NoOpOutputStream extends OutputStream
+ {
+ @Override
+ public void write(byte[] b) throws IOException
+ {
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException
+ {
+ }
+
+ @Override
+ public void flush() throws IOException
+ {
+ }
+
+ @Override
+ public void close() throws IOException
+ {
+ }
+
+ @Override
+ public void write(int b) throws IOException
+ {
+ }
+ }
+
+ public static class NameValue
+ {
+ public String name;
+ public String value;
+ }
}
diff --git a/pom.xml b/pom.xml
index a4ec07b2c5d..14ca21dda91 100644
--- a/pom.xml
+++ b/pom.xml
@@ -280,8 +280,8 @@
true
false
- deploy
- -Peclipse-release
+ javadoc:aggregate-jar deploy
+ -Peclipse-release -Paggregate-javadoc-jar
clean install
forked-path
@@ -537,10 +537,8 @@
false
false
protected
- com.acme.*;org.slf4j.*;org.mortbay.*
-
- https://docs.oracle.com/javase/8/docs/api/
-
+ true
+ com.acme,org.slf4j*,org.mortbay*,*.jmh*,org.eclipse.jetty.embedded*,org.eclipse.jetty.example.asyncrest*,org.eclipse.jetty.test*
@@ -1222,6 +1220,7 @@
org.apache.maven.plugins
maven-gpg-plugin
+ 1.6
sign-artifacts
@@ -1282,38 +1281,6 @@
-
-
- aggregate-site
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
-
- com.acme,*.jmh
-
- http://docs.oracle.com/javase/8/docs/api/
- http://docs.oracle.com/javaee/7/api
- http://junit.sourceforge.net/javadoc/
-
-
-
- org.apache.xbean.XBean
- X
-
-
-
-
-
-
-
-
compact3
diff --git a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
index 0661ca6f7db..44a2a9edda9 100644
--- a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
+++ b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
@@ -185,7 +185,7 @@ public class DistributionTester
/**
* Resolves an artifact given its Maven coordinates.
*
- * @param coordinates :[:[:]]:
+ * @param coordinates <groupId>:<artifactId>[:<extension>[:<classifier>]]:<version>
* @return the artifact
* @see #installWarFile(File, String)
*/