- """
-
- emailext (
- to: email,
- subject: summary,
- body: detail
- )
-
-}
-
-
// vim: et:ts=2:sw=2:ft=groovy
From 6ec3321c16b00fcc7f001935719f84b4e879b431 Mon Sep 17 00:00:00 2001
From: Joakim Erdfelt
Date: Tue, 14 Aug 2018 15:37:39 -0500
Subject: [PATCH 008/931] Attempting to fix jetty-9.2.x build
---
Jenkinsfile | 103 ++++++++++++++++++++++++++--------------------------
1 file changed, 52 insertions(+), 51 deletions(-)
diff --git a/Jenkinsfile b/Jenkinsfile
index 8a34460cef1..5da4a893415 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,9 +1,10 @@
#!groovy
-node {
+node("linux") {
// System Dependent Locations
+ def jdk = 'jdk7'
def mvntool = tool name: 'maven3.5', type: 'hudson.tasks.Maven$MavenInstallation'
- def jdktool = tool name: 'jdk7', type: 'hudson.model.JDK'
+ def jdktool = tool name: $jdk, type: 'hudson.model.JDK'
def mvnName = 'maven3.5'
def localRepo = "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}" // ".repository" //
def settingsName = 'oss-settings.xml'
@@ -49,57 +50,57 @@ node {
}
}
- stage('Test') {
- withEnv(mvnEnv) {
- timeout(time: 60, unit: 'MINUTES') {
- withmaven(
- maven: mvnName,
- jdk: "$jdk",
- publisherStrategy: 'EXPLICIT',
- globalMavenSettingsConfig: settingsName,
- mavenOpts: mavenOpts,
- mavenLocalRepo: localRepo) {
- // Run test phase / ignore test failures
- sh "mvn -B install -Dmaven.test.failure.ignore=true"
- // Report failures in the jenkins UI
- step([$class : 'JUnitResultArchiver',
- testResults: '**/target/surefire-reports/TEST-*.xml'])
- // Collect up the jacoco execution results
- def jacocoExcludes =
- // build tools
- "**/org/eclipse/jetty/ant/**" +
- ",**/org/eclipse/jetty/maven/**" +
- ",**/org/eclipse/jetty/jspc/**" +
- // example code / documentation
- ",**/org/eclipse/jetty/embedded/**" +
- ",**/org/eclipse/jetty/asyncrest/**" +
- ",**/org/eclipse/jetty/demo/**" +
- // special environments / late integrations
- ",**/org/eclipse/jetty/gcloud/**" +
- ",**/org/eclipse/jetty/infinispan/**" +
- ",**/org/eclipse/jetty/osgi/**" +
- ",**/org/eclipse/jetty/spring/**" +
- ",**/org/eclipse/jetty/http/spi/**" +
- // test classes
- ",**/org/eclipse/jetty/tests/**" +
- ",**/org/eclipse/jetty/test/**";
- step([$class: 'JacocoPublisher',
- inclusionPattern: '**/org/eclipse/jetty/**/*.class',
- exclusionPattern: jacocoExcludes,
- execPattern: '**/target/jacoco.exec',
- classPattern: '**/target/classes',
- sourcePattern: '**/src/main/java'])
- // Report on Maven and Javadoc warnings
- step([$class: 'WarningsPublisher',
- consoleParsers: [
- [parserName: 'Maven'],
- [parserName: 'JavaDoc'],
- [parserName: 'JavaC']
- ]])
- }
- }
+ stage('Test') {
+ withEnv(mvnEnv) {
+ timeout(time: 60, unit: 'MINUTES') {
+ withmaven(
+ maven: mvnName,
+ jdk: "$jdk",
+ publisherStrategy: 'EXPLICIT',
+ globalMavenSettingsConfig: settingsName,
+ mavenOpts: mavenOpts,
+ mavenLocalRepo: localRepo) {
+ // Run test phase / ignore test failures
+ sh "mvn -B install -Dmaven.test.failure.ignore=true"
+ // Report failures in the jenkins UI
+ step([$class : 'JUnitResultArchiver',
+ testResults: '**/target/surefire-reports/TEST-*.xml'])
+ // Collect up the jacoco execution results
+ def jacocoExcludes =
+ // build tools
+ "**/org/eclipse/jetty/ant/**" +
+ ",**/org/eclipse/jetty/maven/**" +
+ ",**/org/eclipse/jetty/jspc/**" +
+ // example code / documentation
+ ",**/org/eclipse/jetty/embedded/**" +
+ ",**/org/eclipse/jetty/asyncrest/**" +
+ ",**/org/eclipse/jetty/demo/**" +
+ // special environments / late integrations
+ ",**/org/eclipse/jetty/gcloud/**" +
+ ",**/org/eclipse/jetty/infinispan/**" +
+ ",**/org/eclipse/jetty/osgi/**" +
+ ",**/org/eclipse/jetty/spring/**" +
+ ",**/org/eclipse/jetty/http/spi/**" +
+ // test classes
+ ",**/org/eclipse/jetty/tests/**" +
+ ",**/org/eclipse/jetty/test/**";
+ step([$class: 'JacocoPublisher',
+ inclusionPattern: '**/org/eclipse/jetty/**/*.class',
+ exclusionPattern: jacocoExcludes,
+ execPattern: '**/target/jacoco.exec',
+ classPattern: '**/target/classes',
+ sourcePattern: '**/src/main/java'])
+ // Report on Maven and Javadoc warnings
+ step([$class: 'WarningsPublisher',
+ consoleParsers: [
+ [parserName: 'Maven'],
+ [parserName: 'JavaDoc'],
+ [parserName: 'JavaC']
+ ]])
+ }
}
}
+ }
}
// vim: et:ts=2:sw=2:ft=groovy
From 283fa32e5962982a2f867b37d1557c966baef581 Mon Sep 17 00:00:00 2001
From: Joakim Erdfelt
Date: Tue, 14 Aug 2018 15:39:08 -0500
Subject: [PATCH 009/931] Attempting to fix jetty-9.2.x build
---
Jenkinsfile | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Jenkinsfile b/Jenkinsfile
index 5da4a893415..9a355449f0e 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,10 +1,11 @@
#!groovy
+def jdk = 'jdk7'
+
node("linux") {
// System Dependent Locations
- def jdk = 'jdk7'
def mvntool = tool name: 'maven3.5', type: 'hudson.tasks.Maven$MavenInstallation'
- def jdktool = tool name: $jdk, type: 'hudson.model.JDK'
+ def jdktool = tool name: "$jdk", type: 'hudson.model.JDK'
def mvnName = 'maven3.5'
def localRepo = "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}" // ".repository" //
def settingsName = 'oss-settings.xml'
From 73d940680aa8bbc2fd521d1fe8026e6bd1c6a4d0 Mon Sep 17 00:00:00 2001
From: Joakim Erdfelt
Date: Tue, 14 Aug 2018 15:39:58 -0500
Subject: [PATCH 010/931] Attempting to fix jetty-9.2.x build
---
Jenkinsfile | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Jenkinsfile b/Jenkinsfile
index 9a355449f0e..ad11acdc88a 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -22,7 +22,7 @@ node("linux") {
stage('Compile') {
withEnv(mvnEnv) {
timeout(time: 15, unit: 'MINUTES') {
- withmaven(
+ withMaven(
maven: mvnName,
jdk: "$jdk",
publisherStrategy: 'EXPLICIT',
@@ -38,7 +38,7 @@ node("linux") {
stage('Javadoc') {
withEnv(mvnEnv) {
timeout(time: 15, unit: 'MINUTES') {
- withmaven(
+ withMaven(
maven: mvnName,
jdk: "$jdk",
publisherStrategy: 'EXPLICIT',
@@ -54,7 +54,7 @@ node("linux") {
stage('Test') {
withEnv(mvnEnv) {
timeout(time: 60, unit: 'MINUTES') {
- withmaven(
+ withMaven(
maven: mvnName,
jdk: "$jdk",
publisherStrategy: 'EXPLICIT',
From e0a92f6181fcbc2cf168250cd66fbe5a37aa407b Mon Sep 17 00:00:00 2001
From: Roland Grunberg
Date: Tue, 14 Aug 2018 19:26:37 -0400
Subject: [PATCH 011/931] Issue #2794 - Add profile for jar signing with
eclipse-jarsigner-plugin. (#2803)
Create a profile 'eclipse-sign' that is enabled when the property by
the same name is defined, in order to handle the signing of Eclipse
bundles by the configured signing service.
Signed-off-by: Roland Grunberg
---
pom.xml | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/pom.xml b/pom.xml
index fc489b8a551..c98ee1d6811 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,6 +21,8 @@
undefinedundefined
+ 1.2.0
+ 1.1.5scm:git:https://github.com/eclipse/jetty.project.git
@@ -1052,6 +1054,60 @@
7.1.3.v20150130
+
+ eclipse-sign
+
+
+ eclipse-sign
+
+
+
+
+
+ org.eclipse.tycho.extras
+ tycho-pack200a-plugin
+ ${tycho-version}
+
+
+ pack200-normalize
+
+ normalize
+
+ package
+
+
+
+
+ org.eclipse.cbi.maven.plugins
+ eclipse-jarsigner-plugin
+ ${cbi-plugins.version}
+
+
+ sign
+ package
+
+ sign
+
+
+
+
+
+ org.eclipse.tycho.extras
+ tycho-pack200b-plugin
+ ${tycho-version}
+
+
+ pack200-pack
+
+ pack
+
+ package
+
+
+
+
+
+ 8u00
@@ -1461,4 +1517,15 @@
+
+
+
+ cbi-releases
+ https://repo.eclipse.org/content/repositories/cbi-releases/
+
+ false
+
+
+
+
From 74e30605ed39cbe98a5838f94b680618f2330af2 Mon Sep 17 00:00:00 2001
From: Olivier Lamy
Date: Wed, 15 Aug 2018 22:10:26 +1000
Subject: [PATCH 012/931] should fix osgi test with missing dependencies
(#2809)
Signed-off-by: olivier lamy
---
jetty-osgi/test-jetty-osgi/pom.xml | 3 +++
.../org/eclipse/jetty/osgi/test/TestJettyOSGiBootCore.java | 5 +++++
2 files changed, 8 insertions(+)
diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml
index 570074ecc25..7b3316522a5 100644
--- a/jetty-osgi/test-jetty-osgi/pom.xml
+++ b/jetty-osgi/test-jetty-osgi/pom.xml
@@ -391,6 +391,9 @@
-Dmortbay-alpn-boot=${settings.localRepository}/org/mortbay/jetty/alpn/alpn-boot/${alpn.version}/alpn-boot-${alpn.version}.jar
+
+ ${settings.localRepository}
+
diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootCore.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootCore.java
index 8baf71a67b8..519b78aae1b 100644
--- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootCore.java
+++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootCore.java
@@ -28,6 +28,7 @@ import java.util.List;
import javax.inject.Inject;
+import org.eclipse.jetty.util.StringUtil;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -82,6 +83,10 @@ public class TestJettyOSGiBootCore
{
List
+ org.apache.maven.pluginsmaven-dependency-plugin
+
org.ops4j.pax.exam
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java
index 651fd354971..edfa3de5b24 100644
--- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java
@@ -42,7 +42,7 @@ import java.io.StringReader;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.fail;
public class CookiePatternRuleTest
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/CustomResourcesMonitorTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/CustomResourcesMonitorTest.java
index 57b4a5fe9a4..0048f34fcdb 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/CustomResourcesMonitorTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/CustomResourcesMonitorTest.java
@@ -27,7 +27,6 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
@@ -38,7 +37,8 @@ import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import static org.junit.Assert.*;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
public class CustomResourcesMonitorTest
{
@@ -111,28 +111,14 @@ public class CustomResourcesMonitorTest
InputStream input1 = socket1.getInputStream();
assertTrue(_fileOnDirectoryMonitor.isLowOnResources());
- try
- {
- input1.read();
- fail();
- }
- catch (SocketTimeoutException expected)
- {
- }
+ assertThrows(SocketTimeoutException.class, () -> input1.read());
// Wait a couple of lowResources idleTimeouts.
Thread.sleep(2 * lowResourcesIdleTimeout);
// Verify the new socket is still open.
assertTrue(_fileOnDirectoryMonitor.isLowOnResources());
- try
- {
- input1.read();
- fail();
- }
- catch (SocketTimeoutException expected)
- {
- }
+ assertThrows(SocketTimeoutException.class, () -> input1.read());
Files.delete( tmpFile );
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/LowResourcesMonitorTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/LowResourcesMonitorTest.java
index 9d7bf40fcba..6cebfcdada6 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/LowResourcesMonitorTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/LowResourcesMonitorTest.java
@@ -23,6 +23,7 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.TimerScheduler;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -38,7 +39,6 @@ import java.util.concurrent.CountDownLatch;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.fail;
import static org.junit.jupiter.api.Assertions.*;
public class LowResourcesMonitorTest
@@ -248,28 +248,15 @@ public class LowResourcesMonitorTest
InputStream input1 = socket1.getInputStream();
assertTrue(_lowResourcesMonitor.isLowOnResources());
- try
- {
- input1.read();
- fail();
- }
- catch (SocketTimeoutException expected)
- {
- }
+ assertThrows( SocketTimeoutException.class, () -> input1.read());
// Wait a couple of lowResources idleTimeouts.
Thread.sleep(2 * lowResourcesIdleTimeout);
// Verify the new socket is still open.
assertTrue(_lowResourcesMonitor.isLowOnResources());
- try
- {
- input1.read();
- fail();
- }
- catch (SocketTimeoutException expected)
- {
- }
+ assertThrows( SocketTimeoutException.class, () -> input1.read());
+
// Let the maxLowResourcesTime elapse.
Thread.sleep(maxLowResourcesTime);
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java
index c720e0f3e15..48a39b7d2e7 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java
@@ -18,15 +18,26 @@
package org.eclipse.jetty.servlet;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.contains;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.equalToIgnoringCase;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.hamcrest.Matchers.nullValue;
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.server.LocalConnector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.gzip.GzipHandler;
+import org.eclipse.jetty.util.IO;
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import javax.servlet.DispatcherType;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -40,22 +51,9 @@ import java.util.Enumeration;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
-import javax.servlet.*;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.http.HttpTester;
-import org.eclipse.jetty.server.Dispatcher;
-import org.eclipse.jetty.server.LocalConnector;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.gzip.GzipHandler;
-import org.eclipse.jetty.util.IO;
-import org.hamcrest.Matchers;
-import org.junit.Assert;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
@SuppressWarnings("serial")
public class GzipHandlerTest
@@ -616,9 +614,9 @@ public class GzipHandlerTest
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
if (request.getParameter("X-Content-Encoding")!=null)
- Assert.assertEquals(-1,request.getContentLength());
+ assertEquals(-1,request.getContentLength());
else if (request.getContentLength()>=0)
- Assert.assertThat(request.getParameter("X-Content-Encoding"),Matchers.nullValue());
+ assertThat(request.getParameter("X-Content-Encoding"),Matchers.nullValue());
chain.doFilter(request,response);
}
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/TypeUtilTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/TypeUtilTest.java
index dc103c1b1d4..6349a364fae 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/TypeUtilTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/TypeUtilTest.java
@@ -21,10 +21,10 @@ package org.eclipse.jetty.util;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assume.assumeTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
import java.nio.file.Path;
import java.nio.file.Paths;
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/RateStatisticTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/RateStatisticTest.java
index 0a768d4f990..9ef3e5578d2 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/RateStatisticTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/RateStatisticTest.java
@@ -24,7 +24,8 @@ import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import static org.hamcrest.Matchers.equalTo;
-import static org.junit.Assert.assertThat;
+import static org.hamcrest.MatcherAssert.assertThat;
+
/* ------------------------------------------------------------ */
diff --git a/pom.xml b/pom.xml
index 08f256d856f..4df812973df 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,6 +37,8 @@
2.4.5.Final1.0.5
+
+ false2.22.0
@@ -49,7 +51,7 @@
- 5.0
+ 5.1
@@ -647,6 +649,8 @@
${project.build.directory}${unix.socket.tmp}
+ true
+ ${jetty.testtracker.log}
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/JettyDistro.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/JettyDistro.java
index 3cc69f47f27..27994a3e1d3 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/JettyDistro.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/JettyDistro.java
@@ -258,7 +258,7 @@ public class JettyDistro
*/
public JettyDistro(Class> clazz, String artifact) throws IOException
{
- this.jettyHomeDir = MavenTestingUtils.getTargetTestingDir(clazz,"jettyHome");
+ this.jettyHomeDir = MavenTestingUtils.getTargetTestingPath(clazz,"jettyHome").toFile();
if (artifact != null)
{
this.artifactName = artifact;
diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredOrphanedSessionTest.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredOrphanedSessionTest.java
index 0e54b028bc3..fb192d31b60 100644
--- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredOrphanedSessionTest.java
+++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredOrphanedSessionTest.java
@@ -22,6 +22,7 @@ package org.eclipse.jetty.gcloud.session;
import org.eclipse.jetty.server.session.AbstractClusteredOrphanedSessionTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
/**
@@ -32,10 +33,25 @@ import org.junit.jupiter.api.Test;
public class ClusteredOrphanedSessionTest extends AbstractClusteredOrphanedSessionTest
{
+ public static GCloudSessionTestSupport __testSupport;
+
+ @BeforeAll
+ public static void setUp () throws Exception
+ {
+ __testSupport = new GCloudSessionTestSupport();
+ __testSupport.setUp();
+ }
+
+ @AfterAll
+ public static void tearDown () throws Exception
+ {
+ __testSupport.tearDown();
+ }
+
@AfterAll
public static void teardown () throws Exception
{
- GCloudTestSuite.__testSupport.deleteSessions();
+ __testSupport.deleteSessions();
}
@@ -46,7 +62,7 @@ public class ClusteredOrphanedSessionTest extends AbstractClusteredOrphanedSessi
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
- return GCloudSessionTestSupport.newSessionDataStoreFactory(GCloudTestSuite.__testSupport.getDatastore());
+ return GCloudSessionTestSupport.newSessionDataStoreFactory(__testSupport.getDatastore());
}
diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredSessionScavengingTest.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredSessionScavengingTest.java
index ab430f9c03a..31393388e63 100644
--- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredSessionScavengingTest.java
+++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredSessionScavengingTest.java
@@ -22,6 +22,7 @@ package org.eclipse.jetty.gcloud.session;
import org.eclipse.jetty.server.session.AbstractClusteredSessionScavengingTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
/**
* ClusteredSessionScavengingTest
@@ -30,11 +31,26 @@ import org.junit.jupiter.api.AfterAll;
*/
public class ClusteredSessionScavengingTest extends AbstractClusteredSessionScavengingTest
{
-
+
+ public static GCloudSessionTestSupport __testSupport;
+
+ @BeforeAll
+ public static void setUp () throws Exception
+ {
+ __testSupport = new GCloudSessionTestSupport();
+ __testSupport.setUp();
+ }
+
+ @AfterAll
+ public static void tearDown () throws Exception
+ {
+ __testSupport.tearDown();
+ }
+
@AfterAll
public static void teardown () throws Exception
{
- GCloudTestSuite.__testSupport.deleteSessions();
+ __testSupport.deleteSessions();
}
@@ -44,7 +60,7 @@ public class ClusteredSessionScavengingTest extends AbstractClusteredSessionScav
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
- return GCloudSessionTestSupport.newSessionDataStoreFactory(GCloudTestSuite.__testSupport.getDatastore());
+ return GCloudSessionTestSupport.newSessionDataStoreFactory(__testSupport.getDatastore());
}
diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreTest.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreTest.java
index b652e034d7b..d10de993b63 100644
--- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreTest.java
+++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreTest.java
@@ -22,7 +22,9 @@ package org.eclipse.jetty.gcloud.session;
import org.eclipse.jetty.server.session.AbstractSessionDataStoreTest;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
+import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
/**
* GCloudSessionDataStoreTest
@@ -32,24 +34,39 @@ import org.junit.jupiter.api.AfterEach;
public class GCloudSessionDataStoreTest extends AbstractSessionDataStoreTest
{
+ public static GCloudSessionTestSupport __testSupport;
+
+ @BeforeAll
+ public static void setUp () throws Exception
+ {
+ __testSupport = new GCloudSessionTestSupport();
+ __testSupport.setUp();
+ }
+
+ @AfterAll
+ public static void tearDown () throws Exception
+ {
+ __testSupport.tearDown();
+ }
+
@AfterEach
public void teardown () throws Exception
{
- GCloudTestSuite.__testSupport.deleteSessions();
+ __testSupport.deleteSessions();
}
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
- return GCloudSessionTestSupport.newSessionDataStoreFactory(GCloudTestSuite.__testSupport.getDatastore());
+ return GCloudSessionTestSupport.newSessionDataStoreFactory(__testSupport.getDatastore());
}
@Override
public void persistSession(SessionData data) throws Exception
{
- GCloudTestSuite.__testSupport.createSession(data.getId(), data.getContextPath(), data.getVhost(), data.getLastNode(), data.getCreated(),
+ __testSupport.createSession(data.getId(), data.getContextPath(), data.getVhost(), data.getLastNode(), data.getCreated(),
data.getAccessed(), data.getLastAccessed(), data.getMaxInactiveMs(), data.getExpiry(),
data.getCookieSet(), data.getLastSaved(), data.getAllAttributes());
@@ -60,7 +77,7 @@ public class GCloudSessionDataStoreTest extends AbstractSessionDataStoreTest
public void persistUnreadableSession(SessionData data) throws Exception
{
- GCloudTestSuite.__testSupport.createSession(data.getId(), data.getContextPath(), data.getVhost(), data.getLastNode(), data.getCreated(),
+ __testSupport.createSession(data.getId(), data.getContextPath(), data.getVhost(), data.getLastNode(), data.getCreated(),
data.getAccessed(), data.getLastAccessed(), data.getMaxInactiveMs(), data.getExpiry(),
data.getCookieSet(), data.getLastSaved(), null);
}
@@ -69,7 +86,7 @@ public class GCloudSessionDataStoreTest extends AbstractSessionDataStoreTest
@Override
public boolean checkSessionExists(SessionData data) throws Exception
{
- return GCloudTestSuite.__testSupport.checkSessionExists(data.getId());
+ return __testSupport.checkSessionExists(data.getId());
}
@@ -79,7 +96,7 @@ public class GCloudSessionDataStoreTest extends AbstractSessionDataStoreTest
@Override
public boolean checkSessionPersisted(SessionData data) throws Exception
{
- return GCloudTestSuite.__testSupport.checkSessionPersisted(data);
+ return __testSupport.checkSessionPersisted(data);
}
}
diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudTestSuite.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudTestSuite.java
deleted file mode 100644
index a77dd76aceb..00000000000
--- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudTestSuite.java
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2018 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.gcloud.session;
-
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-/**
- * GCloudTestSuite
- *
- * Sets up the gcloud emulator once before running all tests.
- *
- */
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
- GCloudSessionDataStoreTest.class,
- InvalidationSessionTest.class,
- ClusteredSessionScavengingTest.class,
- ClusteredOrphanedSessionTest.class
-})
-public class GCloudTestSuite
-{
- public static GCloudSessionTestSupport __testSupport;
-
- @BeforeAll
- public static void setUp () throws Exception
- {
- __testSupport = new GCloudSessionTestSupport();
- __testSupport.setUp();
- }
-
- @AfterAll
- public static void tearDown () throws Exception
- {
- __testSupport.tearDown();
- }
-}
diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/InvalidationSessionTest.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/InvalidationSessionTest.java
index 476c8dd9e18..3e7809aa82a 100644
--- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/InvalidationSessionTest.java
+++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/InvalidationSessionTest.java
@@ -23,6 +23,7 @@ package org.eclipse.jetty.gcloud.session;
import org.eclipse.jetty.server.session.AbstractClusteredInvalidationSessionTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
/**
* InvalidationSessionTest
@@ -31,11 +32,26 @@ import org.junit.jupiter.api.AfterAll;
*/
public class InvalidationSessionTest extends AbstractClusteredInvalidationSessionTest
{
-
+
+ public static GCloudSessionTestSupport __testSupport;
+
+ @BeforeAll
+ public static void setUp () throws Exception
+ {
+ __testSupport = new GCloudSessionTestSupport();
+ __testSupport.setUp();
+ }
+
+ @AfterAll
+ public static void tearDown () throws Exception
+ {
+ __testSupport.tearDown();
+ }
+
@AfterAll
public static void teardown () throws Exception
{
- GCloudTestSuite.__testSupport.deleteSessions();
+ __testSupport.deleteSessions();
}
/**
@@ -44,6 +60,6 @@ public class InvalidationSessionTest extends AbstractClusteredInvalidationSessio
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
- return GCloudSessionTestSupport.newSessionDataStoreFactory(GCloudTestSuite.__testSupport.getDatastore());
+ return GCloudSessionTestSupport.newSessionDataStoreFactory(__testSupport.getDatastore());
}
}
From 7a2ba10ed62d4727ecc993d07583072f03935e0c Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Fri, 21 Sep 2018 10:38:23 +0200
Subject: [PATCH 036/931] Issue #2727 - Revisit JMX MBean lookup behavior.
Improved lookup of MBean constructor, now done only once.
Cleaned up tests.
Signed-off-by: Simone Bordet
---
.../org/eclipse/jetty/jmx/MBeanContainer.java | 38 ++-
.../java/org/eclipse/jetty/jmx/MetaData.java | 84 ++++---
.../org/eclipse/jetty/jmx/ObjectMBean.java | 12 +-
.../test/java/com/acme/DerivedExtended.java | 1 -
.../eclipse/jetty/jmx/MBeanContainerTest.java | 47 +---
.../eclipse/jetty/jmx/ObjectMBeanTest.java | 188 +++++----------
.../jetty/jmx/ObjectMBeanUtilTest.java | 224 ++++--------------
.../java/org/eclipse/jetty/jmx/PojoTest.java | 12 +-
.../test/resources/jetty-logging.properties | 2 +-
9 files changed, 218 insertions(+), 390 deletions(-)
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
index c5f22c38a40..3f2ea7bb4f9 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
@@ -19,6 +19,7 @@
package org.eclipse.jetty.jmx;
import java.io.IOException;
+import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -34,7 +35,9 @@ import javax.management.InstanceNotFoundException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
+import javax.management.modelmbean.ModelMBean;
+import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.Container;
@@ -151,7 +154,7 @@ public class MBeanContainer implements Container.InheritedListener, Dumpable, De
if (mbean instanceof ObjectMBean)
((ObjectMBean)mbean).setMBeanContainer(container);
if (LOG.isDebugEnabled())
- LOG.debug("mbeanFor {} is {}", o, mbean);
+ LOG.debug("MBean for {} is {}", o, mbean);
return mbean;
}
@@ -161,7 +164,11 @@ public class MBeanContainer implements Container.InheritedListener, Dumpable, De
return null;
MetaData metaData = getMetaData(container, klass);
if (metaData != null)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("Found cached {}", metaData);
return metaData;
+ }
return newMetaData(container, klass);
}
@@ -175,12 +182,12 @@ public class MBeanContainer implements Container.InheritedListener, Dumpable, De
if (klass == null)
return null;
if (klass == Object.class)
- return new MetaData(klass, null, Collections.emptyList());
+ return new MetaData(klass, null, null, Collections.emptyList());
List interfaces = Arrays.stream(klass.getInterfaces())
- .map(iClass -> findMetaData(container, iClass))
+ .map(intf -> findMetaData(container, intf))
.collect(Collectors.toList());
- MetaData metaData = new MetaData(klass, findMetaData(container, klass.getSuperclass()), interfaces);
+ MetaData metaData = new MetaData(klass, findConstructor(klass), findMetaData(container, klass.getSuperclass()), interfaces);
if (container != null)
{
@@ -195,6 +202,29 @@ public class MBeanContainer implements Container.InheritedListener, Dumpable, De
return metaData;
}
+ private static Constructor> findConstructor(Class> klass)
+ {
+ String pName = klass.getPackage().getName();
+ String cName = klass.getName().substring(pName.length() + 1);
+ String mName = pName + ".jmx." + cName + "MBean";
+ try
+ {
+ Class> mbeanClass = Loader.loadClass(mName);
+ Constructor> constructor = ModelMBean.class.isAssignableFrom(mbeanClass)
+ ? mbeanClass.getConstructor()
+ : mbeanClass.getConstructor(Object.class);
+ if (LOG.isDebugEnabled())
+ LOG.debug("Found MBean wrapper: {} for {}", mName, klass.getName());
+ return constructor;
+ }
+ catch (Throwable x)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("MBean wrapper not found: {} for {}", mName, klass.getName());
+ return null;
+ }
+ }
+
/**
* Lookup an object name by instance
*
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
index 9f3b8882068..c081178b050 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
@@ -45,7 +45,6 @@ import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.modelmbean.ModelMBean;
-import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.annotation.ManagedOperation;
@@ -59,21 +58,24 @@ class MetaData
private final Map _attributes = new HashMap<>();
private final Map _operations = new HashMap<>();
+ private final Class> _klass;
private final MetaData _parent;
private final List _interfaces;
private final Constructor> _constructor;
private final MBeanInfo _info;
- MetaData(Class> klass, MetaData parent, List interfaces)
+ MetaData(Class> klass, Constructor> constructor, MetaData parent, List interfaces)
{
+ _klass = klass;
_parent = parent;
_interfaces = interfaces;
- _constructor = findConstructor(klass);
+ _constructor = constructor;
if (_constructor != null)
parseMethods(klass, _constructor.getDeclaringClass());
else
parseMethods(klass);
_info = buildMBeanInfo(klass);
+
}
Object newInstance(Object bean)
@@ -93,7 +95,7 @@ class MetaData
return _info;
}
- Object getAttribute(String name, ObjectMBean mbean) throws AttributeNotFoundException, ReflectionException
+ Object getAttribute(String name, ObjectMBean mbean) throws AttributeNotFoundException, ReflectionException, MBeanException
{
AttributeInfo info = findAttribute(name);
if (info == null)
@@ -101,7 +103,7 @@ class MetaData
return info.getAttribute(mbean);
}
- void setAttribute(Attribute attribute, ObjectMBean mbean) throws AttributeNotFoundException, ReflectionException
+ void setAttribute(Attribute attribute, ObjectMBean mbean) throws AttributeNotFoundException, ReflectionException, MBeanException
{
if (attribute == null)
return;
@@ -114,6 +116,8 @@ class MetaData
private AttributeInfo findAttribute(String name)
{
+ if (name == null)
+ return null;
AttributeInfo result = _attributes.get(name);
if (result != null)
return result;
@@ -153,24 +157,6 @@ class MetaData
return null;
}
- private static Constructor> findConstructor(Class> klass)
- {
- try
- {
- String pName = klass.getPackage().getName();
- String cName = klass.getName().substring(pName.length() + 1);
- String mName = pName + ".jmx." + cName + "MBean";
- Class> mbeanClass = Loader.loadClass(mName);
- return ModelMBean.class.isAssignableFrom(mbeanClass)
- ? mbeanClass.getConstructor()
- : mbeanClass.getConstructor(Object.class);
- }
- catch (Throwable x)
- {
- return null;
- }
- }
-
private static Object newInstance(Constructor> constructor, Object bean)
{
try
@@ -190,6 +176,7 @@ class MetaData
{
for (Class> klass : classes)
{
+ // Only work on the public method of the class, not of the hierarchy.
for (Method method : klass.getDeclaredMethods())
{
if (!Modifier.isPublic(method.getModifiers()))
@@ -198,12 +185,16 @@ class MetaData
if (attribute != null)
{
AttributeInfo info = new AttributeInfo(attribute, method);
+ if (LOG.isDebugEnabled())
+ LOG.debug("Found attribute for {}: {}", klass.getName(), info);
_attributes.put(info._name, info);
}
ManagedOperation operation = method.getAnnotation(ManagedOperation.class);
if (operation != null)
{
OperationInfo info = new OperationInfo(operation, method);
+ if (LOG.isDebugEnabled())
+ LOG.debug("Found operation for {}: {}", klass.getName(), info);
_operations.put(info._name, info);
}
}
@@ -284,6 +275,21 @@ class MetaData
_parent.collectMBeanOperationInfos(operationInfos);
}
+ private static MBeanException toMBeanException(InvocationTargetException x)
+ {
+ Throwable cause = x.getCause();
+ if (cause instanceof Exception)
+ return new MBeanException((Exception)cause);
+ else
+ return new MBeanException(x);
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("%s@%x[%s]", getClass().getSimpleName(), hashCode(), _klass.getName());
+ }
+
private static class AttributeInfo
{
private final String _name;
@@ -318,7 +324,7 @@ class MetaData
_setter != null, getter.getName().startsWith("is"));
}
- Object getAttribute(ObjectMBean mbean) throws ReflectionException
+ Object getAttribute(ObjectMBean mbean) throws ReflectionException, MBeanException
{
try
{
@@ -338,13 +344,17 @@ class MetaData
names[i] = mbean.findObjectName(Array.get(result, i));
return names;
}
+ catch (InvocationTargetException x)
+ {
+ throw toMBeanException(x);
+ }
catch (Exception x)
{
throw new ReflectionException(x);
}
}
- void setAttribute(Object value, ObjectMBean mbean) throws ReflectionException
+ void setAttribute(Object value, ObjectMBean mbean) throws ReflectionException, MBeanException
{
try
{
@@ -370,6 +380,10 @@ class MetaData
Array.set(result, i, mbean.findBean(names[i]));
_setter.invoke(target, result);
}
+ catch (InvocationTargetException x)
+ {
+ throw toMBeanException(x);
+ }
catch (Exception x)
{
throw new ReflectionException(x);
@@ -404,6 +418,13 @@ class MetaData
return setter;
}
+
+ @Override
+ public String toString()
+ {
+ return String.format("%s@%x[%s,proxied=%b,convert=%b]", getClass().getSimpleName(), hashCode(),
+ _name, _proxied, _convert);
+ }
}
private static class OperationInfo
@@ -464,11 +485,7 @@ class MetaData
}
catch (InvocationTargetException x)
{
- Throwable cause = x.getCause();
- if (cause instanceof Exception)
- throw new MBeanException((Exception)cause);
- else
- throw new MBeanException(new RuntimeException(cause));
+ throw toMBeanException(x);
}
catch (Exception x)
{
@@ -498,5 +515,12 @@ class MetaData
}
return result;
}
+
+ @Override
+ public String toString()
+ {
+ return String.format("%s@%x[%s,proxied=%b,convert=%b]", getClass().getSimpleName(), hashCode(),
+ _name, _proxied, _convert);
+ }
}
}
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java
index 2bd6b08ac6b..5782ffe660e 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java
@@ -139,7 +139,7 @@ public class ObjectMBean implements DynamicMBean
}
@Override
- public Object getAttribute(String name) throws AttributeNotFoundException, ReflectionException
+ public Object getAttribute(String name) throws AttributeNotFoundException, ReflectionException, MBeanException
{
ClassLoader prevLoader = Thread.currentThread().getContextClassLoader();
try
@@ -164,14 +164,15 @@ public class ObjectMBean implements DynamicMBean
}
catch (Throwable x)
{
- LOG.info(x);
+ if (LOG.isDebugEnabled())
+ LOG.debug(x);
}
}
return results;
}
@Override
- public void setAttribute(Attribute attribute) throws AttributeNotFoundException, ReflectionException
+ public void setAttribute(Attribute attribute) throws AttributeNotFoundException, ReflectionException, MBeanException
{
ClassLoader prevLoader = Thread.currentThread().getContextClassLoader();
try
@@ -197,7 +198,8 @@ public class ObjectMBean implements DynamicMBean
}
catch (Throwable x)
{
- LOG.info(x);
+ if (LOG.isDebugEnabled())
+ LOG.debug(x);
}
}
return results;
@@ -227,7 +229,7 @@ public class ObjectMBean implements DynamicMBean
return _mbeanContainer.findBean(objectName);
}
- private MetaData metaData()
+ MetaData metaData()
{
if (_metaData == null)
_metaData = MBeanContainer.findMetaData(_mbeanContainer, _managed.getClass());
diff --git a/jetty-jmx/src/test/java/com/acme/DerivedExtended.java b/jetty-jmx/src/test/java/com/acme/DerivedExtended.java
index b25280e2154..daa3f34aea5 100644
--- a/jetty-jmx/src/test/java/com/acme/DerivedExtended.java
+++ b/jetty-jmx/src/test/java/com/acme/DerivedExtended.java
@@ -25,7 +25,6 @@ import org.eclipse.jetty.util.annotation.ManagedOperation;
@ManagedObject(value = "Test the mbean extended stuff")
public class DerivedExtended extends Derived
{
-
private String doodle4 = "doodle4";
@ManagedAttribute(value = "The doodle4 name of something", name = "doodle4", setter = "setDoodle4")
diff --git a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/MBeanContainerTest.java b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/MBeanContainerTest.java
index ded64808426..630c95374a8 100644
--- a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/MBeanContainerTest.java
+++ b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/MBeanContainerTest.java
@@ -18,24 +18,23 @@
package org.eclipse.jetty.jmx;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import com.acme.Managed;
-
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
+import com.acme.Managed;
import org.eclipse.jetty.util.component.Container;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
public class MBeanContainerTest
{
private MBeanContainer mbeanContainer;
@@ -54,27 +53,21 @@ public class MBeanContainerTest
@Test
public void testMakeName()
{
- // given
beanName = "mngd:bean";
- // when
beanName = mbeanContainer.makeName(beanName);
- // then
assertEquals("mngd_bean", beanName, "Bean name should be mngd_bean");
}
@Test
public void testFindBean()
{
- // given
managed = getManaged();
- // when
objectName = mbeanContainer.findMBean(managed);
assertNotNull(objectName);
- // then
assertEquals(managed, mbeanContainer.findBean(objectName), "Bean must be added");
assertNull(mbeanContainer.findBean(null), "It must return null as there is no bean with the name null");
}
@@ -104,40 +97,31 @@ public class MBeanContainerTest
@Test
public void testDomain()
{
- // given
String domain = "Test";
- // when
mbeanContainer.setDomain(domain);
- // then
assertEquals(domain, mbeanContainer.getDomain(), "Domain name must be Test");
}
@Test
- public void testBeanAdded() throws Exception
+ public void testBeanAdded()
{
- // given
setBeanAdded();
- // when
objectName = mbeanContainer.findMBean(managed);
- // then
assertTrue(mbeanServer.isRegistered(objectName), "Bean must have been registered");
}
@Test
- public void testBeanAddedNullCheck() throws Exception
+ public void testBeanAddedNullCheck()
{
- // given
setBeanAdded();
Integer mbeanCount = mbeanServer.getMBeanCount();
- // when
mbeanContainer.beanAdded(null, null);
- // then
assertEquals(mbeanCount, mbeanServer.getMBeanCount(), "MBean count must not change after beanAdded(null, null) call");
}
@@ -150,15 +134,12 @@ public class MBeanContainerTest
}
@Test
- public void testBeanRemoved() throws Exception
+ public void testBeanRemoved()
{
- // given
setUpBeanRemoved();
- // when
mbeanContainer.beanRemoved(null, managed);
- // then
assertNull(mbeanContainer.findMBean(managed), "Bean shouldn't be registered with container as we removed the bean");
}
@@ -200,30 +181,24 @@ public class MBeanContainerTest
}
@Test
- public void testDestroy() throws Exception
+ public void testDestroy()
{
- // given
setUpDestroy();
- // when
objectName = mbeanContainer.findMBean(managed);
mbeanContainer.destroy();
- // then
assertFalse(mbeanContainer.getMBeanServer().isRegistered(objectName), "Unregistered bean - managed");
}
@Test
public void testDestroyInstanceNotFoundException() throws Exception
{
- // given
setUpDestroy();
- // when
objectName = mbeanContainer.findMBean(managed);
mbeanContainer.getMBeanServer().unregisterMBean(objectName);
- // then
assertFalse(mbeanContainer.getMBeanServer().isRegistered(objectName), "Unregistered bean - managed");
// this flow covers InstanceNotFoundException. Actual code just eating
// the exception. i.e Actual code just printing the stacktrace, whenever
diff --git a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java
index 0fd87499096..00b6b81b952 100644
--- a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java
+++ b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java
@@ -26,202 +26,126 @@ import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import com.acme.Derived;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import com.acme.Managed;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class ObjectMBeanTest
{
- private static final Logger LOG = Log.getLogger(ObjectMBeanTest.class);
-
- private static MBeanContainer container;
+ private MBeanContainer container;
@BeforeEach
- public void before() throws Exception
+ public void before()
{
container = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
}
@AfterEach
- public void after() throws Exception
+ public void after()
{
container.destroy();
container = null;
}
- /*
- * this test uses the com.acme.Derived test classes
- */
+ @Test
+ public void testMetaDataCaching()
+ {
+ Derived derived = new Derived();
+ ObjectMBean derivedMBean = (ObjectMBean)container.mbeanFor(derived);
+ ObjectMBean derivedMBean2 = (ObjectMBean)container.mbeanFor(derived);
+ assertNotSame(derivedMBean, derivedMBean2);
+ assertSame(derivedMBean.metaData(), derivedMBean2.metaData());
+ }
+
@Test
public void testDerivedAttributes() throws Exception
{
Derived derived = new Derived();
- ObjectMBean mbean = (ObjectMBean)ObjectMBean.mbeanFor(derived);
+ Managed managed = derived.getManagedInstance();
+ ObjectMBean derivedMBean = (ObjectMBean)container.mbeanFor(derived);
+ ObjectMBean managedMBean = (ObjectMBean)container.mbeanFor(managed);
- ObjectMBean managed = (ObjectMBean)ObjectMBean.mbeanFor(derived.getManagedInstance());
- mbean.setMBeanContainer(container);
- managed.setMBeanContainer(container);
+ container.beanAdded(null, derived);
+ container.beanAdded(null, managed);
- container.beanAdded(null,derived);
- container.beanAdded(null,derived.getManagedInstance());
+ MBeanInfo derivedInfo = derivedMBean.getMBeanInfo();
+ assertNotNull(derivedInfo);
+ MBeanInfo managedInfo = managedMBean.getMBeanInfo();
+ assertNotNull(managedInfo);
- MBeanInfo toss = managed.getMBeanInfo();
+ assertEquals("com.acme.Derived", derivedInfo.getClassName(), "name does not match");
+ assertEquals("Test the mbean stuff", derivedInfo.getDescription(), "description does not match");
+ assertEquals(6, derivedInfo.getAttributes().length, "attribute count does not match");
+ assertEquals("Full Name", derivedMBean.getAttribute("fname"), "attribute values does not match");
- assertNotNull(mbean.getMBeanInfo());
-
- MBeanInfo info = mbean.getMBeanInfo();
-
- assertEquals("com.acme.Derived", info.getClassName(), "name does not match");
- assertEquals("Test the mbean stuff", info.getDescription(), "description does not match");
-
- // for ( MBeanAttributeInfo i : info.getAttributes())
- // {
- // LOG.debug(i.toString());
- // }
-
- /*
- * 2 attributes from lifecycle and 2 from Derived and 1 from MBean
- */
- assertEquals(6, info.getAttributes().length, "attribute count does not match");
-
- assertEquals("Full Name", mbean.getAttribute("fname"), "attribute values does not match");
-
- mbean.setAttribute(new Attribute("fname","Fuller Name"));
-
- assertEquals("Fuller Name", mbean.getAttribute("fname"), "set attribute value does not match");
-
- assertEquals("goop", mbean.getAttribute("goop"), "proxy attribute values do not match");
-
- // Thread.sleep(100000);
+ derivedMBean.setAttribute(new Attribute("fname", "Fuller Name"));
+ assertEquals("Fuller Name", derivedMBean.getAttribute("fname"), "set attribute value does not match");
+ assertEquals("goop", derivedMBean.getAttribute("goop"), "proxy attribute values do not match");
}
@Test
public void testDerivedOperations() throws Exception
{
Derived derived = new Derived();
- ObjectMBean mbean = (ObjectMBean)ObjectMBean.mbeanFor(derived);
+ ObjectMBean mbean = (ObjectMBean)container.mbeanFor(derived);
- mbean.setMBeanContainer(container);
-
- container.beanAdded(null,derived);
+ container.beanAdded(null, derived);
MBeanInfo info = mbean.getMBeanInfo();
-
assertEquals(5, info.getOperations().length, "operation count does not match");
- MBeanOperationInfo[] opinfos = info.getOperations();
+ MBeanOperationInfo[] operationInfos = info.getOperations();
boolean publish = false;
boolean doodle = false;
boolean good = false;
- for (int i = 0; i < opinfos.length; ++i)
+ for (MBeanOperationInfo operationInfo : operationInfos)
{
- MBeanOperationInfo opinfo = opinfos[i];
-
- if ("publish".equals(opinfo.getName()))
+ if ("publish".equals(operationInfo.getName()))
{
publish = true;
- assertEquals("publish something", opinfo.getDescription(), "description doesn't match");
+ assertEquals("publish something", operationInfo.getDescription(), "description doesn't match");
}
- if ("doodle".equals(opinfo.getName()))
+ if ("doodle".equals(operationInfo.getName()))
{
doodle = true;
- assertEquals("Doodle something", opinfo.getDescription(), "description doesn't match");
-
- MBeanParameterInfo[] pinfos = opinfo.getSignature();
-
- assertEquals("A description of the argument", pinfos[0].getDescription(), "parameter description doesn't match");
- assertEquals("doodle", pinfos[0].getName(), "parameter name doesn't match");
+ assertEquals("Doodle something", operationInfo.getDescription(), "description doesn't match");
+ MBeanParameterInfo[] parameterInfos = operationInfo.getSignature();
+ assertEquals("A description of the argument", parameterInfos[0].getDescription(), "parameter description doesn't match");
+ assertEquals("doodle", parameterInfos[0].getName(), "parameter name doesn't match");
}
- // This is a proxied operation on the JMX wrapper
- if ("good".equals(opinfo.getName()))
+ // This is a proxied operation on the MBean wrapper.
+ if ("good".equals(operationInfo.getName()))
{
good = true;
-
- assertEquals("test of proxy operations", opinfo.getDescription(), "description does not match");
- assertEquals("not bad",mbean.invoke("good",new Object[] {}, new String[] {}), "execution contexts wrong");
+ assertEquals("test of proxy operations", operationInfo.getDescription(), "description does not match");
+ assertEquals("not bad", mbean.invoke("good", new Object[]{}, new String[]{}), "execution contexts wrong");
}
}
assertTrue(publish, "publish operation was not not found");
assertTrue(doodle, "doodle operation was not not found");
assertTrue(good, "good operation was not not found");
-
}
@Test
- public void testDerivedObjectAttributes() throws Exception
+ public void testMethodNameMining()
{
- Derived derived = new Derived();
- ObjectMBean mbean = (ObjectMBean)ObjectMBean.mbeanFor(derived);
-
- ObjectMBean managed = (ObjectMBean)ObjectMBean.mbeanFor(derived.getManagedInstance());
- mbean.setMBeanContainer(container);
- managed.setMBeanContainer(container);
-
- assertNotNull(mbean.getMBeanInfo());
-
- container.beanAdded(null,derived);
- container.beanAdded(null,derived.getManagedInstance());
- container.beanAdded(null,mbean);
- container.beanAdded(null,managed);
-
- // Managed managedInstance = (Managed)mbean.getAttribute("managedInstance");
- // assertNotNull(managedInstance);
- // assertEquals("foo", managedInstance.getManaged(), "managed instance returning nonsense");
-
+ assertEquals("fullName", MetaData.toAttributeName("getFullName"));
+ assertEquals("fullName", MetaData.toAttributeName("getfullName"));
+ assertEquals("fullName", MetaData.toAttributeName("isFullName"));
+ assertEquals("fullName", MetaData.toAttributeName("isfullName"));
+ assertEquals("fullName", MetaData.toAttributeName("setFullName"));
+ assertEquals("fullName", MetaData.toAttributeName("setfullName"));
+ assertEquals("fullName", MetaData.toAttributeName("FullName"));
+ assertEquals("fullName", MetaData.toAttributeName("fullName"));
}
-
- @Test
- @Disabled("ignore, used in testing jconsole atm")
- public void testThreadPool() throws Exception
- {
-
- Derived derived = new Derived();
- ObjectMBean mbean = (ObjectMBean)ObjectMBean.mbeanFor(derived);
-
- ObjectMBean managed = (ObjectMBean)ObjectMBean.mbeanFor(derived.getManagedInstance());
- mbean.setMBeanContainer(container);
- managed.setMBeanContainer(container);
-
- QueuedThreadPool qtp = new QueuedThreadPool();
-
- ObjectMBean bqtp = (ObjectMBean)ObjectMBean.mbeanFor(qtp);
-
- bqtp.getMBeanInfo();
-
- container.beanAdded(null,derived);
- container.beanAdded(null,derived.getManagedInstance());
- container.beanAdded(null,mbean);
- container.beanAdded(null,managed);
- container.beanAdded(null,qtp);
-
- Thread.sleep(10000000);
-
- }
-
- @Test
- public void testMethodNameMining() throws Exception
- {
- ObjectMBean mbean = new ObjectMBean(new Derived());
-
- assertEquals("fullName",MetaData.toAttributeName("getFullName"));
- assertEquals("fullName",MetaData.toAttributeName("getfullName"));
- assertEquals("fullName",MetaData.toAttributeName("isFullName"));
- assertEquals("fullName",MetaData.toAttributeName("isfullName"));
- assertEquals("fullName",MetaData.toAttributeName("setFullName"));
- assertEquals("fullName",MetaData.toAttributeName("setfullName"));
- assertEquals("fullName",MetaData.toAttributeName("FullName"));
- assertEquals("fullName",MetaData.toAttributeName("fullName"));
- }
-
}
diff --git a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanUtilTest.java b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanUtilTest.java
index cebfc1d9e42..0f1321bbbfe 100644
--- a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanUtilTest.java
+++ b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanUtilTest.java
@@ -32,11 +32,6 @@ import javax.management.ReflectionException;
import com.acme.Derived;
import com.acme.DerivedExtended;
import com.acme.DerivedManaged;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.log.StdErrLog;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -47,56 +42,20 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
public class ObjectMBeanUtilTest
{
-
private ObjectMBean objectMBean;
-
private DerivedExtended derivedExtended;
-
private MBeanContainer container;
-
private MBeanInfo objectMBeanInfo;
-
- private Object mBean;
-
- private String value;
-
private Attribute attribute;
-
- private AttributeList attributes;
-
private ObjectMBean mBeanDerivedManaged;
-
- private Derived[] derivedes;
-
- private ArrayList aliasNames;
-
private DerivedManaged derivedManaged;
- private static final int EMPTY = 0;
-
- @BeforeAll
- public static void beforeClass()
- {
- Logger ombLog = Log.getLogger(ObjectMBean.class);
- if (ombLog instanceof StdErrLog && !ombLog.isDebugEnabled())
- ((StdErrLog)ombLog).setHideStacks(true);
- }
-
- @AfterAll
- public static void afterClass()
- {
- Logger ombLog = Log.getLogger(ObjectMBean.class);
- if (ombLog instanceof StdErrLog)
- ((StdErrLog)ombLog).setHideStacks(false);
- }
-
@BeforeEach
public void setUp()
{
- derivedExtended = new DerivedExtended();
- objectMBean = new ObjectMBean(derivedExtended);
container = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
- objectMBean.setMBeanContainer(container);
+ derivedExtended = new DerivedExtended();
+ objectMBean = (ObjectMBean)container.mbeanFor(derivedExtended);
objectMBeanInfo = objectMBean.getMBeanInfo();
}
@@ -114,131 +73,93 @@ public class ObjectMBeanUtilTest
@Test
public void testMbeanForNullCheck()
{
- // when
- mBean = ObjectMBean.mbeanFor(null);
-
- // then
+ Object mBean = container.mbeanFor(null);
assertNull(mBean, "As we are passing null value the output should be null");
}
@Test
- public void testGetAttributeReflectionException() throws Exception
+ public void testGetAttributeMBeanException() throws Exception
{
- // given
- setUpGetAttribute("doodle4","charu");
+ Attribute attribute = new Attribute("doodle4", "charu");
+ objectMBean.setAttribute(attribute);
- // when
- ReflectionException e = assertThrows(ReflectionException.class, ()-> {
- objectMBean.getAttribute("doodle4");
- });
+ MBeanException e = assertThrows(MBeanException.class, () -> objectMBean.getAttribute("doodle4"));
- // then
assertNotNull(e, "An InvocationTargetException must have occurred by now as doodle4() internally throwing exception");
}
- private void setUpGetAttribute(String property, String value) throws Exception
- {
- Attribute attribute = new Attribute(property,value);
- objectMBean.setAttribute(attribute);
- }
-
@Test
- public void testGetAttributeAttributeNotFoundException() throws Exception
+ public void testGetAttributeAttributeNotFoundException()
{
- // when
- AttributeNotFoundException e = assertThrows(AttributeNotFoundException.class, ()->{
- objectMBean.getAttribute("ffname");
- });
+ AttributeNotFoundException e = assertThrows(AttributeNotFoundException.class, () -> objectMBean.getAttribute("ffname"));
- // then
- assertNotNull(e, "An AttributeNotFoundException must have occurred by now as there is no " + "attribute with the name ffname in bean");
+ assertNotNull(e, "An AttributeNotFoundException must have occurred by now as there is no attribute with the name ffname in bean");
}
@Test
public void testSetAttributeWithCorrectAttrName() throws Exception
{
- // given
- setUpGetAttribute("fname","charu");
+ Attribute attribute = new Attribute("fname", "charu");
+ objectMBean.setAttribute(attribute);
- // when
- value = (String)objectMBean.getAttribute("fname");
+ String value = (String)objectMBean.getAttribute("fname");
- // then
- assertEquals("charu", value, "Attribute(fname) value must be equl to charu");
+ assertEquals("charu", value, "Attribute(fname) value must be equal to charu");
}
@Test
public void testSetAttributeNullCheck() throws Exception
{
- // given
objectMBean.setAttribute(null);
- // when
- AttributeNotFoundException e = assertThrows(AttributeNotFoundException.class, ()->{
- objectMBean.getAttribute(null);
- });
+ AttributeNotFoundException e = assertThrows(AttributeNotFoundException.class, () -> objectMBean.getAttribute(null));
- // then
- assertNotNull(e,"An AttributeNotFoundException must have occurred by now as there is no attribute with the name null");
+ assertNotNull(e, "An AttributeNotFoundException must have occurred by now as there is no attribute with the name null");
}
@Test
- public void testSetAttributeAttributeWithWrongAttrName() throws Exception
+ public void testSetAttributeAttributeWithWrongAttrName()
{
- // given
- attribute = new Attribute("fnameee","charu");
+ attribute = new Attribute("fnameee", "charu");
- // when
- AttributeNotFoundException e = assertThrows(AttributeNotFoundException.class, ()->{
- objectMBean.setAttribute(attribute);
- });
+ AttributeNotFoundException e = assertThrows(AttributeNotFoundException.class, () -> objectMBean.setAttribute(attribute));
- // then
assertNotNull(e, "An AttributeNotFoundException must have occurred by now as there is no attribute " + "with the name ffname in bean");
}
@Test
- public void testSetAttributesWithCorrectValues() throws Exception
+ public void testSetAttributesWithCorrectValues()
{
- // given
- attributes = getAttributes("fname","vijay");
- attributes = objectMBean.setAttributes(attributes);
+ AttributeList attributes = getAttributes("fname", "vijay");
+ objectMBean.setAttributes(attributes);
- // when
- attributes = objectMBean.getAttributes(new String[]
- { "fname" });
+ attributes = objectMBean.getAttributes(new String[]{"fname"});
- // then
+ assertEquals(1, attributes.size());
assertEquals("vijay", ((Attribute)(attributes.get(0))).getValue(), "Fname value must be equal to vijay");
}
@Test
- public void testSetAttributesForArrayTypeAttribue() throws Exception
+ public void testSetAttributesForArrayTypeAttribute() throws Exception
{
- // given
- derivedes = getArrayTypeAttribute();
+ Derived[] deriveds = getArrayTypeAttribute();
- // when
- derivedManaged.setAddresses(derivedes);
+ derivedManaged.setAddresses(deriveds);
mBeanDerivedManaged.getMBeanInfo();
- // then
assertNotNull(mBeanDerivedManaged.getAttribute("addresses"), "Address object shouldn't be null");
}
@Test
public void testSetAttributesForCollectionTypeAttribue() throws Exception
{
- // given
- aliasNames = getCollectionTypeAttribute();
+ ArrayList aliasNames = new ArrayList<>(Arrays.asList(getArrayTypeAttribute()));
- // when
derivedManaged.setAliasNames(aliasNames);
mBeanDerivedManaged.getMBeanInfo();
- // then
assertNotNull(mBeanDerivedManaged.getAttribute("aliasNames"), "Address object shouldn't be null");
- assertNull(mBeanDerivedManaged.getAttribute("derived"), "Derived object shouldn't registerd with container so its value will be null");
+ assertNull(mBeanDerivedManaged.getAttribute("derived"), "Derived object shouldn't registered with container so its value will be null");
}
private Derived[] getArrayTypeAttribute()
@@ -248,119 +169,74 @@ public class ObjectMBeanUtilTest
MBeanContainer mBeanDerivedManagedContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
mBeanDerivedManaged.setMBeanContainer(mBeanDerivedManagedContainer);
Derived derived0 = new Derived();
- mBeanDerivedManagedContainer.beanAdded(null,derived0);
- Derived[] derivedes = new Derived[3];
+ mBeanDerivedManagedContainer.beanAdded(null, derived0);
+ Derived[] deriveds = new Derived[3];
for (int i = 0; i < 3; i++)
- {
- derivedes[i] = new Derived();
- }
- derivedManaged.setAddresses(derivedes);
+ deriveds[i] = new Derived();
+ derivedManaged.setAddresses(deriveds);
mBeanDerivedManaged.getMBeanInfo();
- ArrayList aliasNames = new ArrayList(Arrays.asList(derivedes));
+ ArrayList aliasNames = new ArrayList<>(Arrays.asList(deriveds));
derivedManaged.setAliasNames(aliasNames);
- return derivedes;
- }
-
- private ArrayList getCollectionTypeAttribute()
- {
- ArrayList aliasNames = new ArrayList(Arrays.asList(getArrayTypeAttribute()));
- return aliasNames;
+ return deriveds;
}
@Test
public void testSetAttributesException()
{
- // given
- attributes = getAttributes("fnameee","charu");
+ AttributeList attributes = getAttributes("fnameee", "charu");
- // when
attributes = objectMBean.setAttributes(attributes);
- // then
// Original code eating the exception and returning zero size list
- assertEquals(EMPTY,attributes.size(),"As there is no attribute with the name fnameee, this should return empty");
+ assertEquals(0, attributes.size(), "As there is no attribute with the name fnameee, this should return empty");
}
private AttributeList getAttributes(String name, String value)
{
- Attribute attribute = new Attribute(name,value);
+ Attribute attribute = new Attribute(name, value);
AttributeList attributes = new AttributeList();
attributes.add(attribute);
return attributes;
}
@Test
- public void testInvokeMBeanException() throws Exception
+ public void testInvokeMBeanException()
{
- // given
- setMBeanInfoForInvoke();
+ ReflectionException e = assertThrows(ReflectionException.class, () -> objectMBean.invoke("doodle2", new Object[0], new String[0]));
- // when
- ReflectionException e = assertThrows(ReflectionException.class, ()->{
- objectMBean.invoke("doodle2",new Object[] {},new String[] {});
- });
-
- // then
assertNotNull(e, "An ReflectionException must have occurred by now as doodle2() in Derived bean is private");
}
@Test
- public void testInvokeReflectionException() throws Exception
+ public void testInvokeReflectionException()
{
- // given
- setMBeanInfoForInvoke();
+ MBeanException e = assertThrows(MBeanException.class, () -> objectMBean.invoke("doodle1", new Object[0], new String[0]));
- // when
- MBeanException e = assertThrows(MBeanException.class, ()->{
- objectMBean.invoke("doodle1",new Object[] {},new String[] {});
- });
-
- // then
assertNotNull(e, "MBeanException is null");
}
@Test
public void testInvoke() throws Exception
{
- // given
- setMBeanInfoForInvoke();
+ String value = (String)objectMBean.invoke("good", new Object[0], new String[0]);
- // when
- value = (String)objectMBean.invoke("good",new Object[] {},new String[] {});
-
- // then
assertEquals("not bad", value, "Method(good) invocation on objectMBean must return not bad");
}
@Test
- public void testInvokeNoSuchMethodException() throws Exception
+ public void testInvokeNoSuchMethodException()
{
- // given
- setMBeanInfoForInvoke();
+ // DerivedMBean contains a managed method with the name good,
+ // we must call this method without any arguments.
+ ReflectionException e = assertThrows(ReflectionException.class, () ->
+ objectMBean.invoke("good", new Object[0], new String[]{"int aone"}));
- // when
- // DerivedMBean contains a managed method with the name good,we must
- // call this method without any arguments
- ReflectionException e = assertThrows(ReflectionException.class, ()->{
- objectMBean.invoke("good",new Object[] {},new String[]
- { "int aone" });
- });
-
- // then
assertNotNull(e, "An ReflectionException must have occurred by now as we cannot call a methow with wrong signature");
-
- }
-
- private void setMBeanInfoForInvoke()
- {
- objectMBean = (ObjectMBean)ObjectMBean.mbeanFor(derivedExtended);
- container.beanAdded(null,derivedExtended);
- objectMBean.getMBeanInfo();
}
@Test
- public void testToVariableName()
+ public void testToAttributeName()
{
- assertEquals("fullName",MetaData.toAttributeName("isfullName"));
+ assertEquals("fullName", MetaData.toAttributeName("isfullName"));
}
}
diff --git a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/PojoTest.java b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/PojoTest.java
index 3ea782d22ff..2d1aad0bae0 100644
--- a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/PojoTest.java
+++ b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/PojoTest.java
@@ -20,27 +20,25 @@ package org.eclipse.jetty.jmx;
import java.util.Arrays;
import java.util.List;
-import org.eclipse.jetty.util.log.jmx.LogMBean;
-import org.junit.jupiter.api.Test;
+
import com.openpojo.reflection.impl.PojoClassFactory;
import com.openpojo.validation.Validator;
import com.openpojo.validation.ValidatorBuilder;
import com.openpojo.validation.test.impl.GetterTester;
import com.openpojo.validation.test.impl.SetterTester;
+import org.eclipse.jetty.util.log.jmx.LogMBean;
+import org.junit.jupiter.api.Test;
/*
* This class tests all the getters and setters for a given list of classes.
*/
public class PojoTest
{
-
- private Validator validator;
-
@Test
public void testOpenPojo()
{
- validator = ValidatorBuilder.create().with(new SetterTester()).with(new GetterTester()).build();
- List classes = Arrays.asList(MBeanContainer.class,ObjectMBean.class,LogMBean.class);
+ Validator validator = ValidatorBuilder.create().with(new SetterTester()).with(new GetterTester()).build();
+ List classes = Arrays.asList(MBeanContainer.class, ObjectMBean.class, LogMBean.class);
for (Class clazz : classes)
{
validator.validate(PojoClassFactory.getPojoClass(clazz));
diff --git a/jetty-jmx/src/test/resources/jetty-logging.properties b/jetty-jmx/src/test/resources/jetty-logging.properties
index f0392ad78c1..ad4b63c91cc 100644
--- a/jetty-jmx/src/test/resources/jetty-logging.properties
+++ b/jetty-jmx/src/test/resources/jetty-logging.properties
@@ -1,2 +1,2 @@
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
-org.eclipse.jetty.jmx.LEVEL=INFO
+#org.eclipse.jetty.jmx.LEVEL=DEBUG
From 87f39449a9283282a5b04854aed75032331b3cd6 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Fri, 21 Sep 2018 10:56:13 +0200
Subject: [PATCH 037/931] Issue #2727 - Revisit JMX MBean lookup behavior.
Fixed NPE in case the class is an interface.
Signed-off-by: Simone Bordet
---
jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
index c081178b050..b7d978a37cc 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
@@ -217,7 +217,7 @@ class MetaData
klass = klass.getComponentType();
if (klass.isPrimitive())
return false;
- while (klass != Object.class)
+ while (klass != null)
{
if (klass.isAnnotationPresent(ManagedObject.class))
return true;
From 2673ae98c2d44c1253366e7d3205109ae0f6d4b8 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Fri, 21 Sep 2018 17:56:43 +0200
Subject: [PATCH 038/931] Issue #2727 - Revisit JMX MBean lookup behavior.
Optimized creation of MBeanInfo.
Rather than collecting attributes from the whole hierarchy,
just merge the local attributes with the ones from the parent,
using a Set to discard duplicates.
Signed-off-by: Simone Bordet
---
.../java/org/eclipse/jetty/jmx/MetaData.java | 28 +++++++++++++------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
index b7d978a37cc..6ac8fd60284 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
@@ -24,12 +24,13 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Set;
import java.util.stream.Collectors;
import javax.management.Attribute;
@@ -75,7 +76,6 @@ class MetaData
else
parseMethods(klass);
_info = buildMBeanInfo(klass);
-
}
Object newInstance(Object bean)
@@ -244,35 +244,45 @@ class MetaData
ManagedObject managedObject = klass.getAnnotation(ManagedObject.class);
String description = managedObject == null ? "" : managedObject.value();
- List attributeInfos = new ArrayList<>();
+ Set attributeInfos = new HashSet<>();
collectMBeanAttributeInfos(attributeInfos);
- List operationInfos = new ArrayList<>();
+ Set operationInfos = new HashSet<>();
collectMBeanOperationInfos(operationInfos);
- return new MBeanInfo(klass.getName(), description, attributeInfos.toArray(new MBeanAttributeInfo[0]), new MBeanConstructorInfo[0], operationInfos.toArray(new MBeanOperationInfo[0]), new MBeanNotificationInfo[0]);
+ MBeanAttributeInfo[] attributes = attributeInfos.toArray(new MBeanAttributeInfo[0]);
+ MBeanOperationInfo[] operations = operationInfos.toArray(new MBeanOperationInfo[0]);
+ return new MBeanInfo(klass.getName(), description, attributes, new MBeanConstructorInfo[0], operations, new MBeanNotificationInfo[0]);
}
- private void collectMBeanAttributeInfos(List attributeInfos)
+ private void collectMBeanAttributeInfos(Set attributeInfos)
{
+ // Priority to local attributes, then to interfaces then to superClass.
_attributes.values().stream()
.map(info -> info._info)
.collect(Collectors.toCollection(() -> attributeInfos));
for (MetaData intf : _interfaces)
intf.collectMBeanAttributeInfos(attributeInfos);
if (_parent != null)
- _parent.collectMBeanAttributeInfos(attributeInfos);
+ {
+ MBeanInfo parentInfo = _parent.getMBeanInfo();
+ attributeInfos.addAll(Arrays.asList(parentInfo.getAttributes()));
+ }
}
- private void collectMBeanOperationInfos(List operationInfos)
+ private void collectMBeanOperationInfos(Set operationInfos)
{
+ // Priority to local operations, then to interfaces then to superClass.
_operations.values().stream()
.map(info -> info._info)
.collect(Collectors.toCollection(() -> operationInfos));
for (MetaData intf : _interfaces)
intf.collectMBeanOperationInfos(operationInfos);
if (_parent != null)
- _parent.collectMBeanOperationInfos(operationInfos);
+ {
+ MBeanInfo parentInfo = _parent.getMBeanInfo();
+ operationInfos.addAll(Arrays.asList(parentInfo.getOperations()));
+ }
}
private static MBeanException toMBeanException(InvocationTargetException x)
From 53565047e0bb4b3f5db448ce4b9b4aa1ccd1e8e8 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Sun, 23 Sep 2018 12:06:53 +0200
Subject: [PATCH 039/931] Issue #2727 - Revisit JMX MBean lookup behavior.
Fixed creation of MBeanInfo.
Avoiding duplicating *Info by collecting them in a Map.
Signed-off-by: Simone Bordet
---
.../org/eclipse/jetty/jmx/MBeanContainer.java | 2 +
.../java/org/eclipse/jetty/jmx/MetaData.java | 53 +++++++++++--------
2 files changed, 33 insertions(+), 22 deletions(-)
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
index 3f2ea7bb4f9..fb324bf1aae 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
@@ -196,6 +196,8 @@ public class MBeanContainer implements Container.InheritedListener, Dumpable, De
MetaData existing = container._metaData.putIfAbsent(klass, metaData);
if (existing != null)
metaData = existing;
+ if (LOG.isDebugEnabled())
+ LOG.debug("Cached {}", metaData);
}
}
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
index 6ac8fd60284..425422f5a5f 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
@@ -26,11 +26,9 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
-import java.util.Set;
import java.util.stream.Collectors;
import javax.management.Attribute;
@@ -56,6 +54,10 @@ import org.eclipse.jetty.util.log.Logger;
class MetaData
{
private static final Logger LOG = Log.getLogger(MetaData.class);
+ private static final MBeanAttributeInfo[] NO_ATTRIBUTES = new MBeanAttributeInfo[0];
+ private static final MBeanConstructorInfo[] NO_CONSTRUCTORS = new MBeanConstructorInfo[0];
+ private static final MBeanOperationInfo[] NO_OPERATIONS = new MBeanOperationInfo[0];
+ private static final MBeanNotificationInfo[] NO_NOTIFICATIONS = new MBeanNotificationInfo[0];
private final Map _attributes = new HashMap<>();
private final Map _operations = new HashMap<>();
@@ -244,45 +246,51 @@ class MetaData
ManagedObject managedObject = klass.getAnnotation(ManagedObject.class);
String description = managedObject == null ? "" : managedObject.value();
- Set attributeInfos = new HashSet<>();
+ Map attributeInfos = new HashMap<>();
collectMBeanAttributeInfos(attributeInfos);
- Set operationInfos = new HashSet<>();
+ Map operationInfos = new HashMap<>();
collectMBeanOperationInfos(operationInfos);
- MBeanAttributeInfo[] attributes = attributeInfos.toArray(new MBeanAttributeInfo[0]);
- MBeanOperationInfo[] operations = operationInfos.toArray(new MBeanOperationInfo[0]);
- return new MBeanInfo(klass.getName(), description, attributes, new MBeanConstructorInfo[0], operations, new MBeanNotificationInfo[0]);
+ MBeanInfo mbeanInfo = _parent == null ? null : _parent.getMBeanInfo();
+ MBeanAttributeInfo[] attributes = attributeInfos.values().toArray(NO_ATTRIBUTES);
+ MBeanConstructorInfo[] constructors = mbeanInfo == null ? NO_CONSTRUCTORS : mbeanInfo.getConstructors();
+ MBeanOperationInfo[] operations = operationInfos.values().toArray(NO_OPERATIONS);
+ MBeanNotificationInfo[] notifications = mbeanInfo == null ? NO_NOTIFICATIONS : mbeanInfo.getNotifications();
+ return new MBeanInfo(klass.getName(), description, attributes, constructors, operations, notifications);
}
- private void collectMBeanAttributeInfos(Set attributeInfos)
+ private void collectMBeanAttributeInfos(Map attributeInfos)
{
- // Priority to local attributes, then to interfaces then to superClass.
- _attributes.values().stream()
- .map(info -> info._info)
- .collect(Collectors.toCollection(() -> attributeInfos));
+ // Start with interfaces, overwrite with superClass, then overwrite with local attributes.
for (MetaData intf : _interfaces)
intf.collectMBeanAttributeInfos(attributeInfos);
if (_parent != null)
{
- MBeanInfo parentInfo = _parent.getMBeanInfo();
- attributeInfos.addAll(Arrays.asList(parentInfo.getAttributes()));
+ MBeanAttributeInfo[] parentAttributes = _parent.getMBeanInfo().getAttributes();
+ for (MBeanAttributeInfo parentAttribute : parentAttributes)
+ attributeInfos.put(parentAttribute.getName(), parentAttribute);
}
+ for (Map.Entry entry : _attributes.entrySet())
+ attributeInfos.put(entry.getKey(), entry.getValue()._info);
}
- private void collectMBeanOperationInfos(Set operationInfos)
+ private void collectMBeanOperationInfos(Map operationInfos)
{
- // Priority to local operations, then to interfaces then to superClass.
- _operations.values().stream()
- .map(info -> info._info)
- .collect(Collectors.toCollection(() -> operationInfos));
+ // Start with interfaces, overwrite with superClass, then overwrite with local operations.
for (MetaData intf : _interfaces)
intf.collectMBeanOperationInfos(operationInfos);
if (_parent != null)
{
- MBeanInfo parentInfo = _parent.getMBeanInfo();
- operationInfos.addAll(Arrays.asList(parentInfo.getOperations()));
+ MBeanOperationInfo[] parentOperations = _parent.getMBeanInfo().getOperations();
+ for (MBeanOperationInfo parentOperation : parentOperations)
+ {
+ String signature = signature(parentOperation.getName(), Arrays.stream(parentOperation.getSignature()).map(MBeanParameterInfo::getType).toArray(String[]::new));
+ operationInfos.put(signature, parentOperation);
+ }
}
+ for (Map.Entry entry : _operations.entrySet())
+ operationInfos.put(entry.getKey(), entry.getValue()._info);
}
private static MBeanException toMBeanException(InvocationTargetException x)
@@ -297,7 +305,8 @@ class MetaData
@Override
public String toString()
{
- return String.format("%s@%x[%s]", getClass().getSimpleName(), hashCode(), _klass.getName());
+ return String.format("%s@%x[%s, attrs=%s, opers=%s]", getClass().getSimpleName(), hashCode(),
+ _klass.getName(), _attributes.keySet(), _operations.keySet());
}
private static class AttributeInfo
From 304eac7460974a1690cb0b755dcd88a7fcdd21ff Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Mon, 24 Sep 2018 16:41:03 +1000
Subject: [PATCH 040/931] improved debug (more to do)
Signed-off-by: Greg Wilkins
---
.../src/main/resources/jetty-logging.properties | 1 +
.../java/org/eclipse/jetty/jmx/MBeanContainer.java | 12 ++++++++++++
.../main/java/org/eclipse/jetty/jmx/MetaData.java | 12 ++++++++----
.../org/eclipse/jetty/server/AbstractConnector.java | 2 +-
4 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/examples/embedded/src/main/resources/jetty-logging.properties b/examples/embedded/src/main/resources/jetty-logging.properties
index 810f9896c7e..08b834611b3 100644
--- a/examples/embedded/src/main/resources/jetty-logging.properties
+++ b/examples/embedded/src/main/resources/jetty-logging.properties
@@ -9,3 +9,4 @@
#org.eclipse.jetty.server.LEVEL=DEBUG
#org.eclipse.jetty.servlets.LEVEL=DEBUG
#org.eclipse.jetty.alpn.LEVEL=DEBUG
+org.eclipse.jetty.jmx.LEVEL=DEBUG
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
index fb324bf1aae..1a49a9ee80e 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
@@ -32,6 +32,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import javax.management.InstanceNotFoundException;
+import javax.management.MBeanInfo;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
@@ -154,7 +155,18 @@ public class MBeanContainer implements Container.InheritedListener, Dumpable, De
if (mbean instanceof ObjectMBean)
((ObjectMBean)mbean).setMBeanContainer(container);
if (LOG.isDebugEnabled())
+ {
LOG.debug("MBean for {} is {}", o, mbean);
+ if (mbean instanceof ObjectMBean)
+ {
+ MBeanInfo info =((ObjectMBean)mbean).getMBeanInfo();
+ for (Object a :info.getAttributes())
+ LOG.debug(" {}", a);
+ for (Object a :info.getOperations())
+ LOG.debug(" {}", a);
+
+ }
+ }
return mbean;
}
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
index 425422f5a5f..24d80292968 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
@@ -188,7 +188,7 @@ class MetaData
{
AttributeInfo info = new AttributeInfo(attribute, method);
if (LOG.isDebugEnabled())
- LOG.debug("Found attribute for {}: {}", klass.getName(), info);
+ LOG.debug("Found attribute {} for {}: {}", info._name, klass.getName(), info);
_attributes.put(info._name, info);
}
ManagedOperation operation = method.getAnnotation(ManagedOperation.class);
@@ -196,7 +196,7 @@ class MetaData
{
OperationInfo info = new OperationInfo(operation, method);
if (LOG.isDebugEnabled())
- LOG.debug("Found operation for {}: {}", klass.getName(), info);
+ LOG.debug("Found operation {} for {}: {}", info._name, klass.getName(), info);
_operations.put(info._name, info);
}
}
@@ -375,6 +375,8 @@ class MetaData
void setAttribute(Object value, ObjectMBean mbean) throws ReflectionException, MBeanException
{
+ if (LOG.isDebugEnabled())
+ LOG.debug("setAttribute {}.{}={} {}",mbean,_info.getName(), value, _info);
try
{
if (_setter == null)
@@ -441,8 +443,8 @@ class MetaData
@Override
public String toString()
{
- return String.format("%s@%x[%s,proxied=%b,convert=%b]", getClass().getSimpleName(), hashCode(),
- _name, _proxied, _convert);
+ return String.format("%s@%x[%s,proxied=%b,convert=%b,info=%s]", getClass().getSimpleName(), hashCode(),
+ _name, _proxied, _convert, _info);
}
}
@@ -484,6 +486,8 @@ class MetaData
public Object invoke(Object[] args, ObjectMBean mbean) throws ReflectionException, MBeanException
{
+ if (LOG.isDebugEnabled())
+ LOG.debug("invoke {}.{}({}) {}",mbean,_info.getName(), Arrays.asList(args), _info);
try
{
Object target = mbean.getManagedObject();
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
index 224f523b129..80d61b8dd09 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
@@ -226,7 +226,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
}
@Override
- @ManagedAttribute("Idle timeout")
+ @ManagedAttribute
public long getIdleTimeout()
{
return _idleTimeout;
From 87aba86d745257314363cd9e75b0b9ba45a3c2f2 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Mon, 24 Sep 2018 17:00:58 +1000
Subject: [PATCH 041/931] fix findAttribute
Signed-off-by: Greg Wilkins
---
.../java/org/eclipse/jetty/jmx/MetaData.java | 25 +++++++++++++------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
index 24d80292968..11b0fda18e1 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
@@ -120,18 +120,27 @@ class MetaData
{
if (name == null)
return null;
- AttributeInfo result = _attributes.get(name);
- if (result != null)
- return result;
+
+ AttributeInfo result = null;
for (MetaData intf : _interfaces)
{
- result = intf.findAttribute(name);
- if (result != null)
- return result;
+ AttributeInfo r = intf.findAttribute(name);
+ if (r != null)
+ result = r;
}
+
if (_parent != null)
- return _parent.findAttribute(name);
- return null;
+ {
+ AttributeInfo r = _parent.findAttribute(name);
+ if (r != null)
+ result = r;
+ }
+
+ AttributeInfo r = _attributes.get(name);
+ if (r != null)
+ result = r;
+
+ return result;
}
Object invoke(String name, String[] params, Object[] args, ObjectMBean mbean) throws ReflectionException, MBeanException
From 92e70f2c84fc8fe017fe361f32adca875c7b05e7 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Mon, 24 Sep 2018 10:49:29 +0200
Subject: [PATCH 042/931] Issue #2727 - Revisit JMX MBean lookup behavior.
Fixed invoke() lookup.
Signed-off-by: Simone Bordet
---
.../main/resources/jetty-logging.properties | 2 +-
.../org/eclipse/jetty/jmx/MBeanContainer.java | 11 ++++----
.../java/org/eclipse/jetty/jmx/MetaData.java | 28 ++++++++++++-------
.../jetty/server/AbstractConnector.java | 2 +-
4 files changed, 25 insertions(+), 18 deletions(-)
diff --git a/examples/embedded/src/main/resources/jetty-logging.properties b/examples/embedded/src/main/resources/jetty-logging.properties
index 08b834611b3..c0a226179d4 100644
--- a/examples/embedded/src/main/resources/jetty-logging.properties
+++ b/examples/embedded/src/main/resources/jetty-logging.properties
@@ -9,4 +9,4 @@
#org.eclipse.jetty.server.LEVEL=DEBUG
#org.eclipse.jetty.servlets.LEVEL=DEBUG
#org.eclipse.jetty.alpn.LEVEL=DEBUG
-org.eclipse.jetty.jmx.LEVEL=DEBUG
+#org.eclipse.jetty.jmx.LEVEL=DEBUG
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
index 1a49a9ee80e..17ef201b4e7 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
@@ -159,12 +159,11 @@ public class MBeanContainer implements Container.InheritedListener, Dumpable, De
LOG.debug("MBean for {} is {}", o, mbean);
if (mbean instanceof ObjectMBean)
{
- MBeanInfo info =((ObjectMBean)mbean).getMBeanInfo();
- for (Object a :info.getAttributes())
- LOG.debug(" {}", a);
- for (Object a :info.getOperations())
- LOG.debug(" {}", a);
-
+ MBeanInfo info = ((ObjectMBean)mbean).getMBeanInfo();
+ for (Object a : info.getAttributes())
+ LOG.debug(" {}", a);
+ for (Object a : info.getOperations())
+ LOG.debug(" {}", a);
}
}
return mbean;
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
index 11b0fda18e1..c290c727770 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java
@@ -154,18 +154,26 @@ class MetaData
private OperationInfo findOperation(String signature)
{
- OperationInfo result = _operations.get(signature);
- if (result != null)
- return result;
+ OperationInfo result = null;
for (MetaData intf : _interfaces)
{
- result = intf.findOperation(signature);
- if (result != null)
- return result;
+ OperationInfo r = intf.findOperation(signature);
+ if (r != null)
+ result = r;
}
+
if (_parent != null)
- return _parent.findOperation(signature);
- return null;
+ {
+ OperationInfo r = _parent.findOperation(signature);
+ if (r != null)
+ result = r;
+ }
+
+ OperationInfo r = _operations.get(signature);
+ if (r != null)
+ result = r;
+
+ return result;
}
private static Object newInstance(Constructor> constructor, Object bean)
@@ -385,7 +393,7 @@ class MetaData
void setAttribute(Object value, ObjectMBean mbean) throws ReflectionException, MBeanException
{
if (LOG.isDebugEnabled())
- LOG.debug("setAttribute {}.{}={} {}",mbean,_info.getName(), value, _info);
+ LOG.debug("setAttribute {}.{}={} {}", mbean, _info.getName(), value, _info);
try
{
if (_setter == null)
@@ -496,7 +504,7 @@ class MetaData
public Object invoke(Object[] args, ObjectMBean mbean) throws ReflectionException, MBeanException
{
if (LOG.isDebugEnabled())
- LOG.debug("invoke {}.{}({}) {}",mbean,_info.getName(), Arrays.asList(args), _info);
+ LOG.debug("invoke {}.{}({}) {}", mbean, _info.getName(), Arrays.asList(args), _info);
try
{
Object target = mbean.getManagedObject();
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
index 80d61b8dd09..ec7b51c62b4 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
@@ -226,7 +226,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
}
@Override
- @ManagedAttribute
+ @ManagedAttribute("The connection idle timeout in milliseconds")
public long getIdleTimeout()
{
return _idleTimeout;
From 08d0092cbde6fda3f664dd34b272c9fcd07c357f Mon Sep 17 00:00:00 2001
From: Olivier Lamy
Date: Tue, 25 Sep 2018 20:52:49 +1000
Subject: [PATCH 043/931] add a sys property with the it so we know which one
fail otherwise it is always same name in jenkins (#2928)
Signed-off-by: olivier lamy
---
.../src/it/jetty-cdi-run-forked/pom.xml | 1 +
.../src/it/jetty-deploy-war-mojo-it/pom.xml | 1 +
.../jetty-simple-webapp/pom.xml | 1 +
.../jetty-simple-webapp/pom.xml | 1 +
.../jetty-run-mojo-it/jetty-simple-webapp/pom.xml | 1 +
.../jetty-simple-webapp/pom.xml | 1 +
.../jetty-simple-webapp/pom.xml | 1 +
.../jetty-start-mojo-it/jetty-simple-webapp/pom.xml | 1 +
.../src/it/run-mojo-gwt-it/beer-server/pom.xml | 1 +
.../jetty/maven/plugin/it/TestGetContent.java | 13 +++++++------
10 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/jetty-maven-plugin/src/it/jetty-cdi-run-forked/pom.xml b/jetty-maven-plugin/src/it/jetty-cdi-run-forked/pom.xml
index 9208f7ecd10..0933746e86a 100644
--- a/jetty-maven-plugin/src/it/jetty-cdi-run-forked/pom.xml
+++ b/jetty-maven-plugin/src/it/jetty-cdi-run-forked/pom.xml
@@ -57,6 +57,7 @@
${jetty.port.file}true
+ ${project.groupId}:${project.artifactId}org.eclipse.jetty:jetty-maven-plugin
diff --git a/jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/pom.xml b/jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/pom.xml
index 528b0890f38..2ca1b218e2d 100644
--- a/jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/pom.xml
+++ b/jetty-maven-plugin/src/it/jetty-deploy-war-mojo-it/pom.xml
@@ -43,6 +43,7 @@
${jetty.port.file}
+ ${project.groupId}:${project.artifactId}Bean Validation Webapp example
diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/pom.xml
index 168dd7e7b2e..a1d4c8c1ea1 100644
--- a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/pom.xml
+++ b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/pom.xml
@@ -70,6 +70,7 @@
${jetty.port.file}truetrue
+ ${project.groupId}:${project.artifactId}org.eclipse.jetty:jetty-maven-plugin
diff --git a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/pom.xml
index c8af2120bd4..9ba881556cf 100644
--- a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/pom.xml
+++ b/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/pom.xml
@@ -70,6 +70,7 @@
${jetty.port.file}truetrue
+ ${project.groupId}:${project.artifactId}org.eclipse.jetty:jetty-maven-plugin
diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/pom.xml
index d8514ea74e5..099146ad7e0 100644
--- a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/pom.xml
+++ b/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/pom.xml
@@ -73,6 +73,7 @@
${jetty.port.file}truetrue
+ ${project.groupId}:${project.artifactId}org.eclipse.jetty:jetty-maven-plugin
diff --git a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/pom.xml
index 0d75cad9095..ccb42203249 100644
--- a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/pom.xml
+++ b/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/pom.xml
@@ -71,6 +71,7 @@
${jetty.port.file}truetrue
+ ${project.groupId}:${project.artifactId}org.eclipse.jetty:jetty-maven-plugin
diff --git a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/pom.xml
index 6ab552d13e2..8b6c7257ac4 100644
--- a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/pom.xml
+++ b/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/pom.xml
@@ -71,6 +71,7 @@
${jetty.port.file}truetrue
+ ${project.groupId}:${project.artifactId}org.eclipse.jetty:jetty-maven-plugin
diff --git a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/pom.xml
index feea2dbd628..d807ad4c34f 100644
--- a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/pom.xml
+++ b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/pom.xml
@@ -69,6 +69,7 @@
${jetty.port.file}truetrue
+ ${project.groupId}:${project.artifactId}org.eclipse.jetty:jetty-maven-plugin
diff --git a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/pom.xml b/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/pom.xml
index eb5310f1eaa..9e6afd3bd7a 100644
--- a/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/pom.xml
+++ b/jetty-maven-plugin/src/it/run-mojo-gwt-it/beer-server/pom.xml
@@ -74,6 +74,7 @@
${jetty.port.file}Please enter your name
+ ${project.groupId}:${project.artifactId}org.eclipse.jetty:jetty-maven-plugin
diff --git a/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/it/TestGetContent.java b/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/it/TestGetContent.java
index 5c74d08c79f..51495bf8d05 100644
--- a/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/it/TestGetContent.java
+++ b/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/it/TestGetContent.java
@@ -51,23 +51,24 @@ public class TestGetContent
if (Boolean.getBoolean( "helloServlet" ))
{
String response = httpClient.GET( "http://localhost:" + port + "/hello?name=beer" ).getContentAsString();
- assertEquals( "Hello beer", response.trim() );
+ assertEquals( "Hello beer", response.trim(), "it test " + System.getProperty( "maven.it.name" ) );
response = httpClient.GET( "http://localhost:" + port + "/hello?name=foo" ).getContentAsString();
- assertEquals( "Hello foo", response.trim() );
+ assertEquals( "Hello foo", response.trim(), "it test " + System.getProperty( "maven.it.name" ) );
System.out.println( "helloServlet" );
}
if (Boolean.getBoolean( "pingServlet" ))
{
- System.out.println( "pingServlet ok" );
- String response = httpClient.GET( "http://localhost:" + port + "/ping?name=beer" ).getContentAsString();
- assertEquals( "pong beer", response.trim() );
System.out.println( "pingServlet" );
+ String response = httpClient.GET( "http://localhost:" + port + "/ping?name=beer" ).getContentAsString();
+ assertEquals( "pong beer", response.trim(), "it test " + System.getProperty( "maven.it.name" ) );
+ System.out.println( "pingServlet ok" );
}
String contentCheck = System.getProperty( "contentCheck" );
if(StringUtils.isNotBlank( contentCheck ) )
{
String response = httpClient.GET( "http://localhost:" + port ).getContentAsString();
- assertTrue(response.contains(contentCheck), "response not contentCheck: " + contentCheck + ", response:" + response);
+ assertTrue(response.contains(contentCheck), "it test " + System.getProperty( "maven.it.name" )
+ + ", response not contentCheck: " + contentCheck + ", response:" + response);
System.out.println( "contentCheck" );
}
}
From e4ff653295a0fe72b43736a74a9249c8c3b5b479 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Tue, 25 Sep 2018 22:11:25 +0200
Subject: [PATCH 044/931] Issue #2191 - JPMS Support.
Introduced --jpms option in jetty-start to run Jetty from the module-path.
Introduced [jpms] sections in *.mod files, to specify JPMS command line
options that needs to be added to the command line generated by jetty-start.
Bumped java.transaction-api to 1.3 because it has Automatic-Module-Name.
Fixed ASM version lookup using ManifestUtils.
Fixed WebInfConfiguration.findAndFilterContainerPaths() to properly
scan the module-path, which may contain both files and directories.
Signed-off-by: Simone Bordet
---
.../src/main/config/modules/annotations.mod | 3 +
.../jetty/annotations/AnnotationParser.java | 73 ++++----
.../startup/startup-base-vs-home.adoc | 2 +-
.../startup/startup-classpath.adoc | 2 +-
jetty-plus/pom.xml | 2 +-
jetty-quickstart/pom.xml | 2 -
.../java/org/eclipse/jetty/start/Main.java | 18 +-
.../java/org/eclipse/jetty/start/Module.java | 11 ++
.../java/org/eclipse/jetty/start/Modules.java | 4 +
.../org/eclipse/jetty/start/StartArgs.java | 159 +++++++++++++++++-
.../org/eclipse/jetty/util/ManifestUtils.java | 28 +++
.../src/main/config/modules/webapp.mod | 3 +
.../jetty/webapp/WebInfConfiguration.java | 44 ++---
pom.xml | 2 +-
tests/test-quickstart/pom.xml | 1 -
15 files changed, 274 insertions(+), 80 deletions(-)
diff --git a/jetty-annotations/src/main/config/modules/annotations.mod b/jetty-annotations/src/main/config/modules/annotations.mod
index ca8c3bad139..5c58290955c 100644
--- a/jetty-annotations/src/main/config/modules/annotations.mod
+++ b/jetty-annotations/src/main/config/modules/annotations.mod
@@ -13,3 +13,6 @@ lib/annotations/*.jar
[xml]
# Enable annotation scanning webapp configurations
etc/jetty-annotations.xml
+
+[jpms]
+add-modules:org.objectweb.asm
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
index b6d9d35ceff..0b3fe364b6d 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
@@ -24,7 +24,6 @@ import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.nio.file.Path;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -36,6 +35,7 @@ import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.jetty.util.JavaVersion;
import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.ManifestUtils;
import org.eclipse.jetty.util.MultiException;
import org.eclipse.jetty.util.MultiReleaseJarFile;
import org.eclipse.jetty.util.log.Log;
@@ -69,9 +69,8 @@ import org.objectweb.asm.Opcodes;
public class AnnotationParser
{
private static final Logger LOG = Log.getLogger(AnnotationParser.class);
- protected static int ASM_OPCODE_VERSION = Opcodes.ASM6; //compatibility of api
- protected static String ASM_OPCODE_VERSION_STR = "ASM6";
-
+ private static final int ASM_OPCODE_VERSION = Opcodes.ASM6; //compatibility of api
+
/**
* Map of classnames scanned and the first location from which scan occurred
*/
@@ -86,48 +85,44 @@ public class AnnotationParser
public static int asmVersion ()
{
int asmVersion = ASM_OPCODE_VERSION;
- Package asm = Opcodes.class.getPackage();
- if (asm == null)
- LOG.warn("Unknown asm runtime version, assuming version {}", ASM_OPCODE_VERSION_STR);
+ String version = ManifestUtils.getVersion(Opcodes.class).orElse(null);
+ if (version == null)
+ {
+ LOG.warn("Unknown ASM version, assuming {}", ASM_OPCODE_VERSION);
+ }
else
{
- String s = asm.getImplementationVersion();
- if (s==null)
- LOG.info("Unknown asm implementation version, assuming version {}", ASM_OPCODE_VERSION_STR);
- else
+ int dot = version.indexOf('.');
+ version = version.substring(0, (dot < 0 ? version.length() : dot)).trim();
+ try
{
- int dot = s.indexOf('.');
- s = s.substring(0, (dot < 0 ? s.length() : dot)).trim();
- try
+ int v = Integer.parseInt(version);
+ switch (v)
{
- int v = Integer.parseInt(s);
- switch (v)
+ case 4:
{
- case 4:
- {
- asmVersion = Opcodes.ASM4;
- break;
- }
- case 5:
- {
- asmVersion = Opcodes.ASM5;
- break;
- }
- case 6:
- {
- asmVersion = Opcodes.ASM6;
- break;
- }
- default:
- {
- LOG.warn("Unrecognized runtime asm version, assuming {}", ASM_OPCODE_VERSION_STR);
- }
+ asmVersion = Opcodes.ASM4;
+ break;
+ }
+ case 5:
+ {
+ asmVersion = Opcodes.ASM5;
+ break;
+ }
+ case 6:
+ {
+ asmVersion = Opcodes.ASM6;
+ break;
+ }
+ default:
+ {
+ LOG.warn("Unrecognized ASM version, assuming {}", ASM_OPCODE_VERSION);
}
}
- catch (NumberFormatException e)
- {
- LOG.warn("Unable to parse runtime asm version, assuming version {}", ASM_OPCODE_VERSION_STR);
- }
+ }
+ catch (NumberFormatException e)
+ {
+ LOG.warn("Unable to parse ASM version, assuming {}", ASM_OPCODE_VERSION);
}
}
return asmVersion;
diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/startup-base-vs-home.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/startup-base-vs-home.adoc
index e5c347a8a00..93634198870 100644
--- a/jetty-documentation/src/main/asciidoc/administration/startup/startup-base-vs-home.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/startup/startup-base-vs-home.adoc
@@ -170,7 +170,7 @@ Note: order presented here is how they would appear on the classpath.
13: {VERSION} | ${jetty.home}/lib/jetty-jndi-{VERSION}.jar
14: 1.1.0.v201105071233 | ${jetty.home}/lib/jndi/javax.activation-1.1.0.v201105071233.jar
15: 1.4.1.v201005082020 | ${jetty.home}/lib/jndi/javax.mail.glassfish-1.4.1.v201005082020.jar
-16: 1.2 | ${jetty.home}/lib/jndi/javax.transaction-api-1.2.jar
+16: 1.3 | ${jetty.home}/lib/jndi/javax.transaction-api-1.3.jar
17: {VERSION} | ${jetty.home}/lib/jetty-rewrite-{VERSION}.jar
18: {VERSION} | ${jetty.home}/lib/jetty-security-{VERSION}.jar
19: {VERSION} | ${jetty.home}/lib/jetty-servlet-{VERSION}.jar
diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/startup-classpath.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/startup-classpath.adoc
index 4a51bc158bb..648664e42f6 100644
--- a/jetty-documentation/src/main/asciidoc/administration/startup/startup-classpath.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/startup/startup-classpath.adoc
@@ -80,7 +80,7 @@ Note: order presented here is how they would appear on the classpath.
13: {VERSION} | ${jetty.home}/lib/jetty-jndi-{VERSION}.jar
14: 1.1.0.v201105071233 | ${jetty.home}/lib/jndi/javax.activation-1.1.0.v201105071233.jar
15: 1.4.1.v201005082020 | ${jetty.home}/lib/jndi/javax.mail.glassfish-1.4.1.v201005082020.jar
-16: 1.2 | ${jetty.home}/lib/jndi/javax.transaction-api-1.2.jar
+16: 1.3 | ${jetty.home}/lib/jndi/javax.transaction-api-1.3.jar
17: {VERSION} | ${jetty.home}/lib/jetty-rewrite-{VERSION}.jar
18: {VERSION} | ${jetty.home}/lib/jetty-security-{VERSION}.jar
19: {VERSION} | ${jetty.home}/lib/jetty-servlet-{VERSION}.jar
diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml
index 5f5cdb99982..e1a32f8345f 100644
--- a/jetty-plus/pom.xml
+++ b/jetty-plus/pom.xml
@@ -43,7 +43,7 @@
true
- javax.transaction*;version="[1.1,1.3)",*
+ javax.transaction*;version="[1.3)",*
diff --git a/jetty-quickstart/pom.xml b/jetty-quickstart/pom.xml
index 1f76a98f0cb..4547244c9c4 100644
--- a/jetty-quickstart/pom.xml
+++ b/jetty-quickstart/pom.xml
@@ -37,7 +37,6 @@
javax.transactionjavax.transaction-api
- 1.2compile
@@ -49,7 +48,6 @@
org.eclipse.jetty.orbitjavax.mail.glassfish
- 1.4.1.v201005082020test
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java
index 59c7dc72a46..c032034f2ed 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java
@@ -18,11 +18,6 @@
package org.eclipse.jetty.start;
-import static org.eclipse.jetty.start.UsageException.ERR_BAD_STOP_PROPS;
-import static org.eclipse.jetty.start.UsageException.ERR_INVOKE_MAIN;
-import static org.eclipse.jetty.start.UsageException.ERR_NOT_STOPPED;
-import static org.eclipse.jetty.start.UsageException.ERR_UNKNOWN;
-
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
@@ -44,6 +39,11 @@ import org.eclipse.jetty.start.Props.Prop;
import org.eclipse.jetty.start.config.CommandLineConfigSource;
import org.eclipse.jetty.start.config.ConfigSource;
+import static org.eclipse.jetty.start.UsageException.ERR_BAD_STOP_PROPS;
+import static org.eclipse.jetty.start.UsageException.ERR_INVOKE_MAIN;
+import static org.eclipse.jetty.start.UsageException.ERR_NOT_STOPPED;
+import static org.eclipse.jetty.start.UsageException.ERR_UNKNOWN;
+
/**
* Main start class.
*
@@ -353,9 +353,13 @@ public class Main
// ------------------------------------------------------------
// 6) Resolve Extra XMLs
args.resolveExtraXmls();
-
+
// ------------------------------------------------------------
- // 9) Resolve Property Files
+ // 7) JPMS Expansion
+ args.expandJPMS(activeModules);
+
+ // ------------------------------------------------------------
+ // 8) Resolve Property Files
args.resolvePropertyFiles();
return args;
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Module.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Module.java
index 0bdd74b2b11..d449001d39c 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/Module.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Module.java
@@ -89,6 +89,9 @@ public class Module implements Comparable
/** List of library options for this Module */
private final List _libs=new ArrayList<>();
+
+ /** List of JPMS options for this Module */
+ private final List _jpms=new ArrayList<>();
/** List of files for this Module */
private final List _files=new ArrayList<>();
@@ -229,6 +232,11 @@ public class Module implements Comparable
{
return _xmls;
}
+
+ public List getJPMS()
+ {
+ return _jpms;
+ }
public Version getVersion()
{
@@ -350,6 +358,9 @@ public class Module implements Comparable
case "LIBS":
_libs.add(line);
break;
+ case "JPMS":
+ _jpms.add(line);
+ break;
case "LICENSE":
case "LICENSES":
case "LICENCE":
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java
index 69bcad311d9..e5930122ca4 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java
@@ -154,6 +154,10 @@ public class Modules implements Iterable
{
System.out.printf(" XML: %s%n",xml);
}
+ for (String jpms : module.getJPMS())
+ {
+ System.out.printf(" JPMS: %s%n",jpms);
+ }
for (String jvm : module.getJvmArgs())
{
System.out.printf(" JVM: %s%n",jvm);
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java
index 69c61b54023..cb363dfd485 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java
@@ -27,9 +27,12 @@ import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
@@ -37,6 +40,8 @@ import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.jar.Manifest;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
import org.eclipse.jetty.start.Props.Prop;
import org.eclipse.jetty.start.config.ConfigSource;
@@ -109,7 +114,8 @@ public class StartArgs
System.setProperty("jetty.tag.version", tag);
}
- private static final String SERVER_MAIN = "org.eclipse.jetty.xml.XmlConfiguration";
+ private static final String MAIN_CLASS = "org.eclipse.jetty.xml.XmlConfiguration";
+ private static final String MODULE_MAIN_CLASS = "org.eclipse.jetty.xml/org.eclipse.jetty.xml.XmlConfiguration";
private final BaseHome baseHome;
@@ -131,6 +137,13 @@ public class StartArgs
/** List of all active [xml] sections from enabled modules */
private List xmls = new ArrayList<>();
+ /** List of all active [jpms] sections for enabled modules */
+ private Set jmodAdds = new LinkedHashSet<>();
+ private Map> jmodPatch = new LinkedHashMap<>();
+ private Map> jmodOpens = new LinkedHashMap<>();
+ private Map> jmodExports = new LinkedHashMap<>();
+ private Map> jmodReads = new LinkedHashMap<>();
+
/** JVM arguments, found via command line and in all active [exec] sections from enabled modules */
private List jvmArgs = new ArrayList<>();
@@ -173,6 +186,7 @@ public class StartArgs
private boolean listConfig = false;
private boolean version = false;
private boolean dryRun = false;
+ private boolean jpms = false;
private boolean createStartd = false;
private boolean updateIni = false;
private String mavenBaseUri;
@@ -540,6 +554,57 @@ public class StartArgs
}
}
+ void expandJPMS(List activeModules)
+ {
+ for (Module module : activeModules)
+ {
+ for (String line : module.getJPMS())
+ {
+ line = properties.expand(line);
+ String directive;
+ if (line.startsWith(directive = "add-modules:"))
+ {
+ String[] names = line.substring(directive.length()).split(",");
+ Arrays.stream(names).map(String::trim).collect(Collectors.toCollection(() -> jmodAdds));
+ }
+ else if (line.startsWith(directive = "patch-module:"))
+ {
+ parseJPMSKeyValue(module, line, directive, File.pathSeparator, jmodPatch);
+ }
+ else if (line.startsWith(directive = "add-opens:"))
+ {
+ parseJPMSKeyValue(module, line, directive, ",", jmodOpens);
+ }
+ else if (line.startsWith(directive = "add-exports:"))
+ {
+ parseJPMSKeyValue(module, line, directive, ",", jmodExports);
+ }
+ else if (line.startsWith(directive = "add-reads:"))
+ {
+ parseJPMSKeyValue(module, line, directive, ",", jmodReads);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Invalid [jpms] directive " + directive + " in module " + module.getName() + ": " + line);
+ }
+ }
+ }
+ StartLog.debug("Expanded JPMS directives:%nadd-modules: %s%npatch-modules: %s%nadd-opens: %s%nadd-exports: %s%nadd-reads: %s",
+ jmodAdds, jmodPatch, jmodOpens, jmodExports, jmodReads);
+ }
+
+ private void parseJPMSKeyValue(Module module, String line, String directive, String delimiter, Map> output)
+ {
+ String value = line.substring(directive.length());
+ int equals = value.indexOf('=');
+ if (equals <= 0)
+ throw new IllegalArgumentException("Invalid [jpms] directive " + directive + " in module " + module.getName() + ": " + line);
+ String key = value.substring(0, equals).trim();
+ List values = Arrays.asList(value.substring(equals + 1).split(delimiter));
+ values = values.stream().map(String::trim).collect(Collectors.toList());
+ output.computeIfAbsent(key, k -> new LinkedHashSet<>()).addAll(values);
+ }
+
public List getStartModules()
{
return startModules;
@@ -611,9 +676,76 @@ public class StartArgs
cmd.addEqualsArg("-D" + propKey,value);
}
- cmd.addRawArg("-cp");
- cmd.addRawArg(classpath.toString());
- cmd.addRawArg(getMainClassname());
+ if (isJPMS())
+ {
+ Map> dirsAndFiles = StreamSupport.stream(classpath.spliterator(), false)
+ .collect(Collectors.groupingBy(File::isDirectory));
+ List files = dirsAndFiles.get(false);
+ if (!files.isEmpty())
+ {
+ cmd.addRawArg("--module-path");
+ String modules = files.stream()
+ .map(File::getAbsolutePath)
+ .collect(Collectors.joining(File.pathSeparator));
+ cmd.addRawArg(modules);
+ }
+ List dirs = dirsAndFiles.get(true);
+ if (!dirs.isEmpty())
+ {
+ cmd.addRawArg("--class-path");
+ String directories = dirs.stream()
+ .map(File::getAbsolutePath)
+ .collect(Collectors.joining(File.pathSeparator));
+ cmd.addRawArg(directories);
+ }
+
+ if (!jmodAdds.isEmpty())
+ {
+ cmd.addRawArg("--add-modules");
+ cmd.addRawArg(String.join(",", jmodAdds));
+ }
+ if (!jmodPatch.isEmpty())
+ {
+ for (Map.Entry> entry : jmodPatch.entrySet())
+ {
+ cmd.addRawArg("--patch-module");
+ cmd.addRawArg(entry.getKey() + "=" + String.join(File.pathSeparator, entry.getValue()));
+ }
+ }
+ if (!jmodOpens.isEmpty())
+ {
+ for (Map.Entry> entry : jmodOpens.entrySet())
+ {
+ cmd.addRawArg("--add-opens");
+ cmd.addRawArg(entry.getKey() + "=" + String.join(",", entry.getValue()));
+ }
+ }
+ if (!jmodExports.isEmpty())
+ {
+ for (Map.Entry> entry : jmodExports.entrySet())
+ {
+ cmd.addRawArg("--add-exports");
+ cmd.addRawArg(entry.getKey() + "=" + String.join(",", entry.getValue()));
+ }
+ }
+ if (!jmodReads.isEmpty())
+ {
+ for (Map.Entry> entry : jmodReads.entrySet())
+ {
+ cmd.addRawArg("--add-reads");
+ cmd.addRawArg(entry.getKey() + "=" + String.join(",", entry.getValue()));
+ }
+ }
+
+ cmd.addRawArg("--module");
+ cmd.addRawArg(getMainClassname());
+ }
+ else
+ {
+ cmd.addRawArg("-cp");
+ cmd.addRawArg(classpath.toString());
+ cmd.addRawArg(getMainClassname());
+ }
}
@@ -656,8 +788,8 @@ public class StartArgs
public String getMainClassname()
{
- String mainclass = System.getProperty("jetty.server",SERVER_MAIN);
- return System.getProperty("main.class",mainclass);
+ String mainClass = System.getProperty("jetty.server", isJPMS() ? MODULE_MAIN_CLASS : MAIN_CLASS);
+ return System.getProperty("main.class", mainClass);
}
public String getMavenLocalRepoDir()
@@ -764,6 +896,11 @@ public class StartArgs
return createFiles;
}
+ public boolean isJPMS()
+ {
+ return jpms;
+ }
+
public boolean isDryRun()
{
return dryRun;
@@ -781,7 +918,7 @@ public class StartArgs
public boolean isNormalMainClass()
{
- return SERVER_MAIN.equals(getMainClassname());
+ return MAIN_CLASS.equals(getMainClassname());
}
public boolean isHelp()
@@ -973,6 +1110,14 @@ public class StartArgs
return;
}
+ if ("--jpms".equals(arg))
+ {
+ jpms = true;
+ // Need to fork because we cannot use JDK 9 Module APIs.
+ exec = true;
+ return;
+ }
+
if ("--dry-run".equals(arg) || "--exec-print".equals(arg))
{
dryRun = true;
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ManifestUtils.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ManifestUtils.java
index f39d54caa3b..83e9f5517a8 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/ManifestUtils.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ManifestUtils.java
@@ -54,4 +54,32 @@ public class ManifestUtils
return Optional.empty();
}
}
+
+ /**
+ *
Attempts to return the version of the jar/module for the given class.
+ *
First, retrieves the {@code Implementation-Version} main attribute of the manifest;
+ * if that is missing, retrieves the JPMS module version (via reflection);
+ * if that is missing, returns an empty Optional.
+ *
+ * @param klass the class of the jar/module to retrieve the version
+ * @return the jar/module version, or an empty Optional
+ */
+ public static Optional getVersion(Class> klass)
+ {
+ Optional version = getManifest(klass).map(Manifest::getMainAttributes)
+ .map(attributes -> attributes.getValue("Implementation-Version"));
+ if (version.isPresent())
+ return version;
+
+ try
+ {
+ Object module = klass.getClass().getMethod("getModule").invoke(klass);
+ Object descriptor = module.getClass().getMethod("getDescriptor").invoke(module);
+ return (Optional)descriptor.getClass().getMethod("rawVersion").invoke(descriptor);
+ }
+ catch (Throwable x)
+ {
+ return Optional.empty();
+ }
+ }
}
diff --git a/jetty-webapp/src/main/config/modules/webapp.mod b/jetty-webapp/src/main/config/modules/webapp.mod
index 8b9186549bc..d41e57ce4a9 100644
--- a/jetty-webapp/src/main/config/modules/webapp.mod
+++ b/jetty-webapp/src/main/config/modules/webapp.mod
@@ -30,3 +30,6 @@ lib/jetty-webapp-${jetty.version}.jar
##
#jetty.webapp.addSystemClasses+=,org.example.
#jetty.webapp.addServerClasses+=,org.example.
+
+[jpms]
+add-modules:java.instrument
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
index 8e7dc4b550f..d5cc4c1b09d 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
@@ -159,8 +159,6 @@ public class WebInfConfiguration extends AbstractConfiguration
context.getMetaData().setWebInfClassesDirs(findClassDirs(context));
}
-
-
/**
* Find jars and directories that are on the container's classpath
* and apply an optional filter. The filter is a pattern applied to the
@@ -177,15 +175,14 @@ public class WebInfConfiguration extends AbstractConfiguration
* @param context the WebAppContext being deployed
* @throws Exception if unable to apply optional filtering on the container's classpath
*/
- public void findAndFilterContainerPaths (final WebAppContext context)
- throws Exception
+ public void findAndFilterContainerPaths (final WebAppContext context) throws Exception
{
//assume the target jvm is the same as that running
int targetPlatform = JavaVersion.VERSION.getPlatform();
//allow user to specify target jvm different to current runtime
Object target = context.getAttribute(JavaVersion.JAVA_TARGET_PLATFORM);
if (target!=null)
- targetPlatform = Integer.valueOf(target.toString()).intValue();
+ targetPlatform = Integer.parseInt(target.toString());
//Apply an initial name filter to the jars to select which will be eventually
//scanned for META-INF info and annotations. The filter is based on inclusion patterns.
@@ -199,7 +196,7 @@ public class WebInfConfiguration extends AbstractConfiguration
List containerUris = new ArrayList<>();
- while (loader != null && (loader instanceof URLClassLoader))
+ while (loader instanceof URLClassLoader)
{
URL[] urls = ((URLClassLoader)loader).getURLs();
if (urls != null)
@@ -219,12 +216,13 @@ public class WebInfConfiguration extends AbstractConfiguration
loader = loader.getParent();
}
- if (LOG.isDebugEnabled()) LOG.debug("Matching container urls {}", containerUris);
+ if (LOG.isDebugEnabled())
+ LOG.debug("Matching container urls {}", containerUris);
containerPathNameMatcher.match(containerUris);
//if running on jvm 9 or above, we we won't be able to look at the application classloader
//to extract urls, so we need to examine the classpath instead.
- if (JavaVersion.VERSION.getPlatform() >= 9)
+ if (targetPlatform >= 9)
{
tmp = System.getProperty("java.class.path");
if (tmp != null)
@@ -236,7 +234,8 @@ public class WebInfConfiguration extends AbstractConfiguration
File f = new File(entry);
cpUris.add(f.toURI());
}
- if (LOG.isDebugEnabled()) LOG.debug("Matching java.class.path {}", cpUris);
+ if (LOG.isDebugEnabled())
+ LOG.debug("Matching java.class.path {}", cpUris);
containerPathNameMatcher.match(cpUris);
}
}
@@ -253,28 +252,33 @@ public class WebInfConfiguration extends AbstractConfiguration
{
List moduleUris = new ArrayList<>();
String[] entries = tmp.split(File.pathSeparator);
- for (String entry:entries)
+ for (String entry : entries)
{
- File dir = new File(entry);
- File[] files = dir.listFiles();
- if (files != null)
+ File file = new File(entry);
+ if (file.isDirectory())
{
- for (File f:files)
+ File[] files = file.listFiles();
+ if (files != null)
{
- moduleUris.add(f.toURI());
+ for (File f : files)
+ moduleUris.add(f.toURI());
}
}
-
+ else
+ {
+ moduleUris.add(file.toURI());
+ }
}
- if (LOG.isDebugEnabled()) LOG.debug("Matching jdk.module.path {}", moduleUris);
+ if (LOG.isDebugEnabled())
+ LOG.debug("Matching jdk.module.path {}", moduleUris);
containerPathNameMatcher.match(moduleUris);
}
}
- if (LOG.isDebugEnabled()) LOG.debug("Container paths selected:{}", context.getMetaData().getContainerResources());
+ if (LOG.isDebugEnabled())
+ LOG.debug("Container paths selected:{}", context.getMetaData().getContainerResources());
}
-
-
+
/**
* Finds the jars that are either physically or virtually in
* WEB-INF/lib, and applies an optional filter to their full
diff --git a/pom.xml b/pom.xml
index 5f952f93347..0edb642ac71 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1020,7 +1020,7 @@
javax.transactionjavax.transaction-api
- 1.2
+ 1.3provided
diff --git a/tests/test-quickstart/pom.xml b/tests/test-quickstart/pom.xml
index 013d9ca080a..1fd74d1ce22 100644
--- a/tests/test-quickstart/pom.xml
+++ b/tests/test-quickstart/pom.xml
@@ -44,7 +44,6 @@
javax.transactionjavax.transaction-api
- 1.2org.eclipse.jetty.tests
From 5593e5b479291c36ab3703d37753663c90c4cce6 Mon Sep 17 00:00:00 2001
From: Jan Bartel
Date: Wed, 26 Sep 2018 11:27:57 +1000
Subject: [PATCH 045/931] Jetty 9.4.x 2903 delay listener instantiation (#2930)
* Issue #2903 Ensure listeners not instantiated for quickstart gen
Signed-off-by: Jan Bartel
---
.../annotations/WebListenerAnnotation.java | 6 +-
jetty-maven-plugin/pom.xml | 20 ++++
.../QuickStartDescriptorGenerator.java | 9 +-
.../jetty/quickstart/TestQuickStart.java | 7 +-
.../eclipse/jetty/servlet/ListenerHolder.java | 94 +++++++++++++++----
.../jetty/servlet/ServletContextHandler.java | 9 +-
.../webapp/StandardDescriptorProcessor.java | 24 +----
7 files changed, 118 insertions(+), 51 deletions(-)
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java
index 5478d5637ab..89f9ba4f704 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java
@@ -81,12 +81,10 @@ public class WebListenerAnnotation extends DiscoveredAnnotation
{
MetaData metaData = _context.getMetaData();
if (metaData.getOrigin(clazz.getName()+".listener") == Origin.NotSet)
- {
- java.util.EventListener listener = (java.util.EventListener)_context.getServletContext().createInstance(clazz);
+ {
ListenerHolder h = _context.getServletHandler().newListenerHolder(new Source(Source.Origin.ANNOTATION, clazz.getName()));
- h.setListener(listener);
+ h.setHeldClass(clazz);
_context.getServletHandler().addListener(h);
- _context.addEventListener(listener);
}
}
else
diff --git a/jetty-maven-plugin/pom.xml b/jetty-maven-plugin/pom.xml
index c4d02c88a29..d631db23eb0 100644
--- a/jetty-maven-plugin/pom.xml
+++ b/jetty-maven-plugin/pom.xml
@@ -185,6 +185,26 @@
jetty-server${project.version}
+
+ org.eclipse.jetty
+ jetty-servlet
+ ${project.version}
+
+
+ org.eclipse.jetty
+ jetty-client
+ ${project.version}
+
+
+ org.eclipse.jetty
+ jetty-http
+ ${project.version}
+
+
+ org.eclipse.jetty
+ jetty-io
+ ${project.version}
+ org.eclipse.jettyjetty-jmx
diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartDescriptorGenerator.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartDescriptorGenerator.java
index 9a27e1e36c2..896bc4f84bf 100644
--- a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartDescriptorGenerator.java
+++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartDescriptorGenerator.java
@@ -51,6 +51,7 @@ import org.eclipse.jetty.security.authentication.FormAuthenticator;
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.FilterMapping;
+import org.eclipse.jetty.servlet.ListenerHolder;
import org.eclipse.jetty.servlet.ServletContextHandler.JspConfig;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
@@ -176,10 +177,10 @@ public class QuickStartDescriptorGenerator
.tag("param-value",_webApp.getInitParameter(p))
.closeTag();
- if (_webApp.getEventListeners() != null)
- for (EventListener e : _webApp.getEventListeners())
- out.openTag("listener",origin(md,e.getClass().getCanonicalName() + ".listener"))
- .tag("listener-class",e.getClass().getCanonicalName())
+ if (_webApp.getServletHandler().getListeners() != null)
+ for (ListenerHolder e : _webApp.getServletHandler().getListeners())
+ out.openTag("listener",origin(md,e.getClassName() + ".listener"))
+ .tag("listener-class",e.getClassName())
.closeTag();
ServletHandler servlets = _webApp.getServletHandler();
diff --git a/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/TestQuickStart.java b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/TestQuickStart.java
index 0636f18b921..df0a5aa91d1 100644
--- a/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/TestQuickStart.java
+++ b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/TestQuickStart.java
@@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.*;
import java.io.File;
import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.servlet.ListenerHolder;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
@@ -69,8 +70,10 @@ public class TestQuickStart
ServletHolder fooHolder = new ServletHolder();
fooHolder.setServlet(new FooServlet());
fooHolder.setName("foo");
- quickstart.getServletHandler().addServlet(fooHolder);
- quickstart.addEventListener(new FooContextListener());
+ quickstart.getServletHandler().addServlet(fooHolder);
+ ListenerHolder lholder = new ListenerHolder();
+ lholder.setListener(new FooContextListener());
+ quickstart.getServletHandler().addListener(lholder);
server.setHandler(quickstart);
server.start();
server.stop();
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ListenerHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ListenerHolder.java
index d09e298e7e8..9e94f463f62 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ListenerHolder.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ListenerHolder.java
@@ -21,54 +21,112 @@ package org.eclipse.jetty.servlet;
import java.util.EventListener;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
/**
* ListenerHolder
*
- * Specialization of AbstractHolder for servlet listeners. This
+ * Specialization of BaseHolder for servlet listeners. This
* allows us to record where the listener originated - web.xml,
* annotation, api etc.
*/
public class ListenerHolder extends BaseHolder
{
private EventListener _listener;
+ private boolean _initialized = false;
+ public ListenerHolder ()
+ {
+ this (Source.EMBEDDED);
+ }
+
public ListenerHolder(Source source)
{
super(source);
}
-
- public void setListener(EventListener listener)
- {
- _listener = listener;
- setClassName(listener.getClass().getName());
- setHeldClass(listener.getClass());
- _extInstance=true;
- }
-
+
public EventListener getListener()
{
return _listener;
}
+ /**
+ * Set an explicit instance. In this case,
+ * just like ServletHolder and FilterHolder,
+ * the listener will not be introspected for
+ * annotations like Resource etc.
+ *
+ * @param listener
+ */
+ public void setListener (EventListener listener)
+ {
+ _listener = listener;
+ _extInstance=true;
+ setHeldClass(_listener.getClass());
+ setClassName(_listener.getClass().getName());
+ }
+
+
+ public void initialize (ServletContext context) throws Exception
+ {
+ if (!_initialized)
+ {
+ initialize();
+
+ if (_listener == null)
+ {
+ //create an instance of the listener and decorate it
+ try
+ {
+ _listener = (context instanceof ServletContextHandler.Context)
+ ?((ServletContextHandler.Context)context).createListener(getHeldClass())
+ :getHeldClass().getDeclaredConstructor().newInstance();
+
+ }
+ catch (ServletException se)
+ {
+ Throwable cause = se.getRootCause();
+ if (cause instanceof InstantiationException)
+ throw (InstantiationException)cause;
+ if (cause instanceof IllegalAccessException)
+ throw (IllegalAccessException)cause;
+ throw se;
+ }
+ }
+ _initialized = true;
+ }
+ }
+
@Override
public void doStart() throws Exception
{
- //Listeners always have an instance eagerly created, it cannot be deferred to the doStart method
- if (_listener == null)
- throw new IllegalStateException("No listener instance");
-
super.doStart();
+ if (!java.util.EventListener.class.isAssignableFrom(_class))
+ {
+ String msg = _class+" is not a java.util.EventListener";
+ super.stop();
+ throw new IllegalStateException(msg);
+ }
}
+
+ @Override
+ public void doStop() throws Exception
+ {
+ super.doStop();
+ if (!_extInstance)
+ _listener = null;
+ _initialized = false;
+ }
+
@Override
public String toString()
{
- return super.toString()+(_listener == null?"":": "+getClassName());
- }
-
-
+ return super.toString()+": "+getClassName();
+ }
}
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java
index ec0b6e853d2..8729025410b 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java
@@ -356,13 +356,16 @@ public class ServletContextHandler extends ContextHandler
if (_servletHandler != null)
{
- // Call decorators on all holders, and also on any EventListeners before
- // decorators are called on any other classes (like servlets and filters)
+ //Ensure listener instances are created, added to ContextHandler
if(_servletHandler.getListeners() != null)
{
for (ListenerHolder holder:_servletHandler.getListeners())
{
- _objFactory.decorate(holder.getListener());
+ holder.start();
+ //we need to pass in the context because the ServletHandler has not
+ //yet got a reference to the ServletContext (happens in super.startContext)
+ holder.initialize(_scontext);
+ addEventListener(holder.getListener());
}
}
}
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java
index cae3782b160..fdfaede611b 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java
@@ -1911,17 +1911,11 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
}
((WebDescriptor)descriptor).addClassName(className);
-
- Class extends EventListener> listenerClass = (Class extends EventListener>)context.loadClass(className);
- listener = newListenerInstance(context,listenerClass, descriptor);
- if (!(listener instanceof EventListener))
- {
- LOG.warn("Not an EventListener: " + listener);
- return;
- }
- context.addEventListener(listener);
+
+ ListenerHolder h = context.getServletHandler().newListenerHolder(new Source (Source.Origin.DESCRIPTOR, descriptor.getResource().toString()));
+ h.setClassName(className);
+ context.getServletHandler().addListener(h);
context.getMetaData().setOrigin(className+".listener", descriptor);
-
}
}
catch (Exception e)
@@ -1960,14 +1954,4 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
((ConstraintAware)context.getSecurityHandler()).setDenyUncoveredHttpMethods(true);
}
-
- public EventListener newListenerInstance(WebAppContext context,Class extends EventListener> clazz, Descriptor descriptor) throws Exception
- {
- ListenerHolder h = context.getServletHandler().newListenerHolder(new Source (Source.Origin.DESCRIPTOR, descriptor.getResource().toString()));
- EventListener l = context.getServletContext().createInstance(clazz);
- h.setListener(l);
- context.getServletHandler().addListener(h);
- return l;
-
- }
}
From 22cbbdc90047ca1632622192a07dae92cdf44369 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Wed, 26 Sep 2018 12:41:12 +0200
Subject: [PATCH 046/931] Issue #2191 - JPMS Support.
Reverted wrong change in WebInfConfiguration.findAndFilterContainerPaths().
Signed-off-by: Simone Bordet
---
.../java/org/eclipse/jetty/webapp/WebInfConfiguration.java | 5 +++--
jetty-webapp/src/test/resources/jetty-logging.properties | 3 +--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
index d5cc4c1b09d..f38bc347ad8 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
@@ -178,8 +178,9 @@ public class WebInfConfiguration extends AbstractConfiguration
public void findAndFilterContainerPaths (final WebAppContext context) throws Exception
{
//assume the target jvm is the same as that running
- int targetPlatform = JavaVersion.VERSION.getPlatform();
+ int currentPlatform = JavaVersion.VERSION.getPlatform();
//allow user to specify target jvm different to current runtime
+ int targetPlatform = currentPlatform;
Object target = context.getAttribute(JavaVersion.JAVA_TARGET_PLATFORM);
if (target!=null)
targetPlatform = Integer.parseInt(target.toString());
@@ -222,7 +223,7 @@ public class WebInfConfiguration extends AbstractConfiguration
//if running on jvm 9 or above, we we won't be able to look at the application classloader
//to extract urls, so we need to examine the classpath instead.
- if (targetPlatform >= 9)
+ if (currentPlatform >= 9)
{
tmp = System.getProperty("java.class.path");
if (tmp != null)
diff --git a/jetty-webapp/src/test/resources/jetty-logging.properties b/jetty-webapp/src/test/resources/jetty-logging.properties
index 4c4c7f8eddc..3c7f5b26a47 100644
--- a/jetty-webapp/src/test/resources/jetty-logging.properties
+++ b/jetty-webapp/src/test/resources/jetty-logging.properties
@@ -1,6 +1,5 @@
-# Setup default logging implementation for during testing
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
-org.eclipse.jetty.LEVEL=INFO
+#org.eclipse.jetty.LEVEL=DEBUG
# org.eclipse.jetty.webapp.WebAppClassLoader.LEVEL=DEBUG
# org.eclipse.jetty.util.LEVEL=DEBUG
# org.eclipse.jetty.util.PathWatcher.Noisy.LEVEL=OFF
From 81d02893dc441db989b47d57546d40d3a4c426a8 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Wed, 26 Sep 2018 13:21:40 +0200
Subject: [PATCH 047/931] Issue #2191 - JPMS Support.
Using BaseHome.getPaths() to resolve paths for patches modules.
Signed-off-by: Simone Bordet
---
.../org/eclipse/jetty/start/StartArgs.java | 37 +++++++++++++------
1 file changed, 25 insertions(+), 12 deletions(-)
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java
index cb363dfd485..314c9ed3bf4 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java
@@ -554,7 +554,7 @@ public class StartArgs
}
}
- void expandJPMS(List activeModules)
+ void expandJPMS(List activeModules) throws IOException
{
for (Module module : activeModules)
{
@@ -569,19 +569,19 @@ public class StartArgs
}
else if (line.startsWith(directive = "patch-module:"))
{
- parseJPMSKeyValue(module, line, directive, File.pathSeparator, jmodPatch);
+ parseJPMSKeyValue(module, line, directive, true, jmodPatch);
}
else if (line.startsWith(directive = "add-opens:"))
{
- parseJPMSKeyValue(module, line, directive, ",", jmodOpens);
+ parseJPMSKeyValue(module, line, directive, false, jmodOpens);
}
else if (line.startsWith(directive = "add-exports:"))
{
- parseJPMSKeyValue(module, line, directive, ",", jmodExports);
+ parseJPMSKeyValue(module, line, directive, false, jmodExports);
}
else if (line.startsWith(directive = "add-reads:"))
{
- parseJPMSKeyValue(module, line, directive, ",", jmodReads);
+ parseJPMSKeyValue(module, line, directive, false, jmodReads);
}
else
{
@@ -593,16 +593,29 @@ public class StartArgs
jmodAdds, jmodPatch, jmodOpens, jmodExports, jmodReads);
}
- private void parseJPMSKeyValue(Module module, String line, String directive, String delimiter, Map> output)
+ private void parseJPMSKeyValue(Module module, String line, String directive, boolean valueIsFile, Map> output) throws IOException
{
- String value = line.substring(directive.length());
- int equals = value.indexOf('=');
+ String valueString = line.substring(directive.length());
+ int equals = valueString.indexOf('=');
if (equals <= 0)
throw new IllegalArgumentException("Invalid [jpms] directive " + directive + " in module " + module.getName() + ": " + line);
- String key = value.substring(0, equals).trim();
- List values = Arrays.asList(value.substring(equals + 1).split(delimiter));
- values = values.stream().map(String::trim).collect(Collectors.toList());
- output.computeIfAbsent(key, k -> new LinkedHashSet<>()).addAll(values);
+ String delimiter = valueIsFile ? File.pathSeparator : ",";
+ String key = valueString.substring(0, equals).trim();
+ String[] values = valueString.substring(equals + 1).split(delimiter);
+ Set result = output.computeIfAbsent(key, k -> new LinkedHashSet<>());
+ for (String value : values)
+ {
+ value = value.trim();
+ if (valueIsFile)
+ {
+ List paths = baseHome.getPaths(value);
+ paths.stream().map(Path::toAbsolutePath).map(Path::toString).collect(Collectors.toCollection(() -> result));
+ }
+ else
+ {
+ result.add(value);
+ }
+ }
}
public List getStartModules()
From 7e68ef1e1787bc634123f2787eb68699d88748d9 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Wed, 26 Sep 2018 13:22:29 +0200
Subject: [PATCH 048/931] Issue #2191 - JPMS Support.
Now server.mod patches the servlet.api JPMS module with jetty-schemas.jar.
Signed-off-by: Simone Bordet
---
jetty-server/src/main/config/modules/server.mod | 3 +++
1 file changed, 3 insertions(+)
diff --git a/jetty-server/src/main/config/modules/server.mod b/jetty-server/src/main/config/modules/server.mod
index f739beafbbb..2bd4718fd0d 100644
--- a/jetty-server/src/main/config/modules/server.mod
+++ b/jetty-server/src/main/config/modules/server.mod
@@ -24,6 +24,9 @@ lib/jetty-io-${jetty.version}.jar
[xml]
etc/jetty.xml
+[jpms]
+patch-module: servlet.api=lib/jetty-schemas-3.1.jar
+
[ini-template]
### Common HTTP configuration
## Scheme to use to build URIs for secure redirects
From 587ecfeb9c60ff34e932e04a21c44e67b83fd28e Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Wed, 26 Sep 2018 13:36:51 +0200
Subject: [PATCH 049/931] Issue #2191 - JPMS Support.
Code cleanups.
Signed-off-by: Simone Bordet
---
.../org/eclipse/jetty/start/StartArgs.java | 74 +++++--------------
1 file changed, 20 insertions(+), 54 deletions(-)
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java
index 314c9ed3bf4..e9c8e1464c8 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java
@@ -416,8 +416,7 @@ public class StartArgs
return;
}
- List sortedKeys = new ArrayList<>();
- sortedKeys.addAll(systemPropertySource.keySet());
+ List sortedKeys = new ArrayList<>(systemPropertySource.keySet());
Collections.sort(sortedKeys);
for (String key : sortedKeys)
@@ -459,11 +458,8 @@ public class StartArgs
/**
* Expand any command line added {@code --lib} lib references.
- *
- * @throws IOException
- * if unable to expand the libraries
*/
- public void expandSystemProperties() throws IOException
+ public void expandSystemProperties()
{
StartLog.debug("Expanding System Properties");
@@ -480,7 +476,7 @@ public class StartArgs
}
/**
- * Expand any command line added --lib lib references.
+ * Expand any command line added {@code --lib} lib references.
*
* @throws IOException
* if unable to expand the libraries
@@ -665,7 +661,7 @@ public class StartArgs
cmd.addRawArg("-Djetty.home=" + baseHome.getHome());
cmd.addRawArg("-Djetty.base=" + baseHome.getBase());
- for (String x : jvmArgs)
+ for (String x : getJvmArgs())
{
if (x.startsWith("-D"))
{
@@ -717,37 +713,25 @@ public class StartArgs
cmd.addRawArg("--add-modules");
cmd.addRawArg(String.join(",", jmodAdds));
}
- if (!jmodPatch.isEmpty())
+ for (Map.Entry> entry : jmodPatch.entrySet())
{
- for (Map.Entry> entry : jmodPatch.entrySet())
- {
- cmd.addRawArg("--patch-module");
- cmd.addRawArg(entry.getKey() + "=" + String.join(File.pathSeparator, entry.getValue()));
- }
+ cmd.addRawArg("--patch-module");
+ cmd.addRawArg(entry.getKey() + "=" + String.join(File.pathSeparator, entry.getValue()));
}
- if (!jmodOpens.isEmpty())
+ for (Map.Entry> entry : jmodOpens.entrySet())
{
- for (Map.Entry> entry : jmodOpens.entrySet())
- {
- cmd.addRawArg("--add-opens");
- cmd.addRawArg(entry.getKey() + "=" + String.join(",", entry.getValue()));
- }
+ cmd.addRawArg("--add-opens");
+ cmd.addRawArg(entry.getKey() + "=" + String.join(",", entry.getValue()));
}
- if (!jmodExports.isEmpty())
+ for (Map.Entry> entry : jmodExports.entrySet())
{
- for (Map.Entry> entry : jmodExports.entrySet())
- {
- cmd.addRawArg("--add-exports");
- cmd.addRawArg(entry.getKey() + "=" + String.join(",", entry.getValue()));
- }
+ cmd.addRawArg("--add-exports");
+ cmd.addRawArg(entry.getKey() + "=" + String.join(",", entry.getValue()));
}
- if (!jmodReads.isEmpty())
+ for (Map.Entry> entry : jmodReads.entrySet())
{
- for (Map.Entry> entry : jmodReads.entrySet())
- {
- cmd.addRawArg("--add-reads");
- cmd.addRawArg(entry.getKey() + "=" + String.join(",", entry.getValue()));
- }
+ cmd.addRawArg("--add-reads");
+ cmd.addRawArg(entry.getKey() + "=" + String.join(",", entry.getValue()));
}
cmd.addRawArg("--module");
@@ -1241,10 +1225,7 @@ public class StartArgs
if (arg.startsWith("--skip-file-validation="))
{
List moduleNames = Props.getValues(arg);
- for (String moduleName : moduleNames)
- {
- skipFileValidationModules.add(moduleName);
- }
+ skipFileValidationModules.addAll(moduleNames);
return;
}
@@ -1388,12 +1369,7 @@ public class StartArgs
for (String moduleName : moduleNames)
{
modules.add(moduleName);
- List list = sources.get(moduleName);
- if (list == null)
- {
- list = new ArrayList<>();
- sources.put(moduleName,list);
- }
+ List list = sources.computeIfAbsent(moduleName, k -> new ArrayList<>());
list.add(source);
}
}
@@ -1484,17 +1460,7 @@ public class StartArgs
@Override
public String toString()
{
- StringBuilder builder = new StringBuilder();
- builder.append("StartArgs [enabledModules=");
- builder.append(modules);
- builder.append(", xmlRefs=");
- builder.append(xmlRefs);
- builder.append(", properties=");
- builder.append(properties);
- builder.append(", jvmArgs=");
- builder.append(jvmArgs);
- builder.append("]");
- return builder.toString();
+ return String.format("%s[enabledModules=%s, xmlRefs=%s, properties=%s, jvmArgs=%s]",
+ getClass().getSimpleName(), modules, xmlRefs, properties, jvmArgs);
}
-
}
From c3ca4b7ee9d979e6d2e975bff521e4b3746c0c62 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Fri, 28 Sep 2018 15:29:32 +1000
Subject: [PATCH 050/931] Issue #2936 Test bad message error page
Signed-off-by: Greg Wilkins
---
.../eclipse/jetty/servlet/ErrorPageTest.java | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java
index dd2f1f7bfec..5ca8913035c 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java
@@ -31,6 +31,7 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.LocalConnector;
@@ -63,11 +64,13 @@ public class ErrorPageTest
context.addServlet(FailServlet.class, "/fail/*");
context.addServlet(FailClosedServlet.class, "/fail-closed/*");
context.addServlet(ErrorServlet.class, "/error/*");
+ context.addServlet(AppServlet.class, "/app/*");
ErrorPageErrorHandler error = new ErrorPageErrorHandler();
context.setErrorHandler(error);
error.addErrorPage(599,"/error/599");
error.addErrorPage(IllegalStateException.class.getCanonicalName(),"/error/TestException");
+ error.addErrorPage(BadMessageException.class,"/error/TestException");
error.addErrorPage(ErrorPageErrorHandler.GLOBAL_ERROR_PAGE,"/error/GlobalErrorPage");
_server.start();
@@ -157,6 +160,33 @@ public class ErrorPageTest
}
}
+ @Test
+ public void testBadMessage() throws Exception
+ {
+ String response = _connector.getResponse("GET /app?baa=%88%A4 HTTP/1.0\r\n\r\n");
+ assertThat(response, Matchers.containsString("HTTP/1.1 400 Unable to parse URI query"));
+ assertThat(response, Matchers.containsString("ERROR_PAGE: /TestException"));
+ assertThat(response, Matchers.containsString("ERROR_MESSAGE: Unable to parse URI query"));
+ assertThat(response, Matchers.containsString("ERROR_CODE: 400"));
+ assertThat(response, Matchers.containsString("ERROR_EXCEPTION: org.eclipse.jetty.http.BadMessageException: 400: Unable to parse URI query"));
+ assertThat(response, Matchers.containsString("ERROR_EXCEPTION_TYPE: class org.eclipse.jetty.http.BadMessageException"));
+ assertThat(response, Matchers.containsString("ERROR_SERVLET: org.eclipse.jetty.servlet.ErrorPageTest$AppServlet-"));
+ assertThat(response, Matchers.containsString("ERROR_REQUEST_URI: /app"));
+ assertThat(response, Matchers.containsString("getParameterMap()= {}"));
+ }
+
+
+ public static class AppServlet extends HttpServlet implements Servlet
+ {
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ PrintWriter writer = response.getWriter();
+ writer.println(request.getRequestURI());
+ writer.println(request.getParameterMap().toString());
+ }
+ }
+
public static class FailServlet extends HttpServlet implements Servlet
{
@Override
@@ -202,6 +232,7 @@ public class ErrorPageTest
writer.println("ERROR_EXCEPTION_TYPE: " + request.getAttribute(Dispatcher.ERROR_EXCEPTION_TYPE));
writer.println("ERROR_SERVLET: " + request.getAttribute(Dispatcher.ERROR_SERVLET_NAME));
writer.println("ERROR_REQUEST_URI: " + request.getAttribute(Dispatcher.ERROR_REQUEST_URI));
+ writer.println("getParameterMap()= " + request.getParameterMap());
}
}
From 2b11d30a45969aa126bdbc53d68f98ef1ff22987 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Fri, 28 Sep 2018 09:29:52 +0200
Subject: [PATCH 051/931] Issue #2868 - Adding SPNEGO authentication support
for Jetty Client.
Renamed server-side classes and added javadocs.
Deprecated old server-side classes in favor of the new ones.
Signed-off-by: Simone Bordet
---
.../client/util/SPNEGOAuthenticationTest.java | 10 ++---
...va => ConfigurableSpnegoLoginService.java} | 41 +++++++++++++++++--
.../jetty/security/SpnegoLoginService.java | 4 ++
...a => ConfigurableSpnegoAuthenticator.java} | 19 +++++++--
.../authentication/SpnegoAuthenticator.java | 4 ++
5 files changed, 66 insertions(+), 12 deletions(-)
rename jetty-security/src/main/java/org/eclipse/jetty/security/{SpnegoLoginService2.java => ConfigurableSpnegoLoginService.java} (86%)
rename jetty-security/src/main/java/org/eclipse/jetty/security/authentication/{SpnegoAuthenticator2.java => ConfigurableSpnegoAuthenticator.java} (91%)
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java
index 906a36d751a..df8453def1b 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java
@@ -39,12 +39,12 @@ import org.eclipse.jetty.client.api.AuthenticationStore;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;
+import org.eclipse.jetty.security.ConfigurableSpnegoLoginService;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.HashLoginService;
-import org.eclipse.jetty.security.SpnegoLoginService2;
import org.eclipse.jetty.security.authentication.AuthorizationService;
-import org.eclipse.jetty.security.authentication.SpnegoAuthenticator2;
+import org.eclipse.jetty.security.authentication.ConfigurableSpnegoAuthenticator;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.session.DefaultSessionIdManager;
@@ -88,7 +88,7 @@ public class SPNEGOAuthenticationTest extends AbstractHttpClientServerTest
private Path serviceKeyTabPath = testDirPath.resolve("service.keytab");
private Path clientKeyTabPath = testDirPath.resolve("client.keytab");
private SimpleKdcServer kdc;
- private SpnegoAuthenticator2 authenticator;
+ private ConfigurableSpnegoAuthenticator authenticator;
@BeforeEach
public void prepare() throws Exception
@@ -123,7 +123,7 @@ public class SPNEGOAuthenticationTest extends AbstractHttpClientServerTest
server = new Server();
server.setSessionIdManager(new DefaultSessionIdManager(server));
HashLoginService authorizationService = new HashLoginService(realm, realmPropsPath.toString());
- SpnegoLoginService2 loginService = new SpnegoLoginService2(realm, AuthorizationService.from(authorizationService, ""));
+ ConfigurableSpnegoLoginService loginService = new ConfigurableSpnegoLoginService(realm, AuthorizationService.from(authorizationService, ""));
loginService.addBean(authorizationService);
loginService.setKeyTabPath(serviceKeyTabPath);
loginService.setServiceName(serviceName);
@@ -138,7 +138,7 @@ public class SPNEGOAuthenticationTest extends AbstractHttpClientServerTest
mapping.setPathSpec("/secure");
mapping.setConstraint(constraint);
securityHandler.addConstraintMapping(mapping);
- authenticator = new SpnegoAuthenticator2();
+ authenticator = new ConfigurableSpnegoAuthenticator();
securityHandler.setAuthenticator(authenticator);
securityHandler.setLoginService(loginService);
securityHandler.setHandler(handler);
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService2.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java
similarity index 86%
rename from jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService2.java
rename to jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java
index 84c981a1817..48e9cc88047 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService2.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java
@@ -46,9 +46,20 @@ import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.Oid;
-public class SpnegoLoginService2 extends ContainerLifeCycle implements LoginService
+/**
+ *
A configurable (as opposed to using system properties) SPNEGO LoginService.
+ *
At startup, this LoginService will login via JAAS the service principal, composed
+ * of the {@link #getServiceName() service name} and the {@link #getHostName() host name},
+ * for example {@code HTTP/wonder.com}, using a {@code keyTab} file as the service principal
+ * credentials.
+ *
Upon receiving a HTTP request, the server tries to authenticate the client
+ * calling {@link #login(String, Object, ServletRequest)} where the GSS APIs are used to
+ * verify client tokens and (perhaps after a few round-trips) a {@code GSSContext} is
+ * established.
+ */
+public class ConfigurableSpnegoLoginService extends ContainerLifeCycle implements LoginService
{
- private static final Logger LOG = Log.getLogger(SpnegoLoginService2.class);
+ private static final Logger LOG = Log.getLogger(ConfigurableSpnegoLoginService.class);
private final GSSManager _gssManager = GSSManager.getInstance();
private final String _realm;
@@ -59,43 +70,67 @@ public class SpnegoLoginService2 extends ContainerLifeCycle implements LoginServ
private String _hostName;
private SpnegoContext _context;
- public SpnegoLoginService2(String realm, AuthorizationService authorizationService)
+ public ConfigurableSpnegoLoginService(String realm, AuthorizationService authorizationService)
{
_realm = realm;
_authorizationService = authorizationService;
}
+ /**
+ * @return the realm name
+ */
@Override
public String getName()
{
return _realm;
}
+ /**
+ * @return the path of the keyTab file containing service credentials
+ */
public Path getKeyTabPath()
{
return _keyTabPath;
}
+ /**
+ * @param keyTabFile the path of the keyTab file containing service credentials
+ */
public void setKeyTabPath(Path keyTabFile)
{
_keyTabPath = keyTabFile;
}
+ /**
+ * @return the service name, typically "HTTP"
+ * @see #getHostName()
+ */
public String getServiceName()
{
return _serviceName;
}
+ /**
+ * @param serviceName the service name
+ * @see #setHostName(String)
+ */
public void setServiceName(String serviceName)
{
_serviceName = serviceName;
}
+ /**
+ * @return the host name of the service
+ * @see #setServiceName(String)
+ */
public String getHostName()
{
return _hostName;
}
+ /**
+ * @param hostName the host name of the service
+ */
public void setHostName(String hostName)
{
_hostName = hostName;
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java
index 5ea42ddb145..41f30f0a736 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java
@@ -36,6 +36,10 @@ import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.Oid;
+/**
+ * @deprecated use {@link ConfigurableSpnegoLoginService} instead
+ */
+@Deprecated
public class SpnegoLoginService extends AbstractLifeCycle implements LoginService
{
private static final Logger LOG = Log.getLogger(SpnegoLoginService.class);
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator2.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java
similarity index 91%
rename from jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator2.java
rename to jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java
index 5e8bb43e881..59e0611af14 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator2.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java
@@ -42,14 +42,22 @@ import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.security.Constraint;
-public class SpnegoAuthenticator2 extends LoginAuthenticator
+/**
+ *
A LoginAuthenticator that uses SPNEGO and the GSS API to authenticate requests.
+ *
A successful authentication from a client is cached for a configurable
+ * {@link #getAuthenticationDuration() duration} using the HTTP session; this avoids
+ * that the client is asked to authenticate for every request.
+ *
+ * @see org.eclipse.jetty.security.ConfigurableSpnegoLoginService
+ */
+public class ConfigurableSpnegoAuthenticator extends LoginAuthenticator
{
- private static final Logger LOG = Log.getLogger(SpnegoAuthenticator2.class);
+ private static final Logger LOG = Log.getLogger(ConfigurableSpnegoAuthenticator.class);
private final String _authMethod;
private Duration _authenticationDuration = Duration.ofNanos(-1);
- public SpnegoAuthenticator2()
+ public ConfigurableSpnegoAuthenticator()
{
this(Constraint.__SPNEGO_AUTH);
}
@@ -59,7 +67,7 @@ public class SpnegoAuthenticator2 extends LoginAuthenticator
*
* @param authMethod the auth method
*/
- public SpnegoAuthenticator2(String authMethod)
+ public ConfigurableSpnegoAuthenticator(String authMethod)
{
_authMethod = authMethod;
}
@@ -70,6 +78,9 @@ public class SpnegoAuthenticator2 extends LoginAuthenticator
return _authMethod;
}
+ /**
+ * @return the authentication duration
+ */
public Duration getAuthenticationDuration()
{
return _authenticationDuration;
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java
index 0dfe1b6add5..8142eb7c4d8 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java
@@ -35,6 +35,10 @@ import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.security.Constraint;
+/**
+ * @deprecated use {@link ConfigurableSpnegoAuthenticator} instead.
+ */
+@Deprecated
public class SpnegoAuthenticator extends LoginAuthenticator
{
private static final Logger LOG = Log.getLogger(SpnegoAuthenticator.class);
From 02eccd55aeb988c8a0eba9c9d442e60575e1f0f0 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Fri, 28 Sep 2018 10:22:51 +0200
Subject: [PATCH 052/931] Issue #2191 - JPMS Support.
NPE fixes.
Signed-off-by: Simone Bordet
---
.../src/main/java/org/eclipse/jetty/start/StartArgs.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java
index e9c8e1464c8..58a31811064 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java
@@ -690,7 +690,7 @@ public class StartArgs
Map> dirsAndFiles = StreamSupport.stream(classpath.spliterator(), false)
.collect(Collectors.groupingBy(File::isDirectory));
List files = dirsAndFiles.get(false);
- if (!files.isEmpty())
+ if (files != null && !files.isEmpty())
{
cmd.addRawArg("--module-path");
String modules = files.stream()
@@ -699,7 +699,7 @@ public class StartArgs
cmd.addRawArg(modules);
}
List dirs = dirsAndFiles.get(true);
- if (!dirs.isEmpty())
+ if (dirs != null && !dirs.isEmpty())
{
cmd.addRawArg("--class-path");
String directories = dirs.stream()
From 5cac3376c60e024b70a18b31d41759dfe9775891 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Fri, 28 Sep 2018 13:23:43 +0200
Subject: [PATCH 053/931] Issue #2191 - JPMS Support.
JPMS documentation.
Signed-off-by: Simone Bordet
---
.../administration/startup/chapter.adoc | 1 +
.../administration/startup/startup-jpms.adoc | 190 ++++++++++++++++++
2 files changed, 191 insertions(+)
create mode 100644 jetty-documentation/src/main/asciidoc/administration/startup/startup-jpms.adoc
diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/chapter.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/chapter.adoc
index 441d8d47d87..3b63ab8ae5e 100644
--- a/jetty-documentation/src/main/asciidoc/administration/startup/chapter.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/startup/chapter.adoc
@@ -28,3 +28,4 @@ include::custom-modules.adoc[]
include::startup-xml-config.adoc[]
include::startup-unix-service.adoc[]
include::startup-windows-service.adoc[]
+include::startup-jpms.adoc[]
diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/startup-jpms.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/startup-jpms.adoc
new file mode 100644
index 00000000000..b6fdb7b9671
--- /dev/null
+++ b/jetty-documentation/src/main/asciidoc/administration/startup/startup-jpms.adoc
@@ -0,0 +1,190 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2018 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.
+// ========================================================================
+//
+
+[[startup-overview]]
+=== Startup using the Java Platform Module System (JPMS)
+
+Jetty modules are also automatic https://en.wikipedia.org/wiki/Java_Platform_Module_System[JPMS]
+modules via the `Automatic-Module-Name` attribute in the jar's `MANIFEST.MF` file.
+
+This makes possible to run Jetty from the module-path, rather than the class-path.
+
+We recommend to use JDK 11 or greater due to the fact that JDK 11 removed all the
+"enterprise" modules from the JDK.
+The classes in these "enterprise" modules were bundled with JDK 8, and present in
+"enterprise" modules in JDK 9 and JDK 10.
+With JDK 11, these "enterprise" classes are either not available in the JDK (because
+their corresponding module was removed), or they are present in a different module.
+
+Some of these "enterprise" classes are required by Jetty or by applications running
+in Jetty, so it is better to use a stable source for those classes by using JDK 11
+or greater.
+
+==== Starting Jetty on the module-path
+
+To start Jetty on the module-path, rather than the class-path, it is enough to add
+the `--jpms` option to the command line, for example:
+
+[source, screen, subs="{sub-order}"]
+....
+$ mkdir my-jetty-base
+$ cd my-jetty-base
+$ java -jar $JETTY_HOME/start.jar --add-to-start=http
+INFO : server transitively enabled, ini template available with --add-to-start=server
+INFO : http initialized in ${jetty.base}/start.ini
+INFO : threadpool transitively enabled, ini template available with --add-to-start=threadpool
+INFO : Base directory was modified
+$ java -jar $JETTY_HOME/start.jar --jpms
+....
+
+The example above creates a link:#startup-base-and-home[Jetty base directory] and
+enables the `http` module using `--add-to-start`.
+Then starts Jetty on the module-path using the `--jpms` option.
+
+----
+[NOTE]
+When running on the module-path using the `--jpms` option, the Jetty start mechanism
+will fork a second JVM passing it the right JVM options to run on the module-path.
+
+You will have two JVMs running: one that runs `start.jar` and one that runs Jetty on
+the module-path.
+----
+
+If you are interested in the details of how the command line to run Jetty on the
+module-path looks like, you can add the `--dry-run` option:
+
+[source, screen, subs="{sub-order}"]
+....
+$ java -jar $JETTY_HOME/start.jar --jpms --dry-run
+....
+
+You will see something like this (broken in sections for clarity):
+
+[source, screen, subs="{sub-order}"]
+....
+/opt/openjdk-11+28/bin/java
+--module-path /opt/jetty/lib/servlet-api-3.1.jar:/opt/jetty/lib/jetty-schemas-3.1.jar:/opt/jetty/lib/jetty-http-9.4.13-SNAPSHOT.jar:...
+--patch-module servlet.api=/opt/jetty/lib/jetty-schemas-3.1.jar
+--module org.eclipse.jetty.xml/org.eclipse.jetty.xml.XmlConfiguration /opt/jetty/etc/jetty-threadpool.xml /opt/jetty/etc/jetty.xml ...
+....
+
+The `--module-path` option specifies the list of Jetty jars. This list depends
+on the Jetty modules that have been enabled via `--add-to-start`.
+
+The `--patch-module` option is necessary for Servlet and JSP Containers to find XML DTDs
+and XML Schemas required to validate the various XML files present in web applications
+(such as `web.xml` and others).
+
+The `--module` option tells the JVM to run main class `XmlConfiguration` from the
+`org.eclipse.jetty.xml` module, with the given XML files as program arguments.
+
+When the JVM starts, module `org.eclipse.jetty.xml` is added to the set of JPMS
+_root modules_; all other Jetty modules, being automatic, will be resolved and added
+to the module graph; jars that are not modules such as `servlet-api-3.1.jar` are on
+the module-path and therefore will be made automatic modules by the JVM (hence the
+derived module name `servlet.api` for this jar, referenced by the `--patch-module`
+command line option above).
+
+==== Advanced JPMS Configuration
+
+Web applications may need additional services from the Servlet Container, such as
+JDBC `DataSource` references or JTA `UserTransaction` references.
+
+For example, for JDBC it is typical to store in JNDI a reference to the connection
+pool's `DataSource` (for example `com.zaxxer.hikari.HikariDataSource`) or a
+reference directly to the JDBC driver's `DataSource` (for example
+`com.mysql.jdbc.jdbc2.optional.MysqlDataSource`).
+Jetty needs to be able to instantiate those classes and therefore needs to be able
+to load those classes and all their super-classes, among which `javax.sql.DataSource`.
+
+When Jetty runs on the class-path, this is easily achieved by using a
+link:#custom-modules[custom module]:
+
+[source, screen, subs="{sub-order}"]
+.mysql.mod
+....
+[description]
+MySQL module
+
+[lib]
+lib/mysql/mysql-connector-java-*.jar
+....
+
+However, when running on the module-path, things are quite different.
+
+Class `javax.sql.DataSource` is in a JDK bundled module named `java.sql`, which is
+not automatic (it's a proper JPMS module) and it is not in the _root modules_ set;
+because it is not an automatic module, it is not added to the module graph, and
+therefore needs to be added explicitly using the JVM command line `--add-modules`.
+
+To add the JPMS module `java.sql` to the module graph, you need to modify
+`mysql.mod` in the following way:
+
+[source, screen, subs="{sub-order}"]
+.mysql.mod
+....
+[description]
+MySQL module
+
+[lib]
+lib/mysql/mysql-connector-java-*.jar
+
+[jpms]
+add-modules: java.sql
+....
+
+The new `[jpms]` section is only used when Jetty is started on the module-path
+via the `--jpms` command line option.
+
+Assuming that `mysql-connector-java-*.jar` is a non JPMS modular jar, or an
+automatic JPMS modular jar, the Jetty start mechanism will add
+`mysql-connector-java-*.jar` to the module-path, and will add the JVM command
+line option `--add-modules java.sql`.
+
+If `mysql-connector-java-*.jar` were a proper JPMS modular jar with name
+(for example) `com.mysql.jdbc`, then it would need to be explicitly added to
+the module graph, in this way:
+
+[source, screen, subs="{sub-order}"]
+.mysql.mod
+....
+[description]
+MySQL module
+
+[lib]
+lib/mysql/mysql-connector-java-*.jar
+
+[jpms]
+add-modules: com.mysql.jdbc
+....
+
+Now we don't need to add JPMS module `java.sql` explicitly because it would be
+a dependency of the `com.mysql.jdbc` module and therefore automatically added
+to the module graph.
+
+The `[jpms]` section has the following format:
+
+[source, screen, subs="{sub-order}"]
+....
+[jpms]
+add-modules: (,)*
+patch-module: =(:)*
+add-opens: /=(,)*
+add-exports: /=(,)*
+add-reads: =(,)*
+....
From b3739f42b85fc1870ef520625185ebee591a61ef Mon Sep 17 00:00:00 2001
From: Joakim Erdfelt
Date: Sun, 30 Sep 2018 07:01:06 -0500
Subject: [PATCH 054/931] Issue #2936 - Improving testcase to replicate
reported scenario as described
---
.../eclipse/jetty/servlet/ErrorPageTest.java | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java
index 5ca8913035c..b611afb6f6f 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java
@@ -65,12 +65,15 @@ public class ErrorPageTest
context.addServlet(FailClosedServlet.class, "/fail-closed/*");
context.addServlet(ErrorServlet.class, "/error/*");
context.addServlet(AppServlet.class, "/app/*");
+ context.addServlet(LongerAppServlet.class, "/longer.app/*");
ErrorPageErrorHandler error = new ErrorPageErrorHandler();
context.setErrorHandler(error);
error.addErrorPage(599,"/error/599");
+ error.addErrorPage(400,"/error/400");
+ // error.addErrorPage(500,"/error/500");
error.addErrorPage(IllegalStateException.class.getCanonicalName(),"/error/TestException");
- error.addErrorPage(BadMessageException.class,"/error/TestException");
+ error.addErrorPage(BadMessageException.class,"/error/BadMessageException");
error.addErrorPage(ErrorPageErrorHandler.GLOBAL_ERROR_PAGE,"/error/GlobalErrorPage");
_server.start();
@@ -164,8 +167,8 @@ public class ErrorPageTest
public void testBadMessage() throws Exception
{
String response = _connector.getResponse("GET /app?baa=%88%A4 HTTP/1.0\r\n\r\n");
- assertThat(response, Matchers.containsString("HTTP/1.1 400 Unable to parse URI query"));
- assertThat(response, Matchers.containsString("ERROR_PAGE: /TestException"));
+ assertThat(response, Matchers.containsString("HTTP/1.1 400 Bad Request"));
+ assertThat(response, Matchers.containsString("ERROR_PAGE: /BadMessageException"));
assertThat(response, Matchers.containsString("ERROR_MESSAGE: Unable to parse URI query"));
assertThat(response, Matchers.containsString("ERROR_CODE: 400"));
assertThat(response, Matchers.containsString("ERROR_EXCEPTION: org.eclipse.jetty.http.BadMessageException: 400: Unable to parse URI query"));
@@ -177,13 +180,21 @@ public class ErrorPageTest
public static class AppServlet extends HttpServlet implements Servlet
+ {
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ request.getRequestDispatcher("/longer.app/").forward(request, response);
+ }
+ }
+
+ public static class LongerAppServlet extends HttpServlet implements Servlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
PrintWriter writer = response.getWriter();
writer.println(request.getRequestURI());
- writer.println(request.getParameterMap().toString());
}
}
From fe66e3d0cbda56c05c5e9de2cb7b59cd199c7096 Mon Sep 17 00:00:00 2001
From: Joakim Erdfelt
Date: Mon, 1 Oct 2018 10:43:57 -0500
Subject: [PATCH 055/931] Issue #2936 - Allow Dispatcher.error() to work for
BadMessageException
Signed-off-by: Joakim Erdfelt
---
.../org/eclipse/jetty/server/Dispatcher.java | 21 +++++++++++++++++--
.../eclipse/jetty/servlet/ErrorPageTest.java | 6 +++---
2 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java
index bba38c90b6e..d2033a488b7 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java
@@ -31,6 +31,7 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.Attributes;
@@ -195,8 +196,24 @@ public class Dispatcher implements RequestDispatcher
baseRequest.setContextPath(_contextHandler.getContextPath());
baseRequest.setServletPath(null);
baseRequest.setPathInfo(_pathInContext);
- if (_uri.getQuery()!=null || old_uri.getQuery()!=null)
- baseRequest.mergeQueryParameters(old_uri.getQuery(),_uri.getQuery(), true);
+
+ if (_uri.getQuery() != null || old_uri.getQuery() != null)
+ {
+ try
+ {
+ baseRequest.mergeQueryParameters(old_uri.getQuery(), _uri.getQuery(), true);
+ }
+ catch (BadMessageException e)
+ {
+ // Only throw BME if not in Error Dispatch Mode
+ // This allows application ErrorPageErrorHandler to handle BME messages
+ Boolean inErrorDispatch = (Boolean) request.getAttribute(__ERROR_DISPATCH);
+ if(inErrorDispatch == null || !inErrorDispatch)
+ {
+ throw e;
+ }
+ }
+ }
baseRequest.setAttributes(attr);
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java
index b611afb6f6f..7fd8431a4cb 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java
@@ -167,11 +167,11 @@ public class ErrorPageTest
public void testBadMessage() throws Exception
{
String response = _connector.getResponse("GET /app?baa=%88%A4 HTTP/1.0\r\n\r\n");
- assertThat(response, Matchers.containsString("HTTP/1.1 400 Bad Request"));
+ assertThat(response, Matchers.containsString("HTTP/1.1 400 Bad query encoding"));
assertThat(response, Matchers.containsString("ERROR_PAGE: /BadMessageException"));
- assertThat(response, Matchers.containsString("ERROR_MESSAGE: Unable to parse URI query"));
+ assertThat(response, Matchers.containsString("ERROR_MESSAGE: Bad query encoding"));
assertThat(response, Matchers.containsString("ERROR_CODE: 400"));
- assertThat(response, Matchers.containsString("ERROR_EXCEPTION: org.eclipse.jetty.http.BadMessageException: 400: Unable to parse URI query"));
+ assertThat(response, Matchers.containsString("ERROR_EXCEPTION: org.eclipse.jetty.http.BadMessageException: 400: Bad query encoding"));
assertThat(response, Matchers.containsString("ERROR_EXCEPTION_TYPE: class org.eclipse.jetty.http.BadMessageException"));
assertThat(response, Matchers.containsString("ERROR_SERVLET: org.eclipse.jetty.servlet.ErrorPageTest$AppServlet-"));
assertThat(response, Matchers.containsString("ERROR_REQUEST_URI: /app"));
From a094dbaa697b06b640deae5e2b083f89b4637310 Mon Sep 17 00:00:00 2001
From: Olivier Lamy
Date: Tue, 2 Oct 2018 16:44:24 +1000
Subject: [PATCH 056/931] fix osgi tests not running as paxexam is not junit5
ready (#2945)
* fix osgi tests not running as paxexam is not junit5 ready
Signed-off-by: olivier lamy
* upgrade pax exam to 4.12.0
Signed-off-by: olivier lamy
* cleanup comment, using transitive deps from pax-exam-junit4
Signed-off-by: olivier lamy
---
jetty-osgi/test-jetty-osgi/pom.xml | 21 +++++++++------------
pom.xml | 7 -------
2 files changed, 9 insertions(+), 19 deletions(-)
diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml
index 921948f8ea6..40340aa2fbb 100644
--- a/jetty-osgi/test-jetty-osgi/pom.xml
+++ b/jetty-osgi/test-jetty-osgi/pom.xml
@@ -14,7 +14,7 @@
${project.groupId}.boot.test.osgihttp://download.eclipse.org/jetty/orbit/target/distribution
- 4.11.0
+ 4.12.02.5.21.0true
@@ -45,15 +45,6 @@
pax-exam-junit4${exam.version}test
-
-
org.ops4j.pax.exam
@@ -405,13 +396,11 @@
org.ow2.asmasm
- ${asm.version}testorg.ow2.asmasm-commons
- ${asm.version}test
@@ -438,6 +427,14 @@
${settings.localRepository}
Implementation of the SPNEGO (or "Negotiate") authentication defined in RFC 4559.
+ *
A {@link #getUserName() user} is logged in via JAAS (either via userName/password or
+ * via userName/keyTab) once only.
+ *
For every request that needs authentication, a {@link GSSContext} is initiated and
+ * later established after reading the response from the server.
+ *
Applications should create objects of this class and add them to the
+ * {@link AuthenticationStore} retrieved from the {@link HttpClient}
+ * via {@link HttpClient#getAuthenticationStore()}.
+ */
public class SPNEGOAuthentication extends AbstractAuthentication
{
private static final Logger LOG = Log.getLogger(SPNEGOAuthentication.class);
@@ -73,71 +85,117 @@ public class SPNEGOAuthentication extends AbstractAuthentication
return NEGOTIATE;
}
+ /**
+ * @return the user name of the user to login
+ */
public String getUserName()
{
return userName;
}
+ /**
+ * @param userName user name of the user to login
+ */
public void setUserName(String userName)
{
this.userName = userName;
}
+ /**
+ * @return the password of the user to login
+ */
public String getUserPassword()
{
return userPassword;
}
+ /**
+ * @param userPassword the password of the user to login
+ * @see #setUserKeyTabPath(Path)
+ */
public void setUserPassword(String userPassword)
{
this.userPassword = userPassword;
}
+ /**
+ * @return the path of the keyTab file with the user credentials
+ */
public Path getUserKeyTabPath()
{
return userKeyTabPath;
}
+ /**
+ * @param userKeyTabPath the path of the keyTab file with the user credentials
+ * @see #setUserPassword(String)
+ */
public void setUserKeyTabPath(Path userKeyTabPath)
{
this.userKeyTabPath = userKeyTabPath;
}
+ /**
+ * @return the name of the service to use
+ */
public String getServiceName()
{
return serviceName;
}
+ /**
+ * @param serviceName the name of the service to use
+ */
public void setServiceName(String serviceName)
{
this.serviceName = serviceName;
}
+ /**
+ * @return whether to use the ticket cache during login
+ */
public boolean isUseTicketCache()
{
return useTicketCache;
}
+ /**
+ * @param useTicketCache whether to use the ticket cache during login
+ * @see #setTicketCachePath(Path)
+ */
public void setUseTicketCache(boolean useTicketCache)
{
this.useTicketCache = useTicketCache;
}
+ /**
+ * @return the path of the ticket cache file
+ */
public Path getTicketCachePath()
{
return ticketCachePath;
}
+ /**
+ * @param ticketCachePath the path of the ticket cache file
+ * @see #setUseTicketCache(boolean)
+ */
public void setTicketCachePath(Path ticketCachePath)
{
this.ticketCachePath = ticketCachePath;
}
+ /**
+ * @return whether to renew the ticket granting ticket
+ */
public boolean isRenewTGT()
{
return renewTGT;
}
+ /**
+ * @param renewTGT whether to renew the ticket granting ticket
+ */
public void setRenewTGT(boolean renewTGT)
{
this.renewTGT = renewTGT;
From 6b5a46b63b61d82c3403a2fc6aa571a8a3e77237 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Tue, 2 Oct 2018 11:26:32 +0200
Subject: [PATCH 058/931] Issue #2868 - Adding SPNEGO authentication support
for Jetty Client.
Avoid hardcoded KDC port in tests.
Updated Krb5LoginModule options with refreshKrb5Config=true,
to make sure the KDC configuration is re-read for every test.
Signed-off-by: Simone Bordet
---
.../jetty/client/util/SPNEGOAuthentication.java | 1 +
.../jetty/client/util/SPNEGOAuthenticationTest.java | 11 ++++++++++-
.../security/ConfigurableSpnegoLoginService.java | 1 +
3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/SPNEGOAuthentication.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/SPNEGOAuthentication.java
index 5a383bedc56..601f4abfd24 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/SPNEGOAuthentication.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/SPNEGOAuthentication.java
@@ -349,6 +349,7 @@ public class SPNEGOAuthentication extends AbstractAuthentication
Map options = new HashMap<>();
if (LOG.isDebugEnabled())
options.put("debug", "true");
+ options.put("refreshKrb5Config", "true");
options.put("principal", getUserName());
options.put("isInitiator", "true");
Path keyTabPath = getUserKeyTabPath();
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java
index df8453def1b..1185418006a 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java
@@ -27,6 +27,7 @@ import java.nio.file.Path;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -102,13 +103,21 @@ public class SPNEGOAuthenticationTest extends AbstractHttpClientServerTest
kdc.setAllowTcp(true);
kdc.setKdcRealm(realm);
kdc.setWorkDir(testDirPath.toFile());
- kdc.setKdcTcpPort(8844);
kdc.init();
kdc.createAndExportPrincipals(serviceKeyTabPath.toFile(), serviceName + "/" + serviceHost);
kdc.createPrincipal(clientName + "@" + realm, clientPassword);
kdc.exportPrincipal(clientName, clientKeyTabPath.toFile());
kdc.start();
+
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("KDC started on port {}", kdc.getKdcTcpPort());
+ String krb5 = Files.readAllLines(testDirPath.resolve("krb5.conf")).stream()
+ .filter(line -> !line.startsWith("#"))
+ .collect(Collectors.joining(System.lineSeparator()));
+ LOG.debug("krb5.conf{}{}", System.lineSeparator(), krb5);
+ }
}
@AfterEach
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java
index 48e9cc88047..fe256d8e749 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java
@@ -295,6 +295,7 @@ public class ConfigurableSpnegoLoginService extends ContainerLifeCycle implement
if (LOG.isDebugEnabled())
options.put("debug", "true");
options.put("doNotPrompt", "true");
+ options.put("refreshKrb5Config", "true");
options.put("principal", principal);
options.put("useKeyTab", "true");
Path keyTabPath = getKeyTabPath();
From 20fff533c80f3b60939a5e72e7ac22260bf129a2 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Tue, 2 Oct 2018 11:59:52 +0200
Subject: [PATCH 059/931] Issue #2868 - Adding SPNEGO authentication support
for Jetty Client.
Updated server-side authentication logic after review.
Signed-off-by: Simone Bordet
---
.../ConfigurableSpnegoAuthenticator.java | 79 +++++++++----------
1 file changed, 37 insertions(+), 42 deletions(-)
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java
index 59e0611af14..23873e0f36d 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java
@@ -108,8 +108,44 @@ public class ConfigurableSpnegoAuthenticator extends LoginAuthenticator
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
+ String header = request.getHeader(HttpHeader.AUTHORIZATION.asString());
+ String spnegoToken = getSpnegoToken(header);
HttpSession httpSession = request.getSession(false);
- if (httpSession != null)
+
+ // We have a token from the client, so run the login.
+ if (header != null && spnegoToken != null)
+ {
+ SpnegoUserIdentity identity = (SpnegoUserIdentity)login(null, spnegoToken, request);
+ if (identity.isEstablished())
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("Sending final challenge");
+ SpnegoUserPrincipal principal = (SpnegoUserPrincipal)identity.getUserPrincipal();
+ setSpnegoToken(response, principal.getEncodedToken());
+
+ Duration authnDuration = getAuthenticationDuration();
+ if (!authnDuration.isNegative())
+ {
+ if (httpSession == null)
+ httpSession = request.getSession(true);
+ httpSession.setAttribute(UserIdentityHolder.ATTRIBUTE, new UserIdentityHolder(identity));
+ }
+ return new UserAuthentication(getAuthMethod(), identity);
+ }
+ else
+ {
+ if (DeferredAuthentication.isDeferred(response))
+ return Authentication.UNAUTHENTICATED;
+ if (LOG.isDebugEnabled())
+ LOG.debug("Sending intermediate challenge");
+ SpnegoUserPrincipal principal = (SpnegoUserPrincipal)identity.getUserPrincipal();
+ sendChallenge(response, principal.getEncodedToken());
+ return Authentication.SEND_CONTINUE;
+ }
+ }
+ // No token from the client; check if the client has logged in
+ // successfully before and the authentication has not expired.
+ else if (httpSession != null)
{
UserIdentityHolder holder = (UserIdentityHolder)httpSession.getAttribute(UserIdentityHolder.ATTRIBUTE);
if (holder != null)
@@ -130,47 +166,6 @@ public class ConfigurableSpnegoAuthenticator extends LoginAuthenticator
}
}
- String header = request.getHeader(HttpHeader.AUTHORIZATION.asString());
- String spnegoToken = getSpnegoToken(header);
-
- // The client has responded to the challenge we sent previously.
- if (header != null && spnegoToken != null)
- {
- SpnegoUserIdentity identity = (SpnegoUserIdentity)login(null, spnegoToken, request);
- if (identity != null)
- {
- if (identity.isEstablished())
- {
- if (!DeferredAuthentication.isDeferred(response))
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Sending final challenge");
- SpnegoUserPrincipal principal = (SpnegoUserPrincipal)identity.getUserPrincipal();
- setSpnegoToken(response, principal.getEncodedToken());
- }
-
- Duration authnDuration = getAuthenticationDuration();
- if (!authnDuration.isNegative())
- {
- if (httpSession == null)
- httpSession = request.getSession(true);
- httpSession.setAttribute(UserIdentityHolder.ATTRIBUTE, new UserIdentityHolder(identity));
- }
- return new UserAuthentication(getAuthMethod(), identity);
- }
- else
- {
- if (DeferredAuthentication.isDeferred(response))
- return Authentication.UNAUTHENTICATED;
- if (LOG.isDebugEnabled())
- LOG.debug("Sending intermediate challenge");
- SpnegoUserPrincipal principal = (SpnegoUserPrincipal)identity.getUserPrincipal();
- sendChallenge(response, principal.getEncodedToken());
- return Authentication.SEND_CONTINUE;
- }
- }
- }
-
if (DeferredAuthentication.isDeferred(response))
return Authentication.UNAUTHENTICATED;
From 42de1dffe0b7e195f6f87e0ad53598acb62f69bb Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Tue, 2 Oct 2018 13:25:33 +0200
Subject: [PATCH 060/931] Issue #2868 - Adding SPNEGO authentication support
for Jetty Client.
Fixed server-side logic after review.
Signed-off-by: Simone Bordet
---
.../ConfigurableSpnegoAuthenticator.java | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java
index 23873e0f36d..6cae1a4745b 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java
@@ -118,10 +118,15 @@ public class ConfigurableSpnegoAuthenticator extends LoginAuthenticator
SpnegoUserIdentity identity = (SpnegoUserIdentity)login(null, spnegoToken, request);
if (identity.isEstablished())
{
- if (LOG.isDebugEnabled())
- LOG.debug("Sending final challenge");
- SpnegoUserPrincipal principal = (SpnegoUserPrincipal)identity.getUserPrincipal();
- setSpnegoToken(response, principal.getEncodedToken());
+ if (!DeferredAuthentication.isDeferred(response))
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("Sending final token");
+ // Send to the client the final token so that the
+ // client can establish the GSS context with the server.
+ SpnegoUserPrincipal principal = (SpnegoUserPrincipal)identity.getUserPrincipal();
+ setSpnegoToken(response, principal.getEncodedToken());
+ }
Duration authnDuration = getAuthenticationDuration();
if (!authnDuration.isNegative())
From 103b1292ea42d625c38d73b168a879e0e52bcafa Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Tue, 2 Oct 2018 15:16:40 +0200
Subject: [PATCH 061/931] Fixed annotations on tests that should run on
specific JDK versions.
Signed-off-by: Simone Bordet
---
.../jetty/client/ssl/SslBytesClientTest.java | 15 ++++++-----
.../jetty/client/ssl/SslBytesServerTest.java | 25 +++++++++++--------
.../jetty/util/MultiReleaseJarFileTest.java | 12 ++++-----
3 files changed, 27 insertions(+), 25 deletions(-)
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesClientTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesClientTest.java
index a738af91c95..b30c0a39765 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesClientTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesClientTest.java
@@ -18,11 +18,6 @@
package org.eclipse.jetty.client.ssl;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
@@ -54,9 +49,13 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnJre;
import org.junit.jupiter.api.condition.JRE;
-/* This whole test is very specific to how TLS < 1.3 works.
- * Starting in Java 11, TLS/1.3 is now enabled by default.
- */
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+// This whole test is very specific to how TLS < 1.3 works.
+// Starting in Java 11, TLS/1.3 is now enabled by default.
@EnabledOnJre({JRE.JAVA_8, JRE.JAVA_9, JRE.JAVA_10})
public class SslBytesClientTest extends SslBytesTest
{
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java
index 92c3ff6ef8c..1fc70235043 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java
@@ -18,12 +18,6 @@
package org.eclipse.jetty.client.ssl;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.junit.jupiter.api.Assumptions.assumeTrue;
-import static org.junit.jupiter.api.condition.OS.LINUX;
-import static org.junit.jupiter.api.condition.OS.WINDOWS;
-
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.File;
@@ -72,20 +66,31 @@ import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
-import org.eclipse.jetty.util.JavaVersion;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.hamcrest.Matchers;
-
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.DisabledOnOs;
+import org.junit.jupiter.api.condition.EnabledOnJre;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.JRE;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import static org.junit.jupiter.api.condition.OS.LINUX;
+import static org.junit.jupiter.api.condition.OS.WINDOWS;
+
+// This whole test is very specific to how TLS < 1.3 works.
+@EnabledOnJre({JRE.JAVA_8, JRE.JAVA_9, JRE.JAVA_10})
public class SslBytesServerTest extends SslBytesTest
{
private final AtomicInteger sslFills = new AtomicInteger();
@@ -101,8 +106,6 @@ public class SslBytesServerTest extends SslBytesTest
private SimpleProxy proxy;
private Runnable idleHook;
- // This whole test is very specific to how TLS < 1.3 works.
- @DisabledOnJre( JRE.JAVA_11 )
@BeforeEach
public void init() throws Exception
{
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/MultiReleaseJarFileTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/MultiReleaseJarFileTest.java
index e22e98065b2..eaffe9edd5b 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/MultiReleaseJarFileTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/MultiReleaseJarFileTest.java
@@ -18,10 +18,6 @@
package org.eclipse.jetty.util;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
@@ -31,9 +27,13 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.MultiReleaseJarFile.VersionedJarEntry;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.EnabledOnJre;
+import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.JRE;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
public class MultiReleaseJarFileTest
{
private File example = MavenTestingUtils.getTestResourceFile("example.jar");
@@ -124,7 +124,7 @@ public class MultiReleaseJarFileTest
@Test
- @EnabledOnJre({JRE.JAVA_9, JRE.JAVA_10, JRE.JAVA_11})
+ @DisabledOnJre(JRE.JAVA_8)
public void testClassLoaderJava9() throws Exception
{
try(URLClassLoader loader = new URLClassLoader(new URL[]{example.toURI().toURL()}))
From 57ef060325ba094b2d44264d1c0e2f24918d50b7 Mon Sep 17 00:00:00 2001
From: Joakim Erdfelt
Date: Tue, 2 Oct 2018 08:39:05 -0500
Subject: [PATCH 062/931] Issue #2936 - Allow Dispatcher.error() to work for
BadMessageException
+ Applying fixes from review
Signed-off-by: Joakim Erdfelt
---
.../org/eclipse/jetty/server/Dispatcher.java | 11 +++++++--
.../eclipse/jetty/servlet/ErrorPageTest.java | 24 ++++++++++---------
2 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java
index d2033a488b7..c1baef1553d 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java
@@ -36,9 +36,13 @@ import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.Attributes;
import org.eclipse.jetty.util.MultiMap;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
public class Dispatcher implements RequestDispatcher
{
+ private static final Logger LOG = Log.getLogger(Dispatcher.class);
+
public final static String __ERROR_DISPATCH="org.eclipse.jetty.server.Dispatcher.ERROR";
/** Dispatch include attribute names */
@@ -207,11 +211,14 @@ public class Dispatcher implements RequestDispatcher
{
// Only throw BME if not in Error Dispatch Mode
// This allows application ErrorPageErrorHandler to handle BME messages
- Boolean inErrorDispatch = (Boolean) request.getAttribute(__ERROR_DISPATCH);
- if(inErrorDispatch == null || !inErrorDispatch)
+ if (dispatch != DispatcherType.ERROR)
{
throw e;
}
+ else
+ {
+ LOG.warn("Ignoring Original Bad Request Query String: " + old_uri, e);
+ }
}
}
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java
index 7fd8431a4cb..a0c230d5fec 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java
@@ -92,7 +92,6 @@ public class ErrorPageTest
public void testSendErrorClosedResponse() throws Exception
{
String response = _connector.getResponse("GET /fail-closed/ HTTP/1.0\r\n\r\n");
- System.out.println(response);
assertThat(response,Matchers.containsString("HTTP/1.1 599 599"));
assertThat(response,Matchers.containsString("DISPATCH: ERROR"));
assertThat(response,Matchers.containsString("ERROR_PAGE: /599"));
@@ -166,16 +165,19 @@ public class ErrorPageTest
@Test
public void testBadMessage() throws Exception
{
- String response = _connector.getResponse("GET /app?baa=%88%A4 HTTP/1.0\r\n\r\n");
- assertThat(response, Matchers.containsString("HTTP/1.1 400 Bad query encoding"));
- assertThat(response, Matchers.containsString("ERROR_PAGE: /BadMessageException"));
- assertThat(response, Matchers.containsString("ERROR_MESSAGE: Bad query encoding"));
- assertThat(response, Matchers.containsString("ERROR_CODE: 400"));
- assertThat(response, Matchers.containsString("ERROR_EXCEPTION: org.eclipse.jetty.http.BadMessageException: 400: Bad query encoding"));
- assertThat(response, Matchers.containsString("ERROR_EXCEPTION_TYPE: class org.eclipse.jetty.http.BadMessageException"));
- assertThat(response, Matchers.containsString("ERROR_SERVLET: org.eclipse.jetty.servlet.ErrorPageTest$AppServlet-"));
- assertThat(response, Matchers.containsString("ERROR_REQUEST_URI: /app"));
- assertThat(response, Matchers.containsString("getParameterMap()= {}"));
+ try (StacklessLogging ignore = new StacklessLogging(Dispatcher.class))
+ {
+ String response = _connector.getResponse("GET /app?baa=%88%A4 HTTP/1.0\r\n\r\n");
+ assertThat(response, Matchers.containsString("HTTP/1.1 400 Bad query encoding"));
+ assertThat(response, Matchers.containsString("ERROR_PAGE: /BadMessageException"));
+ assertThat(response, Matchers.containsString("ERROR_MESSAGE: Bad query encoding"));
+ assertThat(response, Matchers.containsString("ERROR_CODE: 400"));
+ assertThat(response, Matchers.containsString("ERROR_EXCEPTION: org.eclipse.jetty.http.BadMessageException: 400: Bad query encoding"));
+ assertThat(response, Matchers.containsString("ERROR_EXCEPTION_TYPE: class org.eclipse.jetty.http.BadMessageException"));
+ assertThat(response, Matchers.containsString("ERROR_SERVLET: org.eclipse.jetty.servlet.ErrorPageTest$AppServlet-"));
+ assertThat(response, Matchers.containsString("ERROR_REQUEST_URI: /app"));
+ assertThat(response, Matchers.containsString("getParameterMap()= {}"));
+ }
}
From 06430f1b041f55551f1afe075dd92fe9f5d00d3f Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Tue, 2 Oct 2018 16:10:52 +0200
Subject: [PATCH 063/931] Issue #2868 - Adding SPNEGO authentication support
for Jetty Client.
Restored behavior where authentication results are stored
no matter the response status.
Signed-off-by: Simone Bordet
---
.../eclipse/jetty/client/AuthenticationProtocolHandler.java | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java
index 3e40ae4fe6a..11328247ad1 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java
@@ -37,7 +37,6 @@ import org.eclipse.jetty.client.api.Result;
import org.eclipse.jetty.client.util.BufferingResponseListener;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.QuotedCSV;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -310,8 +309,7 @@ public abstract class AuthenticationProtocolHandler implements ProtocolHandler
@Override
public void onSuccess(Response response)
{
- if (response.getStatus() == HttpStatus.OK_200)
- client.getAuthenticationStore().addAuthenticationResult(authenticationResult);
+ client.getAuthenticationStore().addAuthenticationResult(authenticationResult);
}
}
}
From 462668e80a111ac343dedb4c8a46cd41e9ebd6d5 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Tue, 2 Oct 2018 21:54:05 +0200
Subject: [PATCH 064/931] Issue #2868 - Adding SPNEGO authentication support
for Jetty Client.
Running tests only on JDK 11, as apparently other JDKs have problems
with AES encryption/decryption.
Another hypothesis is that Kerby does AES encryption differently from
what earlier JDKs expect.
Signed-off-by: Simone Bordet
---
.../client/util/SPNEGOAuthenticationTest.java | 20 ++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java
index 1185418006a..8fa771ad4cd 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java
@@ -57,6 +57,8 @@ import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.security.Constraint;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.condition.DisabledOnJre;
+import org.junit.jupiter.api.condition.JRE;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
@@ -64,6 +66,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
+// Apparently only JDK 11 is able to run these tests.
+// See for example: https://bugs.openjdk.java.net/browse/JDK-8202439
+// where apparently the compiler gets the AES CPU instructions wrong.
+@DisabledOnJre({JRE.JAVA_8, JRE.JAVA_9, JRE.JAVA_10})
public class SPNEGOAuthenticationTest extends AbstractHttpClientServerTest
{
private static final Logger LOG = Log.getLogger(SPNEGOAuthenticationTest.class);
@@ -180,7 +186,7 @@ public class SPNEGOAuthenticationTest extends AbstractHttpClientServerTest
// Request without Authentication causes a 401
Request request = client.newRequest(uri).path("/secure");
- ContentResponse response = request.timeout(5, TimeUnit.SECONDS).send();
+ ContentResponse response = request.timeout(15, TimeUnit.SECONDS).send();
assertNotNull(response);
assertEquals(401, response.getStatus());
@@ -197,7 +203,7 @@ public class SPNEGOAuthenticationTest extends AbstractHttpClientServerTest
// Request with authentication causes a 401 (no previous successful authentication) + 200
request = client.newRequest(uri).path("/secure");
- response = request.timeout(5, TimeUnit.SECONDS).send();
+ response = request.timeout(15, TimeUnit.SECONDS).send();
assertNotNull(response);
assertEquals(200, response.getStatus());
// Authentication results for SPNEGO cannot be cached.
@@ -217,7 +223,7 @@ public class SPNEGOAuthenticationTest extends AbstractHttpClientServerTest
// The server has infinite authentication duration, so
// subsequent requests will be preemptively authorized.
request = client.newRequest(uri).path("/secure");
- response = request.timeout(5, TimeUnit.SECONDS).send();
+ response = request.timeout(15, TimeUnit.SECONDS).send();
assertNotNull(response);
assertEquals(200, response.getStatus());
assertEquals(1, requests.get());
@@ -259,14 +265,14 @@ public class SPNEGOAuthenticationTest extends AbstractHttpClientServerTest
});
Request request = client.newRequest(uri).path("/secure");
- Response response = request.timeout(5, TimeUnit.SECONDS).send();
+ Response response = request.timeout(15, TimeUnit.SECONDS).send();
assertEquals(200, response.getStatus());
// Expect 401 + 200.
assertEquals(2, requests.get());
requests.set(0);
request = client.newRequest(uri).path("/secure");
- response = request.timeout(5, TimeUnit.SECONDS).send();
+ response = request.timeout(15, TimeUnit.SECONDS).send();
assertEquals(200, response.getStatus());
// Authentication not expired on server, expect 200 only.
assertEquals(1, requests.get());
@@ -276,7 +282,7 @@ public class SPNEGOAuthenticationTest extends AbstractHttpClientServerTest
requests.set(0);
request = client.newRequest(uri).path("/secure");
- response = request.timeout(5, TimeUnit.SECONDS).send();
+ response = request.timeout(15, TimeUnit.SECONDS).send();
assertEquals(200, response.getStatus());
// Authentication expired, expect 401 + 200.
assertEquals(2, requests.get());
@@ -287,7 +293,7 @@ public class SPNEGOAuthenticationTest extends AbstractHttpClientServerTest
requests.set(0);
ByteArrayInputStream input = new ByteArrayInputStream("hello_world".getBytes(StandardCharsets.UTF_8));
request = client.newRequest(uri).method("POST").path("/secure").content(new InputStreamContentProvider(input));
- response = request.timeout(5, TimeUnit.SECONDS).send();
+ response = request.timeout(15, TimeUnit.SECONDS).send();
assertEquals(200, response.getStatus());
// Authentication expired, but POSTs are allowed.
assertEquals(1, requests.get());
From 85d512ceecef5bcc8604f309ca8319f4cd92793c Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Tue, 2 Oct 2018 21:55:09 +0200
Subject: [PATCH 065/931] Restored proper test timeout.
Signed-off-by: Simone Bordet
---
.../eclipse/jetty/proxy/ProxyServletTest.java | 26 ++++++++-----------
1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java
index 076945ed9db..715ca1e4967 100644
--- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java
+++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java
@@ -18,16 +18,6 @@
package org.eclipse.jetty.proxy;
-import static org.eclipse.jetty.http.HttpFieldsMatchers.containsHeader;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.instanceOf;
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
@@ -73,7 +63,6 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.DuplexConnectionPool;
import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.HttpContentResponse;
import org.eclipse.jetty.client.HttpProxy;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
@@ -96,7 +85,6 @@ import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
-import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.hamcrest.Matchers;
@@ -105,7 +93,15 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
-import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.eclipse.jetty.http.HttpFieldsMatchers.containsHeader;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
public class ProxyServletTest
{
@@ -1400,8 +1396,8 @@ public class ProxyServletTest
// Wait more than the idle timeout to break the connection.
Thread.sleep(2 * idleTimeout);
- assertTrue(serverLatch.await(555, TimeUnit.SECONDS));
- assertTrue(clientLatch.await(555, TimeUnit.SECONDS));
+ assertTrue(serverLatch.await(5, TimeUnit.SECONDS));
+ assertTrue(clientLatch.await(5, TimeUnit.SECONDS));
}
@ParameterizedTest
From baca9cae3982a51a39c406f9f3a457caa4fbf700 Mon Sep 17 00:00:00 2001
From: Olivier Lamy
Date: Wed, 3 Oct 2018 09:54:05 +1000
Subject: [PATCH 066/931] Use cache to download to mongo and upgrade mongodb
plugin (#2949)
* cache downloading mongodb and upgrade mongodb embeded plugin
Signed-off-by: olivier lamy
* force mongodb version
Signed-off-by: olivier lamy
---
tests/test-sessions/test-mongodb-sessions/pom.xml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tests/test-sessions/test-mongodb-sessions/pom.xml b/tests/test-sessions/test-mongodb-sessions/pom.xml
index c1f719beadc..bc6224e3b78 100644
--- a/tests/test-sessions/test-mongodb-sessions/pom.xml
+++ b/tests/test-sessions/test-mongodb-sessions/pom.xml
@@ -121,7 +121,7 @@
com.github.joelittlejohn.embedmongoembedmongo-maven-plugin
- 0.3.5
+ 0.4.1
@@ -137,6 +137,8 @@
false
+ https://jenkins.webtide.net/userContent/
+ 2.2.1
From 9d37feba3c6c9982883c51a2380cf1330b2125ce Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Wed, 3 Oct 2018 10:00:14 +1000
Subject: [PATCH 067/931] Cleanup after #2903 (#2933)
Improved dump output of ServletHandler and ContextHandler
Fixed duplicate listeners
Removed unused fields
Signed-off-by: Greg Wilkins
---
.../jetty/embedded/OneServletContext.java | 80 +++++++++++++++++-
.../jetty/server/handler/ContextHandler.java | 11 ++-
.../eclipse/jetty/servlet/FilterMapping.java | 34 ++++++--
.../eclipse/jetty/servlet/ListenerHolder.java | 7 +-
.../jetty/servlet/ServletContextHandler.java | 11 +--
.../eclipse/jetty/servlet/ServletHandler.java | 84 ++++++-------------
.../util/component/DumpableCollection.java | 9 +-
.../webapp/StandardDescriptorProcessor.java | 10 +--
8 files changed, 155 insertions(+), 91 deletions(-)
diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneServletContext.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneServletContext.java
index a09dab91db1..832aa5af384 100644
--- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneServletContext.java
+++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneServletContext.java
@@ -20,8 +20,23 @@ package org.eclipse.jetty.embedded;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.DefaultServlet;
+import org.eclipse.jetty.servlet.ListenerHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
+import javax.servlet.DispatcherType;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.ServletResponse;
+import java.io.IOException;
+import java.util.EnumSet;
+
public class OneServletContext
{
public static void main( String[] args ) throws Exception
@@ -35,11 +50,72 @@ public class OneServletContext
server.setHandler(context);
// Add dump servlet
- context.addServlet(DumpServlet.class, "/dump/*");
- // Add default servlet
+ context.addServlet(
+ context.addServlet(DumpServlet.class, "/dump/*"),
+ "*.dump");
+ context.addServlet(HelloServlet.class, "/hello/*");
context.addServlet(DefaultServlet.class, "/");
+ context.addFilter(TestFilter.class,"/*", EnumSet.of(DispatcherType.REQUEST));
+ context.addFilter(TestFilter.class,"/test", EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
+ context.addFilter(TestFilter.class,"*.test", EnumSet.of(DispatcherType.REQUEST,DispatcherType.INCLUDE,DispatcherType.FORWARD));
+
+ context.getServletHandler().addListener(new ListenerHolder(InitListener.class));
+ context.getServletHandler().addListener(new ListenerHolder(RequestListener.class));
+
server.start();
+ server.dumpStdErr();
server.join();
}
+
+
+ public static class TestFilter implements Filter
+ {
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException
+ {
+
+ }
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
+ {
+ chain.doFilter(request, response);
+ }
+
+ @Override
+ public void destroy()
+ {
+
+ }
+ }
+
+ public static class InitListener implements ServletContextListener
+ {
+ @Override
+ public void contextInitialized(ServletContextEvent sce)
+ {
+ }
+
+ @Override
+ public void contextDestroyed(ServletContextEvent sce)
+ {
+ }
+ }
+
+
+ public static class RequestListener implements ServletRequestListener
+ {
+ @Override
+ public void requestDestroyed(ServletRequestEvent sre)
+ {
+
+ }
+
+ @Override
+ public void requestInitialized(ServletRequestEvent sre)
+ {
+
+ }
+ }
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
index e3fa2e32d81..e9560d603b2 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
@@ -201,7 +201,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
private final List _servletRequestAttributeListeners = new CopyOnWriteArrayList<>();
private final List _contextListeners = new CopyOnWriteArrayList<>();
private final List _durableListeners = new CopyOnWriteArrayList<>();
- private Map _managedAttributes;
private String[] _protectedTargets;
private final CopyOnWriteArrayList _aliasChecks = new CopyOnWriteArrayList();
@@ -258,9 +257,10 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
public void dump(Appendable out, String indent) throws IOException
{
dumpBeans(out,indent,Collections.singletonList(new ClassLoaderDump(getClassLoader())),
- Collections.singletonList(new DumpableCollection("Handler attributes " + this,((AttributesMap)getAttributes()).getAttributeEntrySet())),
- Collections.singletonList(new DumpableCollection("Context attributes " + this,((Context)getServletContext()).getAttributeEntrySet())),
- Collections.singletonList(new DumpableCollection("Initparams " + this,getInitParams().entrySet())));
+ Collections.singletonList(new DumpableCollection("eventListeners "+this,_eventListeners)),
+ Collections.singletonList(new DumpableCollection("handler attributes " + this,((AttributesMap)getAttributes()).getAttributeEntrySet())),
+ Collections.singletonList(new DumpableCollection("context attributes " + this,((Context)getServletContext()).getAttributeEntrySet())),
+ Collections.singletonList(new DumpableCollection("initparams " + this,getInitParams().entrySet())));
}
/* ------------------------------------------------------------ */
@@ -1553,10 +1553,9 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
}
/* ------------------------------------------------------------ */
+ @Deprecated
public void setManagedAttribute(String name, Object value)
{
- Object old = _managedAttributes.put(name,value);
- updateBean(old,value);
}
/* ------------------------------------------------------------ */
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java
index e37eef01166..50a1f6bf94e 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java
@@ -19,7 +19,9 @@
package org.eclipse.jetty.servlet;
import java.io.IOException;
+import java.util.Arrays;
import java.util.EnumSet;
+import java.util.stream.Collectors;
import javax.servlet.DispatcherType;
@@ -86,11 +88,31 @@ public class FilterMapping implements Dumpable
throw new IllegalArgumentException(type.toString());
}
+ /* ------------------------------------------------------------ */
+ /** Dispatch type from name
+ * @param type the dispatcher type
+ * @return the type constant ({@link #REQUEST}, {@link #ASYNC}, {@link #FORWARD}, {@link #INCLUDE}, or {@link #ERROR})
+ */
+ public static DispatcherType dispatch(int type)
+ {
+ switch(type)
+ {
+ case REQUEST:
+ return DispatcherType.REQUEST;
+ case ASYNC:
+ return DispatcherType.ASYNC;
+ case FORWARD:
+ return DispatcherType.FORWARD;
+ case INCLUDE:
+ return DispatcherType.INCLUDE;
+ case ERROR:
+ return DispatcherType.ERROR;
+ }
+ throw new IllegalArgumentException(Integer.toString(type));
+ }
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
-
-
private int _dispatches=DEFAULT;
private String _filterName;
private transient FilterHolder _holder;
@@ -122,7 +144,7 @@ public class FilterMapping implements Dumpable
/* ------------------------------------------------------------ */
/** Check if this filter applies to a particular dispatch type.
* @param type The type of request:
- * {@link Handler#REQUEST}, {@link Handler#FORWARD}, {@link Handler#INCLUDE} or {@link Handler#ERROR}.
+ * {@link #REQUEST}, {@link #FORWARD}, {@link #INCLUDE} or {@link #ERROR}.
* @return true if this filter applies
*/
boolean appliesTo(int type)
@@ -295,9 +317,9 @@ public class FilterMapping implements Dumpable
public String toString()
{
return
- TypeUtil.asList(_pathSpecs)+"/"+
- TypeUtil.asList(_servletNames)+"=="+
- _dispatches+"=>"+
+ TypeUtil.asList(_pathSpecs)+"/"+
+ TypeUtil.asList(_servletNames)+"/"+
+ Arrays.stream(DispatcherType.values()).filter(this::appliesTo).collect(Collectors.toSet())+"=>"+
_filterName;
}
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ListenerHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ListenerHolder.java
index 9e94f463f62..b3aa0e4c845 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ListenerHolder.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ListenerHolder.java
@@ -46,7 +46,12 @@ public class ListenerHolder extends BaseHolder
{
super(source);
}
-
+
+ public ListenerHolder(Class extends EventListener> listenerClass)
+ {
+ super(Source.EMBEDDED);
+ setHeldClass(listenerClass);
+ }
public EventListener getListener()
{
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java
index 8729025410b..21f51b86ad7 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java
@@ -153,7 +153,7 @@ public class ServletContextHandler extends ContextHandler
/* ------------------------------------------------------------ */
public ServletContextHandler(HandlerContainer parent, String contextPath, SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler,int options)
{
- super((ContextHandler.Context)null);
+ super(parent, contextPath);
_options=options;
_scontext = new Context();
_sessionHandler = sessionHandler;
@@ -163,15 +163,6 @@ public class ServletContextHandler extends ContextHandler
_objFactory = new DecoratedObjectFactory();
_objFactory.addDecorator(new DeprecationWarning());
- if (contextPath!=null)
- setContextPath(contextPath);
-
- if (parent instanceof HandlerWrapper)
- ((HandlerWrapper)parent).setHandler(this);
- else if (parent instanceof HandlerCollection)
- ((HandlerCollection)parent).addHandler(this);
-
-
// Link the handlers
relinkHandlers();
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
index 4ddaf61793f..34adff4bf68 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
@@ -32,6 +32,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
+import java.util.stream.Stream;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
@@ -67,6 +68,7 @@ import org.eclipse.jetty.util.MultiMap;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
+import org.eclipse.jetty.util.component.DumpableCollection;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -124,8 +126,6 @@ public class ServletHandler extends ScopedHandler
@SuppressWarnings("unchecked")
protected final Queue[] _chainLRU = new Queue[FilterMapping.ALL];
-
-
/* ------------------------------------------------------------ */
/** Constructor.
*/
@@ -133,6 +133,18 @@ public class ServletHandler extends ScopedHandler
{
}
+ /* ------------------------------------------------------------ */
+ @Override
+ public void dump(Appendable out, String indent) throws IOException
+ {
+ dumpBeans(out,indent,
+ Collections.singletonList(new DumpableCollection("listeners "+this,_listeners)),
+ Collections.singletonList(new DumpableCollection("filters "+this,_filters)),
+ Collections.singletonList(new DumpableCollection("filterMappings "+this,_filterMappings)),
+ Collections.singletonList(new DumpableCollection("servlets "+this,_servlets)),
+ Collections.singletonList(new DumpableCollection("servletMappings "+this,_servletMappings)));
+ }
+
/* ----------------------------------------------------------------- */
@Override
protected synchronized void doStart()
@@ -178,7 +190,7 @@ public class ServletHandler extends ScopedHandler
if (_contextHandler==null)
initialize();
-
+
super.doStart();
}
@@ -257,10 +269,8 @@ public class ServletHandler extends ScopedHandler
//Retain only filters and mappings that were added using jetty api (ie Source.EMBEDDED)
FilterHolder[] fhs = (FilterHolder[]) LazyList.toArray(filterHolders, FilterHolder.class);
- updateBeans(_filters, fhs);
_filters = fhs;
FilterMapping[] fms = (FilterMapping[]) LazyList.toArray(filterMappings, FilterMapping.class);
- updateBeans(_filterMappings, fms);
_filterMappings = fms;
_matchAfterIndex = (_filterMappings == null || _filterMappings.length == 0 ? -1 : _filterMappings.length-1);
@@ -302,10 +312,8 @@ public class ServletHandler extends ScopedHandler
//Retain only Servlets and mappings added via jetty apis (ie Source.EMBEDDED)
ServletHolder[] shs = (ServletHolder[]) LazyList.toArray(servletHolders, ServletHolder.class);
- updateBeans(_servlets, shs);
_servlets = shs;
ServletMapping[] sms = (ServletMapping[])LazyList.toArray(servletMappings, ServletMapping.class);
- updateBeans(_servletMappings, sms);
_servletMappings = sms;
//Retain only Listeners added via jetty apis (is Source.EMBEDDED)
@@ -327,7 +335,6 @@ public class ServletHandler extends ScopedHandler
}
}
ListenerHolder[] listeners = (ListenerHolder[])LazyList.toArray(listenerHolders, ListenerHolder.class);
- updateBeans(_listeners, listeners);
_listeners = listeners;
//will be regenerated on next start
@@ -730,60 +737,26 @@ public class ServletHandler extends ScopedHandler
{
MultiException mx = new MultiException();
- //start filter holders now
- if (_filters != null)
- {
- for (FilterHolder f: _filters)
- {
+ Stream.concat(Stream.concat(
+ Arrays.stream(_filters),
+ Arrays.stream(_servlets).sorted()),
+ Arrays.stream(_listeners))
+ .forEach(h->{
try
{
- f.start();
- f.initialize();
- }
- catch (Exception e)
- {
- mx.add(e);
- }
- }
- }
-
- // Sort and Initialize servlets
- if (_servlets!=null)
- {
- ServletHolder[] servlets = _servlets.clone();
- Arrays.sort(servlets);
- for (ServletHolder servlet : servlets)
- {
- try
- {
- servlet.start();
- servlet.initialize();
+ if (!h.isStarted())
+ {
+ h.start();
+ h.initialize();
+ }
}
catch (Throwable e)
{
LOG.debug(Log.EXCEPTION, e);
mx.add(e);
}
- }
- }
+ });
- //any other beans
- for (Holder> h: getBeans(Holder.class))
- {
- try
- {
- if (!h.isStarted())
- {
- h.start();
- h.initialize();
- }
- }
- catch (Exception e)
- {
- mx.add(e);
- }
- }
-
mx.ifExceptionThrow();
}
@@ -820,7 +793,6 @@ public class ServletHandler extends ScopedHandler
for (ListenerHolder holder:listeners)
holder.setServletHandler(this);
- updateBeans(_listeners,listeners);
_listeners = listeners;
}
@@ -1537,7 +1509,6 @@ public class ServletHandler extends ScopedHandler
*/
public void setFilterMappings(FilterMapping[] filterMappings)
{
- updateBeans(_filterMappings,filterMappings);
_filterMappings = filterMappings;
if (isStarted()) updateMappings();
invalidateChainsCache();
@@ -1550,7 +1521,6 @@ public class ServletHandler extends ScopedHandler
for (FilterHolder holder:holders)
holder.setServletHandler(this);
- updateBeans(_filters,holders);
_filters=holders;
updateNameMappings();
invalidateChainsCache();
@@ -1562,7 +1532,6 @@ public class ServletHandler extends ScopedHandler
*/
public void setServletMappings(ServletMapping[] servletMappings)
{
- updateBeans(_servletMappings,servletMappings);
_servletMappings = servletMappings;
if (isStarted()) updateMappings();
invalidateChainsCache();
@@ -1578,7 +1547,6 @@ public class ServletHandler extends ScopedHandler
for (ServletHolder holder:holders)
holder.setServletHandler(this);
- updateBeans(_servlets,holders);
_servlets=holders;
updateNameMappings();
invalidateChainsCache();
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/DumpableCollection.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/DumpableCollection.java
index 369e440758e..0fb4c13f139 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/component/DumpableCollection.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/DumpableCollection.java
@@ -19,7 +19,9 @@
package org.eclipse.jetty.util.component;
import java.io.IOException;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
public class DumpableCollection implements Dumpable
{
@@ -31,7 +33,12 @@ public class DumpableCollection implements Dumpable
_name=name;
_collection=collection;
}
-
+
+ public DumpableCollection(String name,Object... items)
+ {
+ this(name, items==null?Collections.emptyList():Arrays.asList(items));
+ }
+
@Override
public String dump()
{
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java
index fdfaede611b..21454cb806d 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java
@@ -1900,14 +1900,10 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
{
//Servlet Spec 3.0 p 74
//Duplicate listener declarations don't result in duplicate listener instances
- EventListener[] listeners=context.getEventListeners();
- if (listeners!=null)
+ for (ListenerHolder holder : context.getServletHandler().getListeners())
{
- for (EventListener l : listeners)
- {
- if (l.getClass().getName().equals(className))
- return;
- }
+ if (holder.getClassName().equals(className))
+ return;
}
((WebDescriptor)descriptor).addClassName(className);
From 64dc93050049c2f21a7b5af1092a22a0cc10801b Mon Sep 17 00:00:00 2001
From: WalkerWatch
Date: Wed, 3 Oct 2018 11:13:40 -0400
Subject: [PATCH 068/931] Clarify Websocket intro. Resolves #2951
---
.../development/websockets/intro/chapter.adoc | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)
diff --git a/jetty-documentation/src/main/asciidoc/development/websockets/intro/chapter.adoc b/jetty-documentation/src/main/asciidoc/development/websockets/intro/chapter.adoc
index fab182278a7..9a43439e238 100644
--- a/jetty-documentation/src/main/asciidoc/development/websockets/intro/chapter.adoc
+++ b/jetty-documentation/src/main/asciidoc/development/websockets/intro/chapter.adoc
@@ -19,14 +19,11 @@
[[websocket-intro]]
== WebSocket Introduction
-WebSocket is a new protocol for bidirectional communications over HTTP.
-
-It is based on a low level framing protocol that delivers messages in either UTF-8 TEXT or BINARY format.
-
-A single message in WebSocket can be of any size (the underlying framing however does have a single frame limit of http://en.wikipedia.org/wiki/9223372036854775807[63-bits])
+WebSocket is a new protocol for bidirectional communications initiated via HTTP/1.1 upgrade and providing basic message framing, layered over TCP.
+It is based on a low-level framing protocol that delivers messages in either UTF-8 TEXT or BINARY format.
+A single message in WebSocket can be of any size (the underlying framing however does have a single frame limit of http://en.wikipedia.org/wiki/9223372036854775807[63-bits]).
There can be an unlimited number of messages sent.
-
Messages are sent sequentially, the base protocol does not support interleaved messages.
A WebSocket connection goes through some basic state changes:
@@ -78,11 +75,9 @@ https://datatracker.ietf.org/doc/draft-ietf-hybi-websocket-perframe-compression/
Per Frame Compression Extension.
+
An early extension draft from the Google/Chromium team that would provide WebSocket frame compression.
-+
perframe-compression using deflate algorithm is present on many versions of Chrome/Chromium.
+
Jetty's support for perframe-compression is based on the draft-04 spec.
-+
This standard is being replaced with permessage-compression.
https://datatracker.ietf.org/doc/draft-tyoshino-hybi-permessage-compression/[permessage-compression]::
@@ -108,12 +103,11 @@ Java WebSocket Server API::
=== Enabling WebSocket
-To enable websocket, you need to link:#enabling-modules[enable] the `websocket` link:#enabling-modules[module].
+To enable Websocket, you need to enable the `websocket` link:#enabling-modules[module].
-Once this module is enabled for your jetty base, it will apply to all webapps deployed to that base.
-If you want to be more selective about which webapps use websocket, then you can:
+Once this module is enabled for your Jetty base, it will apply to all webapps deployed to that base. If you want to be more selective about which webapps use Websocket, then you can:
-Disable jsr-356 for a particular webapp:::
+Disable JSR-356 for a particular webapp:::
You can disable jsr-356 for a particular webapp by setting the link:#context_attributes[context attribute] `org.eclipse.jetty.websocket.jsr356` to `false`.
This will mean that websockets are not available to your webapp, however deployment time scanning for websocket-related classes such as endpoints will still occur.
This can be a significant impost if your webapp contains a lot of classes and/or jar files.
From 20db6700c0912c421adc6c612cece2051d204a7d Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Wed, 3 Oct 2018 18:24:59 +0200
Subject: [PATCH 069/931] Fixes #859 - Stack overflow error in jetty high level
API.
Now executing the call to abort() so that the stack overflow is avoided.
Signed-off-by: Simone Bordet
---
.../org/eclipse/jetty/client/HttpSender.java | 23 +++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpSender.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpSender.java
index d2d620c5e9a..a3093b994b2 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpSender.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpSender.java
@@ -19,6 +19,8 @@
package org.eclipse.jetty.client;
import java.nio.ByteBuffer;
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
@@ -338,18 +340,31 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
}
}
- protected boolean anyToFailure(Throwable failure)
+ private void anyToFailure(Throwable failure)
{
HttpExchange exchange = getHttpExchange();
if (exchange == null)
- return false;
+ return;
// Mark atomically the request as completed, with respect
// to concurrency between request success and request failure.
if (exchange.requestComplete(failure))
- return abort(exchange, failure);
+ executeAbort(exchange, failure);
+ }
- return false;
+ private void executeAbort(HttpExchange exchange, Throwable failure)
+ {
+ try
+ {
+ Executor executor = getHttpChannel().getHttpDestination().getHttpClient().getExecutor();
+ executor.execute(() -> abort(exchange, failure));
+ }
+ catch (RejectedExecutionException x)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug(x);
+ abort(exchange, failure);
+ }
}
private void terminateRequest(HttpExchange exchange)
From 76a9be8a822781489885483cee1ab33395435904 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Wed, 3 Oct 2018 19:24:05 +0200
Subject: [PATCH 070/931] Issue #2191 - JPMS Support.
Restored error message in case of wrong ASM version.
Signed-off-by: Simone Bordet
---
.../org/eclipse/jetty/annotations/AnnotationParser.java | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
index 0b3fe364b6d..e0b146bb006 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
@@ -84,11 +84,12 @@ public class AnnotationParser
*/
public static int asmVersion ()
{
+ String asmString = "ASM6";
int asmVersion = ASM_OPCODE_VERSION;
String version = ManifestUtils.getVersion(Opcodes.class).orElse(null);
if (version == null)
{
- LOG.warn("Unknown ASM version, assuming {}", ASM_OPCODE_VERSION);
+ LOG.warn("Unknown ASM version, assuming {}", asmString);
}
else
{
@@ -116,13 +117,13 @@ public class AnnotationParser
}
default:
{
- LOG.warn("Unrecognized ASM version, assuming {}", ASM_OPCODE_VERSION);
+ LOG.warn("Unrecognized ASM version, assuming {}", asmString);
}
}
}
catch (NumberFormatException e)
{
- LOG.warn("Unable to parse ASM version, assuming {}", ASM_OPCODE_VERSION);
+ LOG.warn("Unable to parse ASM version, assuming {}", asmString);
}
}
return asmVersion;
From 8e44abb1135f6b3e96b6040bebf2fb5b60c8754f Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Wed, 3 Oct 2018 22:20:58 +0200
Subject: [PATCH 071/931] Issue #2191 - JPMS Support.
Fixed OSGi manifest version reference.
Signed-off-by: Simone Bordet
---
jetty-plus/pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml
index e1a32f8345f..69a5a8a1980 100644
--- a/jetty-plus/pom.xml
+++ b/jetty-plus/pom.xml
@@ -43,7 +43,7 @@
true
- javax.transaction*;version="[1.3)",*
+ javax.transaction.*;version="1.3",*
From 4dcc7cbae6d5411d26094b52a7dfe05d93b05b43 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Thu, 4 Oct 2018 00:43:52 +0200
Subject: [PATCH 072/931] Issue #2191 - JPMS Support.
Restored String constant for the ASM version.
Signed-off-by: Simone Bordet
---
.../org/eclipse/jetty/annotations/AnnotationParser.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
index e0b146bb006..9ab39a1de78 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
@@ -70,6 +70,7 @@ public class AnnotationParser
{
private static final Logger LOG = Log.getLogger(AnnotationParser.class);
private static final int ASM_OPCODE_VERSION = Opcodes.ASM6; //compatibility of api
+ private static final String ASM_OPCODE_VERSION_STR = "ASM6";
/**
* Map of classnames scanned and the first location from which scan occurred
@@ -84,12 +85,11 @@ public class AnnotationParser
*/
public static int asmVersion ()
{
- String asmString = "ASM6";
int asmVersion = ASM_OPCODE_VERSION;
String version = ManifestUtils.getVersion(Opcodes.class).orElse(null);
if (version == null)
{
- LOG.warn("Unknown ASM version, assuming {}", asmString);
+ LOG.warn("Unknown ASM version, assuming {}", ASM_OPCODE_VERSION_STR);
}
else
{
@@ -117,13 +117,13 @@ public class AnnotationParser
}
default:
{
- LOG.warn("Unrecognized ASM version, assuming {}", asmString);
+ LOG.warn("Unrecognized ASM version, assuming {}", ASM_OPCODE_VERSION_STR);
}
}
}
catch (NumberFormatException e)
{
- LOG.warn("Unable to parse ASM version, assuming {}", asmString);
+ LOG.warn("Unable to parse ASM version, assuming {}", ASM_OPCODE_VERSION_STR);
}
}
return asmVersion;
From 9f7f0bdc5f3eb90157398cad2a64745a275844e9 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Thu, 4 Oct 2018 13:30:11 +1000
Subject: [PATCH 073/931] Pass BadMessageException from parser to
HttpReceiverOVerHTTP
This change has already mostly been made in 9.4, so essentially this is a back port. However the
primary signature of HttpParser.Handler for badMessage has not been changed and a default method
used to handle the cause. This avoids breaking any usages of the interface.
Signed-off-by: Greg Wilkins
---
.../jetty/client/HttpResponseException.java | 7 ++++++-
.../client/http/HttpReceiverOverHTTP.java | 8 +++++++-
.../client/http/HttpReceiverOverHTTPTest.java | 3 +++
.../org/eclipse/jetty/http/HttpParser.java | 18 ++++++++++++------
4 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponseException.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponseException.java
index e494170c34e..b9e568d5821 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponseException.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponseException.java
@@ -26,7 +26,12 @@ public class HttpResponseException extends RuntimeException
public HttpResponseException(String message, Response response)
{
- super(message);
+ this(message, response, null);
+ }
+
+ public HttpResponseException(String message, Response response, Throwable cause)
+ {
+ super(message, cause);
this.response = response;
}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java
index 3f839e7c535..8bc0ba2b3f2 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java
@@ -302,13 +302,19 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
@Override
public void badMessage(int status, String reason)
+ {
+ badMessage(status, reason, null);
+ }
+
+ @Override
+ public void badMessage(int status, String reason, Throwable cause)
{
HttpExchange exchange = getHttpExchange();
if (exchange != null)
{
HttpResponse response = exchange.getResponse();
response.status(status).reason(reason);
- failAndClose(new HttpResponseException("HTTP protocol violation: bad response on " + getHttpConnection(), response));
+ failAndClose(new HttpResponseException("HTTP protocol violation: bad response on " + getHttpConnection(), response, cause));
}
}
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTPTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTPTest.java
index 7702d27e8e8..cfef6dc577e 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTPTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTPTest.java
@@ -32,6 +32,7 @@ import org.eclipse.jetty.client.HttpResponseException;
import org.eclipse.jetty.client.Origin;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.util.FutureResponseListener;
+import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpVersion;
@@ -204,6 +205,8 @@ public class HttpReceiverOverHTTPTest
catch (ExecutionException e)
{
Assert.assertTrue(e.getCause() instanceof HttpResponseException);
+ Assert.assertTrue(e.getCause().getCause() instanceof BadMessageException);
+ Assert.assertTrue(e.getCause().getCause().getCause() instanceof NumberFormatException);
}
}
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
index 914a4068256..530b8c16644 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
@@ -996,7 +996,7 @@ public class HttpParser
catch(NumberFormatException e)
{
LOG.ignore(e);
- throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Invalid Content-Length Value");
+ throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Invalid Content-Length Value",e);
}
}
@@ -1453,7 +1453,7 @@ public class HttpParser
else
LOG.warn("bad HTTP parsed: "+e._code+(e.getReason()!=null?" "+e.getReason():"")+" for "+_handler);
setState(State.CLOSE);
- _handler.badMessage(e.getCode(), e.getReason());
+ _handler.badMessage(e.getCode(), e.getReason(), e);
}
catch(NumberFormatException|IllegalStateException e)
{
@@ -1461,19 +1461,19 @@ public class HttpParser
LOG.warn("parse exception: {} in {} for {}",e.toString(),_state,_handler);
if (DEBUG)
LOG.debug(e);
- badMessage();
+ badMessage(e);
}
catch(Exception|Error e)
{
BufferUtil.clear(buffer);
LOG.warn("parse exception: "+e.toString()+" for "+_handler,e);
- badMessage();
+ badMessage(e);
}
return false;
}
- protected void badMessage()
+ protected void badMessage(Throwable cause)
{
if (_headerComplete)
{
@@ -1482,7 +1482,7 @@ public class HttpParser
else if (_state!=State.CLOSED)
{
setState(State.CLOSE);
- _handler.badMessage(400,_requestHandler!=null?"Bad Request":"Bad Response");
+ _handler.badMessage(400,_requestHandler!=null?"Bad Request":"Bad Response", cause);
}
}
@@ -1803,6 +1803,12 @@ public class HttpParser
*/
public void badMessage(int status, String reason);
+ /* ------------------------------------------------------------ */
+ public default void badMessage(int status, String reason, Throwable cause)
+ {
+ badMessage(status, reason);
+ }
+
/* ------------------------------------------------------------ */
/** @return the size in bytes of the per parser header cache
*/
From 75942298f5dbfee03166e97ea4a17b3afda985bb Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Thu, 4 Oct 2018 10:51:16 +0200
Subject: [PATCH 074/931] Issue #2191 - JPMS Support.
Restored previous OSGi bundle name for apache-jsp.
Introduced a new property for the JPMS Automatic-Module-Name.
Signed-off-by: Simone Bordet
---
apache-jsp/pom.xml | 3 ++-
pom.xml | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/apache-jsp/pom.xml b/apache-jsp/pom.xml
index bf16e2ff53a..b82de9b0c08 100644
--- a/apache-jsp/pom.xml
+++ b/apache-jsp/pom.xml
@@ -10,7 +10,8 @@
http://www.eclipse.org/jettyjar
- ${project.groupId}.apache.jsp
+ ${project.groupId}.apache-jsp
+ ${project.groupId}.apache.jsp
diff --git a/pom.xml b/pom.xml
index 0edb642ac71..011626e9bd2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,6 +39,7 @@
false
+ ${bundle-symbolic-name}2.22.0
@@ -49,7 +50,6 @@
3.2.23.5.2
-
5.1
@@ -495,7 +495,7 @@
${project.build.outputDirectory}/META-INF/MANIFEST.MF
- ${bundle-symbolic-name}
+ ${jpms-module-name}${project.version}Eclipse.org - Jetty${jetty.url}
From 31d82e148e709bdc516a213aa40421fc137cd29c Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Thu, 4 Oct 2018 11:06:14 +0200
Subject: [PATCH 075/931] Issue #2191 - JPMS Support.
Using javax.transaction version starting from 1.1 for OSGi compatibility.
Signed-off-by: Simone Bordet
---
jetty-plus/pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml
index 69a5a8a1980..c9d45980978 100644
--- a/jetty-plus/pom.xml
+++ b/jetty-plus/pom.xml
@@ -43,7 +43,7 @@
true
- javax.transaction.*;version="1.3",*
+ javax.transaction.*;version="1.1",*
From 1ba945b39b1ca61aeb293e218ce9d1441c65cd22 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Thu, 4 Oct 2018 13:47:56 +0200
Subject: [PATCH 076/931] Issue #2941 - JDK 11: UnsupportedOperationException
at AnnotationParser.scanClass.
Updated to ASM 7.0-beta, and defaulted AnnotationParser to ASM 7.
Signed-off-by: Simone Bordet
---
.../eclipse/jetty/annotations/AnnotationParser.java | 10 +++++++---
pom.xml | 2 +-
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
index b6d9d35ceff..33e9f9e5f61 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
@@ -24,7 +24,6 @@ import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.nio.file.Path;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -69,8 +68,8 @@ import org.objectweb.asm.Opcodes;
public class AnnotationParser
{
private static final Logger LOG = Log.getLogger(AnnotationParser.class);
- protected static int ASM_OPCODE_VERSION = Opcodes.ASM6; //compatibility of api
- protected static String ASM_OPCODE_VERSION_STR = "ASM6";
+ protected static int ASM_OPCODE_VERSION = Opcodes.ASM7; //compatibility of api
+ protected static String ASM_OPCODE_VERSION_STR = "ASM7";
/**
* Map of classnames scanned and the first location from which scan occurred
@@ -118,6 +117,11 @@ public class AnnotationParser
asmVersion = Opcodes.ASM6;
break;
}
+ case 7:
+ {
+ asmVersion = Opcodes.ASM7;
+ break;
+ }
default:
{
LOG.warn("Unrecognized runtime asm version, assuming {}", ASM_OPCODE_VERSION_STR);
diff --git a/pom.xml b/pom.xml
index fae174072ef..9a16af6e4f2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
undefined1.1.4
- 6.2
+ 7.0-beta1.21benchmarks1.2.0
From 166eeaa1f6ecd2b50e7e4827bcaff2b683b3592a Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Fri, 5 Oct 2018 18:36:35 +1000
Subject: [PATCH 077/931] Jetty 9.3.x #2954 report cause (#2959)
Issue #2954 Report badmessage cause
Pass BadMessageException from parser to HttpReceiverOVerHTTP
This change has already mostly been made in 9.4, so essentially this is a back port. However the
primary signature of HttpParser.Handler for badMessage has not been changed and a default method
used to handle the cause. This avoids breaking any usages of the interface.
Signed-off-by: Greg Wilkins
---
.../client/AbstractHttpClientTransport.java | 1 +
.../jetty/client/HttpResponseException.java | 7 ++++++-
.../client/http/HttpReceiverOverHTTP.java | 8 +++++++-
.../client/http/HttpReceiverOverHTTPTest.java | 3 +++
.../org/eclipse/jetty/http/HttpParser.java | 18 ++++++++++++------
.../org/eclipse/jetty/io/ManagedSelector.java | 5 ++++-
6 files changed, 33 insertions(+), 9 deletions(-)
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java
index 7c091398948..9d61939458b 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java
@@ -135,6 +135,7 @@ public abstract class AbstractHttpClientTransport extends ContainerLifeCycle imp
catch (IOException xx)
{
LOG.ignore(xx);
+ x.addSuppressed(xx);
}
finally
{
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponseException.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponseException.java
index e494170c34e..b9e568d5821 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponseException.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponseException.java
@@ -26,7 +26,12 @@ public class HttpResponseException extends RuntimeException
public HttpResponseException(String message, Response response)
{
- super(message);
+ this(message, response, null);
+ }
+
+ public HttpResponseException(String message, Response response, Throwable cause)
+ {
+ super(message, cause);
this.response = response;
}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java
index 3f839e7c535..8bc0ba2b3f2 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java
@@ -302,13 +302,19 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
@Override
public void badMessage(int status, String reason)
+ {
+ badMessage(status, reason, null);
+ }
+
+ @Override
+ public void badMessage(int status, String reason, Throwable cause)
{
HttpExchange exchange = getHttpExchange();
if (exchange != null)
{
HttpResponse response = exchange.getResponse();
response.status(status).reason(reason);
- failAndClose(new HttpResponseException("HTTP protocol violation: bad response on " + getHttpConnection(), response));
+ failAndClose(new HttpResponseException("HTTP protocol violation: bad response on " + getHttpConnection(), response, cause));
}
}
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTPTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTPTest.java
index 7702d27e8e8..cfef6dc577e 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTPTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTPTest.java
@@ -32,6 +32,7 @@ import org.eclipse.jetty.client.HttpResponseException;
import org.eclipse.jetty.client.Origin;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.util.FutureResponseListener;
+import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpVersion;
@@ -204,6 +205,8 @@ public class HttpReceiverOverHTTPTest
catch (ExecutionException e)
{
Assert.assertTrue(e.getCause() instanceof HttpResponseException);
+ Assert.assertTrue(e.getCause().getCause() instanceof BadMessageException);
+ Assert.assertTrue(e.getCause().getCause().getCause() instanceof NumberFormatException);
}
}
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
index 914a4068256..530b8c16644 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
@@ -996,7 +996,7 @@ public class HttpParser
catch(NumberFormatException e)
{
LOG.ignore(e);
- throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Invalid Content-Length Value");
+ throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Invalid Content-Length Value",e);
}
}
@@ -1453,7 +1453,7 @@ public class HttpParser
else
LOG.warn("bad HTTP parsed: "+e._code+(e.getReason()!=null?" "+e.getReason():"")+" for "+_handler);
setState(State.CLOSE);
- _handler.badMessage(e.getCode(), e.getReason());
+ _handler.badMessage(e.getCode(), e.getReason(), e);
}
catch(NumberFormatException|IllegalStateException e)
{
@@ -1461,19 +1461,19 @@ public class HttpParser
LOG.warn("parse exception: {} in {} for {}",e.toString(),_state,_handler);
if (DEBUG)
LOG.debug(e);
- badMessage();
+ badMessage(e);
}
catch(Exception|Error e)
{
BufferUtil.clear(buffer);
LOG.warn("parse exception: "+e.toString()+" for "+_handler,e);
- badMessage();
+ badMessage(e);
}
return false;
}
- protected void badMessage()
+ protected void badMessage(Throwable cause)
{
if (_headerComplete)
{
@@ -1482,7 +1482,7 @@ public class HttpParser
else if (_state!=State.CLOSED)
{
setState(State.CLOSE);
- _handler.badMessage(400,_requestHandler!=null?"Bad Request":"Bad Response");
+ _handler.badMessage(400,_requestHandler!=null?"Bad Request":"Bad Response", cause);
}
}
@@ -1803,6 +1803,12 @@ public class HttpParser
*/
public void badMessage(int status, String reason);
+ /* ------------------------------------------------------------ */
+ public default void badMessage(int status, String reason, Throwable cause)
+ {
+ badMessage(status, reason);
+ }
+
/* ------------------------------------------------------------ */
/** @return the size in bytes of the per parser header cache
*/
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java
index e301c654a27..b3780d26b33 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java
@@ -258,11 +258,14 @@ public class ManagedSelector extends AbstractLifeCycle implements Runnable, Dump
}
catch (Throwable x)
{
- closeNoExceptions(_selector);
if (isRunning())
LOG.warn(x);
else
+ {
+ LOG.warn(x.toString());
LOG.debug(x);
+ }
+ closeNoExceptions(_selector);
}
return false;
}
From cec84cf1bf4edc9bda2ed9b964d1ebe72c6738e0 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Tue, 9 Oct 2018 15:53:53 +0200
Subject: [PATCH 078/931] Issue #2796 - Max local stream count exceeded when
request fails.
Reviewed other possible places where max local stream count may
overflow.
Fixed handling of HTTP/2 stream idle timeouts.
Signed-off-by: Simone Bordet
---
.../eclipse/jetty/client/HttpReceiver.java | 4 +--
.../org/eclipse/jetty/client/HttpRequest.java | 3 +-
.../org/eclipse/jetty/client/HttpSender.java | 4 +--
.../client/http/HttpConnectionOverHTTP.java | 4 ++-
.../fcgi/client/http/HttpChannelOverFCGI.java | 2 +-
.../org/eclipse/jetty/http2/HTTP2Session.java | 20 ++++++-----
.../org/eclipse/jetty/http2/HTTP2Stream.java | 7 ++--
.../org/eclipse/jetty/http2/api/Stream.java | 15 +++++++++
.../client/http/HttpReceiverOverHTTP2.java | 6 ++--
.../client/http/HttpSenderOverHTTP2.java | 4 ++-
.../client/http/MaxConcurrentStreamsTest.java | 33 ++++++++++---------
.../http/client/HttpClientContinueTest.java | 21 ++++++------
12 files changed, 75 insertions(+), 48 deletions(-)
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java
index 813672fb72c..1e33255f6fa 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java
@@ -550,14 +550,14 @@ public abstract class HttpReceiver
// respect to concurrency between request and response.
Result result = exchange.terminateResponse();
terminateResponse(exchange, result);
+ return true;
}
else
{
if (LOG.isDebugEnabled())
LOG.debug("Concurrent failure: response termination skipped, performed by helpers");
+ return false;
}
-
- return true;
}
private boolean updateResponseState(ResponseState from, ResponseState to)
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java
index e2ff05cd6b8..0d473085779 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java
@@ -76,7 +76,7 @@ public class HttpRequest implements Request
private String query;
private String method = HttpMethod.GET.asString();
private HttpVersion version = HttpVersion.HTTP_1_1;
- private long idleTimeout;
+ private long idleTimeout = -1;
private long timeout;
private long timeoutAt;
private ContentProvider content;
@@ -99,7 +99,6 @@ public class HttpRequest implements Request
extractParams(query);
followRedirects(client.isFollowRedirects());
- idleTimeout = client.getIdleTimeout();
HttpField acceptEncodingField = client.getAcceptEncodingField();
if (acceptEncodingField != null)
headers.put(acceptEncodingField);
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpSender.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpSender.java
index a3093b994b2..5aa9787d610 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpSender.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpSender.java
@@ -579,14 +579,14 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
// respect to concurrency between request and response.
Result result = exchange.terminateRequest();
terminateRequest(exchange, failure, result);
+ return true;
}
else
{
if (LOG.isDebugEnabled())
LOG.debug("Concurrent failure: request termination skipped, performed by helpers");
+ return false;
}
-
- return true;
}
private boolean updateRequestState(RequestState from, RequestState to)
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionOverHTTP.java
index 2e344c3c840..a6e69e8dad7 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionOverHTTP.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionOverHTTP.java
@@ -247,7 +247,9 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements Connec
// Save the old idle timeout to restore it.
EndPoint endPoint = getEndPoint();
idleTimeout = endPoint.getIdleTimeout();
- endPoint.setIdleTimeout(request.getIdleTimeout());
+ long requestIdleTimeout = request.getIdleTimeout();
+ if (requestIdleTimeout >= 0)
+ endPoint.setIdleTimeout(requestIdleTimeout);
// One channel per connection, just delegate the send.
return send(channel, exchange);
diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpChannelOverFCGI.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpChannelOverFCGI.java
index 520375ab16f..6ae8eb39fca 100644
--- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpChannelOverFCGI.java
+++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpChannelOverFCGI.java
@@ -166,7 +166,7 @@ public class HttpChannelOverFCGI extends HttpChannel
{
super(connection.getHttpDestination().getHttpClient().getScheduler());
this.connection = connection;
- setIdleTimeout(idleTimeout);
+ setIdleTimeout(idleTimeout >= 0 ? idleTimeout : connection.getEndPoint().getIdleTimeout());
}
@Override
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
index 04279864c5d..83a82d17eb7 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
@@ -341,7 +341,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
case SettingsFrame.MAX_CONCURRENT_STREAMS:
{
if (LOG.isDebugEnabled())
- LOG.debug("Updating max local concurrent streams to {} for {}", maxLocalStreams, this);
+ LOG.debug("Updating max local concurrent streams to {} for {}", value, this);
maxLocalStreams = value;
break;
}
@@ -561,7 +561,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
IStream stream = createLocalStream(streamId);
stream.setListener(listener);
- ControlEntry entry = new ControlEntry(frame, stream, new PromiseCallback<>(promise, stream));
+ ControlEntry entry = new ControlEntry(frame, stream, new StreamPromiseCallback(promise, stream));
queued = flusher.append(entry);
}
// Iterate outside the synchronized block.
@@ -605,7 +605,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
IStream pushStream = createLocalStream(streamId);
pushStream.setListener(listener);
- ControlEntry entry = new ControlEntry(frame, pushStream, new PromiseCallback<>(promise, pushStream));
+ ControlEntry entry = new ControlEntry(frame, pushStream, new StreamPromiseCallback(promise, pushStream));
queued = flusher.append(entry);
}
// Iterate outside the synchronized block.
@@ -779,6 +779,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
}
else
{
+ localStreamCount.decrementAndGet();
throw new IllegalStateException("Duplicate stream " + streamId);
}
}
@@ -815,6 +816,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
}
else
{
+ remoteStreamCount.addAndGetHi(-1);
onConnectionFailure(ErrorCode.PROTOCOL_ERROR.code, "duplicate_stream");
return null;
}
@@ -1461,21 +1463,21 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
}
}
- private static class PromiseCallback implements Callback
+ private static class StreamPromiseCallback implements Callback
{
- private final Promise promise;
- private final C value;
+ private final Promise promise;
+ private final IStream stream;
- private PromiseCallback(Promise promise, C value)
+ private StreamPromiseCallback(Promise promise, IStream stream)
{
this.promise = promise;
- this.value = value;
+ this.stream = stream;
}
@Override
public void succeeded()
{
- promise.succeeded(value);
+ promise.succeeded(stream);
}
@Override
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java
index b9609ad4903..265f57aa8a4 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java
@@ -139,6 +139,7 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa
{
if (writing.compareAndSet(null, callback))
return true;
+ close();
callback.failed(new WritePendingException());
return false;
}
@@ -275,8 +276,6 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa
private void onHeaders(HeadersFrame frame, Callback callback)
{
- if (updateClose(frame.isEndStream(), CloseState.Event.RECEIVED))
- session.removeStream(this);
MetaData metaData = frame.getMetaData();
if (metaData.isRequest() || metaData.isResponse())
{
@@ -286,6 +285,10 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa
length = fields.getLongField(HttpHeader.CONTENT_LENGTH.asString());
dataLength = length >= 0 ? length : Long.MIN_VALUE;
}
+
+ if (updateClose(frame.isEndStream(), CloseState.Event.RECEIVED))
+ session.removeStream(this);
+
callback.succeeded();
}
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java
index f76afeaf445..9e879cab891 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java
@@ -163,6 +163,13 @@ public interface Stream
*/
public void onData(Stream stream, DataFrame frame, Callback callback);
+ /**
+ *
Callback method invoked when a RST_STREAM frame has been received for this stream.
+ *
+ * @param stream the stream
+ * @param frame the RST_FRAME received
+ * @param callback the callback to complete when the reset has been handled
+ */
public default void onReset(Stream stream, ResetFrame frame, Callback callback)
{
try
@@ -214,6 +221,14 @@ public interface Stream
return true;
}
+ /**
+ *
Callback method invoked when the stream failed.
+ *
+ * @param stream the stream
+ * @param error the error code
+ * @param reason the error reason, or null
+ * @param callback the callback to complete when the failure has been handled
+ */
public default void onFailure(Stream stream, int error, String reason, Callback callback)
{
callback.succeeded();
diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java
index a0f1817a6bb..94fa9776fa2 100644
--- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java
+++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java
@@ -171,8 +171,10 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements Stream.Listen
@Override
public boolean onIdleTimeout(Stream stream, Throwable x)
{
- responseFailure(x);
- return true;
+ HttpExchange exchange = getHttpExchange();
+ if (exchange == null)
+ return false;
+ return !exchange.abort(x);
}
@Override
diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java
index 4950c949d3d..1635d27f912 100644
--- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java
+++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java
@@ -67,7 +67,9 @@ public class HttpSenderOverHTTP2 extends HttpSender
{
channel.setStream(stream);
((IStream)stream).setAttachment(channel);
- stream.setIdleTimeout(request.getIdleTimeout());
+ long idleTimeout = request.getIdleTimeout();
+ if (idleTimeout >= 0)
+ stream.setIdleTimeout(idleTimeout);
if (content.hasContent() && !expects100Continue(request))
{
diff --git a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/MaxConcurrentStreamsTest.java b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/MaxConcurrentStreamsTest.java
index fe030fa838f..9e981ee1e80 100644
--- a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/MaxConcurrentStreamsTest.java
+++ b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/MaxConcurrentStreamsTest.java
@@ -18,6 +18,22 @@
package org.eclipse.jetty.http2.client.http;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.IntStream;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
import org.eclipse.jetty.client.AbstractConnectionPool;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.HttpDestination;
@@ -43,21 +59,6 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.jupiter.api.Test;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ForkJoinPool;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.IntStream;
-
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -370,7 +371,7 @@ public class MaxConcurrentStreamsTest extends AbstractTest
}
@Test
- public void testTwoConcurrentStreamsFirstTimesOut() throws Exception
+ public void testTwoStreamsFirstTimesOut() throws Exception
{
long timeout = 1000;
start(1, new EmptyServerHandler()
diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientContinueTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientContinueTest.java
index eb34e6a7e43..a6ff741129c 100644
--- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientContinueTest.java
+++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientContinueTest.java
@@ -18,15 +18,6 @@
package org.eclipse.jetty.http.client;
-import static org.eclipse.jetty.http.client.Transport.FCGI;
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assumptions.assumeTrue;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -65,6 +56,15 @@ import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
+import static org.eclipse.jetty.http.client.Transport.FCGI;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
+
public class HttpClientContinueTest extends AbstractTest
{
@Override
@@ -344,13 +344,14 @@ public class HttpClientContinueTest extends AbstractTest
}
});
- scenario.client.setIdleTimeout(idleTimeout);
+ scenario.client.setIdleTimeout(2 * idleTimeout);
byte[] content = new byte[1024];
final CountDownLatch latch = new CountDownLatch(1);
scenario.client.newRequest(scenario.newURI())
.header(HttpHeader.EXPECT, HttpHeaderValue.CONTINUE.asString())
.content(new BytesContentProvider(content))
+ .idleTimeout(idleTimeout, TimeUnit.MILLISECONDS)
.send(new BufferingResponseListener()
{
@Override
From 6b6036a21c0f130387cdbccb6d3dddb4fce30712 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Tue, 9 Oct 2018 23:21:00 +0200
Subject: [PATCH 079/931] Issue #2771 - h2spec test failures.
Fixed Stream.isRemotelyClosed() to imply CLOSING as well.
Fixed logging.
Signed-off-by: Simone Bordet
---
.../main/java/org/eclipse/jetty/http2/HTTP2Session.java | 7 ++++---
.../src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java | 3 ++-
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
index 04279864c5d..fe2b90e6526 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
@@ -333,15 +333,16 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
}
case SettingsFrame.ENABLE_PUSH:
{
+ boolean enabled = value == 1;
if (LOG.isDebugEnabled())
- LOG.debug("{} push for {}", pushEnabled ? "Enabling" : "Disabling", this);
- pushEnabled = value == 1;
+ LOG.debug("{} push for {}", enabled ? "Enabling" : "Disabling", this);
+ pushEnabled = enabled;
break;
}
case SettingsFrame.MAX_CONCURRENT_STREAMS:
{
if (LOG.isDebugEnabled())
- LOG.debug("Updating max local concurrent streams to {} for {}", maxLocalStreams, this);
+ LOG.debug("Updating max local concurrent streams to {} for {}", value, this);
maxLocalStreams = value;
break;
}
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java
index b9609ad4903..e411c571e05 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java
@@ -176,7 +176,8 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa
@Override
public boolean isRemotelyClosed()
{
- return closeState.get() == CloseState.REMOTELY_CLOSED;
+ CloseState state = closeState.get();
+ return state == CloseState.REMOTELY_CLOSED || state == CloseState.CLOSING;
}
public boolean isLocallyClosed()
From 856b46b4b77ea9c523b3bf749b35428d1ff4809b Mon Sep 17 00:00:00 2001
From: Lachlan Roberts
Date: Wed, 10 Oct 2018 15:17:07 +1100
Subject: [PATCH 080/931] Issue #2892 - NPE in
MultiPartInputStreamParser#getPart
Signed-off-by: Lachlan Roberts
---
.../org/eclipse/jetty/util/MultiPartInputStreamParser.java | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java
index 1280e6f29d5..a1847b3540a 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java
@@ -39,8 +39,6 @@ import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
-
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Part;
@@ -515,7 +513,7 @@ public class MultiPartInputStreamParser
public Part getPart(String name)
throws IOException
{
- if(_parsed)
+ if(!_parsed)
parse();
throwIfError();
return _parts.getValue(name, 0);
From e727ad893d2c3415645153807a8763a499090dc3 Mon Sep 17 00:00:00 2001
From: Lachlan Roberts
Date: Wed, 10 Oct 2018 16:10:29 +1100
Subject: [PATCH 081/931] Fixes #2702 - ArithmeticException in
Credential.stringEquals and .byteEquals
Signed-off-by: Lachlan Roberts
---
.../jetty/util/security/Credential.java | 4 ++--
.../jetty/util/security/CredentialTest.java | 22 ++++++++++++++++---
2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java b/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java
index 862d3bd7605..2f86d7554e0 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java
@@ -105,7 +105,7 @@ public abstract class Credential implements Serializable
int l1 = known.length();
int l2 = unknown.length();
for (int i = 0; i < l2; ++i)
- result &= known.charAt(i%l1) == unknown.charAt(i);
+ result &= ((l1==0)?unknown.charAt(l2-i-1):known.charAt(i%l1)) == unknown.charAt(i);
return result && l1 == l2;
}
@@ -127,7 +127,7 @@ public abstract class Credential implements Serializable
int l1 = known.length;
int l2 = unknown.length;
for (int i = 0; i < l2; ++i)
- result &= known[i%l1] == unknown[i];
+ result &= ((l1==0)?unknown[l2-i-1]:known[i%l1]) == unknown[i];
return result && l1 == l2;
}
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/security/CredentialTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/security/CredentialTest.java
index a8aac3dbc48..5ea977f104a 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/security/CredentialTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/security/CredentialTest.java
@@ -20,13 +20,13 @@
package org.eclipse.jetty.util.security;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
import org.eclipse.jetty.util.security.Credential.Crypt;
import org.eclipse.jetty.util.security.Credential.MD5;
import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
/**
* CredentialTest
@@ -94,4 +94,20 @@ public class CredentialTest
assertFalse(Credential.byteEquals("foo".getBytes(),"fo".getBytes()));
assertFalse(Credential.byteEquals("foo".getBytes(),"bar".getBytes()));
}
+
+ @Test
+ public void testEmptyString()
+ {
+ assertFalse(Credential.stringEquals("fooo",""));
+ assertFalse(Credential.stringEquals("","fooo"));
+ assertTrue(Credential.stringEquals("",""));
+ }
+
+ @Test
+ public void testEmptyBytes()
+ {
+ assertFalse(Credential.byteEquals("fooo".getBytes(),"".getBytes()));
+ assertFalse(Credential.byteEquals("".getBytes(),"fooo".getBytes()));
+ assertTrue(Credential.byteEquals("".getBytes(),"".getBytes()));
+ }
}
From 34511670d108837de50bcb2d82429629ee40cc23 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Wed, 10 Oct 2018 10:27:02 +0200
Subject: [PATCH 082/931] Improved HTTP2Stream.toString().
Signed-off-by: Simone Bordet
---
.../src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java
index e411c571e05..3cc9d531ce0 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java
@@ -628,13 +628,14 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa
@Override
public String toString()
{
- return String.format("%s@%x#%d{sendWindow=%s,recvWindow=%s,reset=%b,%s,age=%d,attachment=%s}",
+ return String.format("%s@%x#%d{sendWindow=%s,recvWindow=%s,reset=%b/%b,%s,age=%d,attachment=%s}",
getClass().getSimpleName(),
hashCode(),
getId(),
sendWindow,
recvWindow,
- isReset(),
+ localReset,
+ remoteReset,
closeState,
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - timeStamp),
attachment);
From 8b44bed25ad22ab98f8b8103d0ee6e8e418040f2 Mon Sep 17 00:00:00 2001
From: Jan Bartel
Date: Thu, 11 Oct 2018 15:37:16 +1100
Subject: [PATCH 083/931] Issue #2975 Quickstart tests broken
---
tests/test-quickstart/pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/test-quickstart/pom.xml b/tests/test-quickstart/pom.xml
index 1fd74d1ce22..3e4363415b3 100644
--- a/tests/test-quickstart/pom.xml
+++ b/tests/test-quickstart/pom.xml
@@ -138,7 +138,7 @@
copy
- package
+ process-test-classescopy
From 29c51091c771cadae025fb6708047e7a0cdbbd9e Mon Sep 17 00:00:00 2001
From: Olivier Lamy
Date: Thu, 11 Oct 2018 17:47:52 +1000
Subject: [PATCH 084/931] Jetty 9.4.x simplify jenkinsfile (#2976)
* simplify Jenkinsfile
Signed-off-by: olivier lamy
* we need checkout scm
Signed-off-by: olivier lamy
* do not run the first install and move javadoc test to last part
Signed-off-by: olivier lamy
* remove comments
Signed-off-by: olivier lamy
---
Jenkinsfile | 54 +++++------------------------------------------------
1 file changed, 5 insertions(+), 49 deletions(-)
diff --git a/Jenkinsfile b/Jenkinsfile
index d116857064b..9ad5fa93007 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -22,58 +22,11 @@ def getFullBuild(jdk, os) {
def settingsName = 'oss-settings.xml'
def mavenOpts = '-Xms1g -Xmx4g -Djava.awt.headless=true'
-
try {
- stage("Checkout - ${jdk}") {
- checkout scm
- }
- } catch (Exception e) {
- notifyBuild("Checkout Failure", jdk)
- throw e
- }
-
- try {
- stage("Compile - ${jdk}") {
- timeout(time: 15, unit: 'MINUTES') {
- withMaven(
- maven: mvnName,
- jdk: "$jdk",
- publisherStrategy: 'EXPLICIT',
- globalMavenSettingsConfig: settingsName,
- mavenOpts: mavenOpts,
- mavenLocalRepo: localRepo) {
- sh "mvn -V -B clean install -DskipTests -T6 -e"
- }
- }
- }
- } catch(Exception e) {
- notifyBuild("Compile Failure", jdk)
- throw e
- }
-
- try {
- stage("Javadoc - ${jdk}") {
- timeout(time: 20, unit: 'MINUTES') {
- withMaven(
- maven: mvnName,
- jdk: "$jdk",
- publisherStrategy: 'EXPLICIT',
- globalMavenSettingsConfig: settingsName,
- mavenOpts: mavenOpts,
- mavenLocalRepo: localRepo) {
- sh "mvn -V -B javadoc:javadoc -T6 -e"
- }
- }
- }
- } catch(Exception e) {
- notifyBuild("Javadoc Failure", jdk)
- throw e
- }
-
- try {
- stage("Test - ${jdk}") {
+ stage("Build ${jdk}/${os}") {
timeout(time: 90, unit: 'MINUTES') {
// Run test phase / ignore test failures
+ checkout scm
withMaven(
maven: mvnName,
jdk: "$jdk",
@@ -83,6 +36,7 @@ def getFullBuild(jdk, os) {
mavenOpts: mavenOpts,
mavenLocalRepo: localRepo) {
sh "mvn -V -B install -Dmaven.test.failure.ignore=true -e -Pmongodb -T3 -Djetty.testtracker.log=true -Dunix.socket.tmp="+env.JENKINS_HOME
+ sh "mvn -V -B javadoc:javadoc -T6 -e"
}
// withMaven doesn't label..
// Report failures in the jenkins UI
@@ -112,6 +66,8 @@ def getFullBuild(jdk, os) {
consoleParsers = [[parserName: 'Maven'],
[parserName: 'JavaDoc'],
[parserName: 'JavaC']];
+ step([$class: 'MavenInvokerRecorder', reportsFilenamePattern: "**/target/invoker-reports/BUILD*.xml",
+ invokerBuildDir: "**/target/its"])
}
// Report on Maven and Javadoc warnings
From ec2b5b1810e3b6537c86510e31b6efa58418a66e Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Thu, 11 Oct 2018 15:56:47 +0200
Subject: [PATCH 085/931] Issue #2796 - Max local stream count exceeded when
request fails.
Bound release of the channel to stream close event.
Signed-off-by: Simone Bordet
---
.../org/eclipse/jetty/http2/HTTP2Session.java | 2 +-
.../org/eclipse/jetty/http2/HTTP2Stream.java | 22 ++++++
.../org/eclipse/jetty/http2/api/Stream.java | 9 +++
.../client/http/HttpChannelOverHTTP2.java | 5 ++
.../client/http/HttpConnectionOverHTTP2.java | 17 ++++-
.../client/http/HttpReceiverOverHTTP2.java | 6 ++
.../jetty/http/client/HttpClientLoadTest.java | 67 ++++++++++++++-----
7 files changed, 107 insertions(+), 21 deletions(-)
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
index 83a82d17eb7..0b3fff14705 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
@@ -763,7 +763,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
int localCount = localStreamCount.get();
int maxCount = getMaxLocalStreams();
if (maxCount >= 0 && localCount >= maxCount)
- throw new IllegalStateException("Max local stream count " + maxCount + " exceeded");
+ throw new IllegalStateException("Max local stream count " + maxCount + " exceeded" + System.lineSeparator() + dump());
if (localStreamCount.compareAndSet(localCount, localCount + 1))
break;
}
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java
index 265f57aa8a4..4d8e0ae2d4a 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java
@@ -510,6 +510,13 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa
}
}
+ @Override
+ public void onClose()
+ {
+ super.onClose();
+ notifyClosed(this);
+ }
+
private void updateStreamCount(int deltaStream, int deltaClosing)
{
((HTTP2Session)session).updateStreamCount(isLocal(), deltaStream, deltaClosing);
@@ -615,6 +622,21 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa
}
}
+ private void notifyClosed(Stream stream)
+ {
+ Listener listener = this.listener;
+ if (listener == null)
+ return;
+ try
+ {
+ listener.onClosed(stream);
+ }
+ catch (Throwable x)
+ {
+ LOG.info("Failure while notifying listener " + listener, x);
+ }
+ }
+
@Override
public String dump()
{
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java
index 9e879cab891..6ddbf7b0350 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java
@@ -234,6 +234,15 @@ public interface Stream
callback.succeeded();
}
+ /**
+ *
Callback method invoked after the stream has been closed.
*/
diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java
index f9cfa6c2949..4a399926c4c 100644
--- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java
+++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java
@@ -101,6 +101,11 @@ public class HttpChannelOverHTTP2 extends HttpChannel
connection.release(this);
}
+ void onStreamClosed(Stream stream)
+ {
+ connection.onStreamClosed(stream, this);
+ }
+
@Override
public void exchangeTerminated(HttpExchange exchange, Result result)
{
diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java
index 4d4a3cfebe8..e805fe5f938 100644
--- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java
+++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java
@@ -36,11 +36,16 @@ import org.eclipse.jetty.client.SendFailure;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http2.ErrorCode;
import org.eclipse.jetty.http2.api.Session;
+import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.util.Callback;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Sweeper;
public class HttpConnectionOverHTTP2 extends HttpConnection implements Sweeper.Sweepable
{
+ private static final Logger LOG = Log.getLogger(HttpConnection.class);
+
private final Set activeChannels = ConcurrentHashMap.newKeySet();
private final Queue idleChannels = new ConcurrentLinkedQueue<>();
private final AtomicBoolean closed = new AtomicBoolean();
@@ -87,16 +92,16 @@ public class HttpConnectionOverHTTP2 extends HttpConnection implements Sweeper.S
protected void release(HttpChannelOverHTTP2 channel)
{
+ if (LOG.isDebugEnabled())
+ LOG.debug("Released {}", channel);
// Only non-push channels are released.
if (activeChannels.remove(channel))
{
- channel.setStream(null);
// Recycle only non-failed channels.
if (channel.isFailed())
channel.destroy();
else
idleChannels.offer(channel);
- getHttpDestination().release(this);
}
else
{
@@ -104,6 +109,14 @@ public class HttpConnectionOverHTTP2 extends HttpConnection implements Sweeper.S
}
}
+ void onStreamClosed(Stream stream, HttpChannelOverHTTP2 channel)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("{} closed for {}", stream, channel);
+ channel.setStream(null);
+ getHttpDestination().release(this);
+ }
+
@Override
public boolean onIdleTimeout(long idleTimeout)
{
diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java
index 94fa9776fa2..dc4007ea366 100644
--- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java
+++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java
@@ -184,6 +184,12 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements Stream.Listen
callback.succeeded();
}
+ @Override
+ public void onClosed(Stream stream)
+ {
+ getHttpChannel().onStreamClosed(stream);
+ }
+
private void notifyContent(HttpExchange exchange, DataFrame frame, Callback callback)
{
contentNotifier.offer(new DataInfo(exchange, frame, callback));
diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java
index 0d2d9fa0013..65b72262eac 100644
--- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java
+++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java
@@ -18,10 +18,6 @@
package org.eclipse.jetty.http.client;
-import static org.eclipse.jetty.http.client.Transport.UNIX_SOCKET;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@@ -30,11 +26,11 @@ import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.IntStream;
-import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -68,6 +64,9 @@ import org.hamcrest.Matchers;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
public class HttpClientLoadTest extends AbstractTest
{
private final Logger logger = Log.getLogger(HttpClientLoadTest.class);
@@ -186,7 +185,7 @@ public class HttpClientLoadTest extends AbstractTest failures)
+ private void test(String scheme, String host, String method, boolean clientClose, boolean serverClose, long clientTimeout, int contentLength, final boolean checkContentLength, final CountDownLatch latch, final List failures)
{
long requestId = requestCount.incrementAndGet();
Request request = scenario.client.newRequest(host, scenario.getNetworkConnectorLocalPortInt().orElse(0))
@@ -215,6 +218,12 @@ public class HttpClientLoadTest extends AbstractTest 0)
+ {
+ request.header("X-Timeout", String.valueOf(clientTimeout));
+ request.idleTimeout(clientTimeout, TimeUnit.MILLISECONDS);
+ }
+
switch (method)
{
case "GET":
@@ -254,12 +263,18 @@ public class HttpClientLoadTest extends AbstractTest 0 && failure instanceof TimeoutException))
+ {
+ failure.printStackTrace();
+ failures.add("Result failed " + result);
+ }
+ }
+ else
+ {
+ if (checkContentLength && contentLength.get() != 0)
+ failures.add("Content length mismatch " + contentLength);
}
-
- if (checkContentLength && contentLength.get() != 0)
- failures.add("Content length mismatch " + contentLength);
requestLatch.countDown();
latch.countDown();
@@ -288,8 +303,14 @@ public class HttpClientLoadTest extends AbstractTest
Date: Thu, 11 Oct 2018 14:08:24 -0400
Subject: [PATCH 086/931] Updating/augmenting JPMS documentation included in PR
#2934
---
.../startup/custom-modules.adoc | 2 +
.../administration/startup/startup-jpms.adoc | 96 +++++++------------
2 files changed, 34 insertions(+), 64 deletions(-)
diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/custom-modules.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/custom-modules.adoc
index e070669d1be..dff59d79315 100644
--- a/jetty-documentation/src/main/asciidoc/administration/startup/custom-modules.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/startup/custom-modules.adoc
@@ -79,6 +79,8 @@ If a user does not accept the license agreement, the module will not be activate
Additional Startup Commands - `[exec]`::
The `[exec]` section is used to define additional parameters specific to the module.
These commands are added to the server startup.
+JPMS Module-Path Definitions - `[jpms]`::
+The `[jpms]` section is used to add link:#startup-jpms[JPMS modules] to the module-path for startup when using the `--jpms` command.
[[custom-module-properties]]
==== Module Properties
diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/startup-jpms.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/startup-jpms.adoc
index b6fdb7b9671..075b75d9c96 100644
--- a/jetty-documentation/src/main/asciidoc/administration/startup/startup-jpms.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/startup/startup-jpms.adoc
@@ -16,29 +16,24 @@
// ========================================================================
//
-[[startup-overview]]
+[[startup-jpms]]
=== Startup using the Java Platform Module System (JPMS)
-Jetty modules are also automatic https://en.wikipedia.org/wiki/Java_Platform_Module_System[JPMS]
-modules via the `Automatic-Module-Name` attribute in the jar's `MANIFEST.MF` file.
+Jetty modules also act ass automatic https://en.wikipedia.org/wiki/Java_Platform_Module_System[JPMS] modules via the `Automatic-Module-Name` attribute in the jar's `MANIFEST.MF` file.
This makes possible to run Jetty from the module-path, rather than the class-path.
-We recommend to use JDK 11 or greater due to the fact that JDK 11 removed all the
-"enterprise" modules from the JDK.
-The classes in these "enterprise" modules were bundled with JDK 8, and present in
-"enterprise" modules in JDK 9 and JDK 10.
-With JDK 11, these "enterprise" classes are either not available in the JDK (because
-their corresponding module was removed), or they are present in a different module.
+We recommend using JDK 11 or greater due to the fact that JDK 11 removed all the "enterprise" modules from the JDK.
+The classes in these "enterprise" modules were bundled with JDK 8, and present in "enterprise" modules in JDK 9 and JDK 10.
+With JDK 11, these "enterprise" classes are either not available in the JDK (because their corresponding module was removed), or they are present in a different module.
-Some of these "enterprise" classes are required by Jetty or by applications running
-in Jetty, so it is better to use a stable source for those classes by using JDK 11
+Because some of these "enterprise" classes are required by Jetty or by applications running in Jetty, it is better to use a stable source for those classes - in this case by using JDK 11
or greater.
+[[jpms-module-path]]
==== Starting Jetty on the module-path
-To start Jetty on the module-path, rather than the class-path, it is enough to add
-the `--jpms` option to the command line, for example:
+To start Jetty on the module-path rather than the class-path, it is enough to add the `--jpms` option to the command line, for example:
[source, screen, subs="{sub-order}"]
....
@@ -52,28 +47,24 @@ INFO : Base directory was modified
$ java -jar $JETTY_HOME/start.jar --jpms
....
-The example above creates a link:#startup-base-and-home[Jetty base directory] and
-enables the `http` module using `--add-to-start`.
-Then starts Jetty on the module-path using the `--jpms` option.
+The example above creates a link:#startup-base-and-home[Jetty base directory] and enables the `http` module using the `--add-to-start` command.
+The server then starts Jetty on the module-path using the `--jpms` option.
----
[NOTE]
-When running on the module-path using the `--jpms` option, the Jetty start mechanism
-will fork a second JVM passing it the right JVM options to run on the module-path.
+When running on the module-path using the `--jpms` option, the Jetty start mechanism will fork a second JVM passing it the right JVM options to run on the module-path.
-You will have two JVMs running: one that runs `start.jar` and one that runs Jetty on
-the module-path.
+You will have two JVMs running: one that runs `start.jar` and one that runs Jetty on the module-path.
----
-If you are interested in the details of how the command line to run Jetty on the
-module-path looks like, you can add the `--dry-run` option:
+If you are interested in the details of how the command line to run Jetty on the module-path looks like, you can add the `--dry-run` option:
[source, screen, subs="{sub-order}"]
....
$ java -jar $JETTY_HOME/start.jar --jpms --dry-run
....
-You will see something like this (broken in sections for clarity):
+This will give an out put looking something like this (broken in sections for clarity):
[source, screen, subs="{sub-order}"]
....
@@ -83,37 +74,25 @@ You will see something like this (broken in sections for clarity):
--module org.eclipse.jetty.xml/org.eclipse.jetty.xml.XmlConfiguration /opt/jetty/etc/jetty-threadpool.xml /opt/jetty/etc/jetty.xml ...
....
-The `--module-path` option specifies the list of Jetty jars. This list depends
-on the Jetty modules that have been enabled via `--add-to-start`.
+The `--module-path` option specifies the list of Jetty jars.
+This list depends on the Jetty modules that have been enabled via the link:#startup-modules[`--add-to-start`] command.
-The `--patch-module` option is necessary for Servlet and JSP Containers to find XML DTDs
-and XML Schemas required to validate the various XML files present in web applications
-(such as `web.xml` and others).
+The `--patch-module` option is necessary for Servlet and JSP Containers to find XML DTDs and XML Schemas required to validate the various XML files present in web applications (such as `web.xml` and others).
-The `--module` option tells the JVM to run main class `XmlConfiguration` from the
-`org.eclipse.jetty.xml` module, with the given XML files as program arguments.
+The `--module` option tells the JVM to run main class `XmlConfiguration` from the `org.eclipse.jetty.xml` module, with the given XML files as program arguments.
-When the JVM starts, module `org.eclipse.jetty.xml` is added to the set of JPMS
-_root modules_; all other Jetty modules, being automatic, will be resolved and added
-to the module graph; jars that are not modules such as `servlet-api-3.1.jar` are on
-the module-path and therefore will be made automatic modules by the JVM (hence the
-derived module name `servlet.api` for this jar, referenced by the `--patch-module`
-command line option above).
+When the JVM starts, module `org.eclipse.jetty.xml` is added to the set of JPMS _root modules_; all other Jetty modules, being automatic, will be resolved and added to the module graph.
+JAR files that are not modules, such as `servlet-api-3.1.jar`, are on the module-path and therefore will be made automatic modules by the JVM (hence the derived module name `servlet.api` for this jar, referenced by the `--patch-module` command line option above).
+[[jpms-advanced-config]]
==== Advanced JPMS Configuration
-Web applications may need additional services from the Servlet Container, such as
-JDBC `DataSource` references or JTA `UserTransaction` references.
+Web applications may need additional services from the Servlet Container, such as JDBC `DataSource` references or JTA `UserTransaction` references.
-For example, for JDBC it is typical to store in JNDI a reference to the connection
-pool's `DataSource` (for example `com.zaxxer.hikari.HikariDataSource`) or a
-reference directly to the JDBC driver's `DataSource` (for example
-`com.mysql.jdbc.jdbc2.optional.MysqlDataSource`).
-Jetty needs to be able to instantiate those classes and therefore needs to be able
-to load those classes and all their super-classes, among which `javax.sql.DataSource`.
+For example, for JDBC it is typical to store, in JNDI, a reference to the connection pool's `DataSource` (such as `com.zaxxer.hikari.HikariDataSource`) or a reference directly to the JDBC driver's `DataSource` (`com.mysql.jdbc.jdbc2.optional.MysqlDataSource`).
+Jetty needs to be able to instantiate those classes and therefore needs to be able to load those classes and all their super-classes, among which includes `javax.sql.DataSource`.
-When Jetty runs on the class-path, this is easily achieved by using a
-link:#custom-modules[custom module]:
+When Jetty runs on the class-path, this is easily achieved by using a link:#custom-modules[custom module]:
[source, screen, subs="{sub-order}"]
.mysql.mod
@@ -127,13 +106,10 @@ lib/mysql/mysql-connector-java-*.jar
However, when running on the module-path, things are quite different.
-Class `javax.sql.DataSource` is in a JDK bundled module named `java.sql`, which is
-not automatic (it's a proper JPMS module) and it is not in the _root modules_ set;
-because it is not an automatic module, it is not added to the module graph, and
-therefore needs to be added explicitly using the JVM command line `--add-modules`.
+Class `javax.sql.DataSource` is in a JDK bundled module named `java.sql`, which is not automatic (it's a proper JPMS module) and it is not in the _root modules_ set.
+Because it is not an automatic module, it is not added to the module graph, and therefore needs to be added explicitly using the JVM command line `--add-modules`.
-To add the JPMS module `java.sql` to the module graph, you need to modify
-`mysql.mod` in the following way:
+To add the JPMS module `java.sql` to the module graph, you need to modify your custom module in the following way, using our `mysql.mod` as an example:
[source, screen, subs="{sub-order}"]
.mysql.mod
@@ -148,17 +124,11 @@ lib/mysql/mysql-connector-java-*.jar
add-modules: java.sql
....
-The new `[jpms]` section is only used when Jetty is started on the module-path
-via the `--jpms` command line option.
+The new `[jpms]` section is only used when Jetty is started on the module-path via the `--jpms` command line option.
-Assuming that `mysql-connector-java-*.jar` is a non JPMS modular jar, or an
-automatic JPMS modular jar, the Jetty start mechanism will add
-`mysql-connector-java-*.jar` to the module-path, and will add the JVM command
-line option `--add-modules java.sql`.
+Assuming that `mysql-connector-java-*.jar` is a non JPMS modular jar, or an automatic JPMS modular jar, the Jetty start mechanism will add `mysql-connector-java-*.jar` to the module-path, and will add the JVM command line option `--add-modules java.sql`.
-If `mysql-connector-java-*.jar` were a proper JPMS modular jar with name
-(for example) `com.mysql.jdbc`, then it would need to be explicitly added to
-the module graph, in this way:
+If `mysql-connector-java-*.jar` were a proper JPMS modular jar with name (for example) `com.mysql.jdbc`, then it would need to be explicitly added to the module graph, in this way:
[source, screen, subs="{sub-order}"]
.mysql.mod
@@ -173,9 +143,7 @@ lib/mysql/mysql-connector-java-*.jar
add-modules: com.mysql.jdbc
....
-Now we don't need to add JPMS module `java.sql` explicitly because it would be
-a dependency of the `com.mysql.jdbc` module and therefore automatically added
-to the module graph.
+The JPMS module `java.sql` does not need to be explicitly added because it would be a dependency of the `com.mysql.jdbc` module and therefore automatically added to the module graph.
The `[jpms]` section has the following format:
From 64e561dcb13692024ba3b2bee56427b412cc4b9b Mon Sep 17 00:00:00 2001
From: Olivier Lamy
Date: Sun, 14 Oct 2018 10:50:02 +1000
Subject: [PATCH 087/931] upgrade surefire plugin 2.22.1 (#2980)
Signed-off-by: olivier lamy
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 18f65cb915c..62be04d2d80 100644
--- a/pom.xml
+++ b/pom.xml
@@ -42,7 +42,7 @@
${bundle-symbolic-name}
- 2.22.0
+ 2.22.13.8.03.1.13.1.0
From 5c8d3f041bee47ed133b68389446e74e46854607 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Tue, 16 Oct 2018 14:28:51 +1100
Subject: [PATCH 088/931] Cleanup to avoid duplication method (noticed while
reviewing #2977)
---
.../jetty/http2/hpack/MetaDataBuilder.java | 53 ++++++++-----------
1 file changed, 22 insertions(+), 31 deletions(-)
diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java
index d891ab3dfe5..636d464686e 100644
--- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java
+++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java
@@ -33,7 +33,7 @@ public class MetaDataBuilder
{
private final int _maxSize;
private int _size;
- private int _status=-1;
+ private Integer _status;
private String _method;
private HttpScheme _scheme;
private HostPortHttpField _authority;
@@ -47,7 +47,7 @@ public class MetaDataBuilder
/**
* @param maxHeadersSize The maximum size of the headers, expressed as total name and value characters.
*/
- MetaDataBuilder(int maxHeadersSize)
+ protected MetaDataBuilder(int maxHeadersSize)
{
_maxSize=maxHeadersSize;
}
@@ -84,7 +84,7 @@ public class MetaDataBuilder
switch(header)
{
case C_STATUS:
- if(checkHeader(header, _status))
+ if(checkPseudoHeader(header, _status))
_status = (Integer)staticField.getStaticValue();
_response = true;
break;
@@ -110,8 +110,8 @@ public class MetaDataBuilder
switch(header)
{
case C_STATUS:
- if(checkHeader(header, _status))
- _status = field.getIntValue();
+ if(checkPseudoHeader(header, _status))
+ _status = Integer.valueOf(field.getIntValue());
_response = true;
break;
@@ -197,7 +197,7 @@ public class MetaDataBuilder
}
}
- void streamException(String messageFormat, Object... args)
+ protected void streamException(String messageFormat, Object... args)
{
HpackException.StreamException stream = new HpackException.StreamException(messageFormat, args);
if (_streamException==null)
@@ -206,20 +206,7 @@ public class MetaDataBuilder
_streamException.addSuppressed(stream);
}
- private boolean checkHeader(HttpHeader header, int value)
- {
- if (_fields.size()>0)
- {
- streamException("Pseudo header %s after fields", header.asString());
- return false;
- }
- if (value==-1)
- return true;
- streamException("Duplicate pseudo header %s", header.asString());
- return false;
- }
-
- private boolean checkPseudoHeader(HttpHeader header, Object value)
+ protected boolean checkPseudoHeader(HttpHeader header, Object value)
{
if (_fields.size()>0)
{
@@ -258,22 +245,26 @@ public class MetaDataBuilder
return new MetaData.Request(_method,_scheme,_authority,_path,HttpVersion.HTTP_2,fields,_contentLength);
}
if (_response)
- return new MetaData.Response(HttpVersion.HTTP_2,_status,fields,_contentLength);
+ {
+ if (_status==null)
+ throw new HpackException.StreamException("No Status");
+ return new MetaData.Response(HttpVersion.HTTP_2, _status, fields, _contentLength);
+ }
return new MetaData(HttpVersion.HTTP_2,fields,_contentLength);
}
finally
{
- _fields = new HttpFields(Math.max(10,fields.size()+5));
- _request=false;
- _response=false;
- _status=-1;
- _method=null;
- _scheme=null;
- _authority=null;
- _path=null;
- _size=0;
- _contentLength=Long.MIN_VALUE;
+ _fields = new HttpFields(Math.max(10, fields.size() + 5));
+ _request = false;
+ _response = false;
+ _status = null;
+ _method = null;
+ _scheme = null;
+ _authority = null;
+ _path = null;
+ _size = 0;
+ _contentLength = Long.MIN_VALUE;
}
}
From 211f3d928b95e4c7748cd7eaf5a962399eab715d Mon Sep 17 00:00:00 2001
From: Olivier Lamy
Date: Wed, 17 Oct 2018 11:45:42 +1000
Subject: [PATCH 089/931] upgrade jackson-databind in maven it to 2.9.7 (#2993)
Signed-off-by: olivier lamy
---
jetty-maven-plugin/src/it/it-parent-pom/pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/jetty-maven-plugin/src/it/it-parent-pom/pom.xml b/jetty-maven-plugin/src/it/it-parent-pom/pom.xml
index a58f3a3bc4c..2ad7f139b01 100644
--- a/jetty-maven-plugin/src/it/it-parent-pom/pom.xml
+++ b/jetty-maven-plugin/src/it/it-parent-pom/pom.xml
@@ -39,7 +39,7 @@
com.fasterxml.jackson.corejackson-databind
- 2.8.1
+ 2.9.7org.slf4j
From add74bf8898efc2bba7c05ebd9f443ff9d60e79c Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Wed, 17 Oct 2018 11:56:39 +0200
Subject: [PATCH 090/931] Updated ALPN version for JDK 8u191 and 8u192.
Signed-off-by: Simone Bordet
---
.../modules/protonego-impl/alpn-1.8.0_191.mod | 8 +++++++
.../modules/protonego-impl/alpn-1.8.0_192.mod | 8 +++++++
.../modules/protonego-impl/alpn-1.8.0_191.mod | 8 +++++++
.../modules/protonego-impl/alpn-1.8.0_192.mod | 8 +++++++
pom.xml | 24 +++++++++++++++++++
5 files changed, 56 insertions(+)
create mode 100644 jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn-1.8.0_191.mod
create mode 100644 jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn-1.8.0_192.mod
create mode 100644 jetty-start/src/test/resources/dist-home/modules/protonego-impl/alpn-1.8.0_191.mod
create mode 100644 jetty-start/src/test/resources/dist-home/modules/protonego-impl/alpn-1.8.0_192.mod
diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn-1.8.0_191.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn-1.8.0_191.mod
new file mode 100644
index 00000000000..d49c0780441
--- /dev/null
+++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn-1.8.0_191.mod
@@ -0,0 +1,8 @@
+[name]
+protonego-boot
+
+[files]
+http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.13.v20181017/alpn-boot-8.1.13.v20181017.jar|lib/alpn/alpn-boot-8.1.13.v20181017.jar
+
+[exec]
+-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn-1.8.0_192.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn-1.8.0_192.mod
new file mode 100644
index 00000000000..d49c0780441
--- /dev/null
+++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn-1.8.0_192.mod
@@ -0,0 +1,8 @@
+[name]
+protonego-boot
+
+[files]
+http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.13.v20181017/alpn-boot-8.1.13.v20181017.jar|lib/alpn/alpn-boot-8.1.13.v20181017.jar
+
+[exec]
+-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
diff --git a/jetty-start/src/test/resources/dist-home/modules/protonego-impl/alpn-1.8.0_191.mod b/jetty-start/src/test/resources/dist-home/modules/protonego-impl/alpn-1.8.0_191.mod
new file mode 100644
index 00000000000..d49c0780441
--- /dev/null
+++ b/jetty-start/src/test/resources/dist-home/modules/protonego-impl/alpn-1.8.0_191.mod
@@ -0,0 +1,8 @@
+[name]
+protonego-boot
+
+[files]
+http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.13.v20181017/alpn-boot-8.1.13.v20181017.jar|lib/alpn/alpn-boot-8.1.13.v20181017.jar
+
+[exec]
+-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
diff --git a/jetty-start/src/test/resources/dist-home/modules/protonego-impl/alpn-1.8.0_192.mod b/jetty-start/src/test/resources/dist-home/modules/protonego-impl/alpn-1.8.0_192.mod
new file mode 100644
index 00000000000..d49c0780441
--- /dev/null
+++ b/jetty-start/src/test/resources/dist-home/modules/protonego-impl/alpn-1.8.0_192.mod
@@ -0,0 +1,8 @@
+[name]
+protonego-boot
+
+[files]
+http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.13.v20181017/alpn-boot-8.1.13.v20181017.jar|lib/alpn/alpn-boot-8.1.13.v20181017.jar
+
+[exec]
+-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
diff --git a/pom.xml b/pom.xml
index c98ee1d6811..89c6c980d6e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1516,6 +1516,30 @@
8.1.12.v20180117
+
+ 8u191
+
+
+ java.version
+ 1.8.0_191
+
+
+
+ 8.1.13.v20181017
+
+
+
+ 8u192
+
+
+ java.version
+ 1.8.0_192
+
+
+
+ 8.1.13.v20181017
+
+
From 3490add2a96e683c96693fa3c91c3c31c3ca66d1 Mon Sep 17 00:00:00 2001
From: olivier lamy
Date: Thu, 18 Oct 2018 16:58:25 +1000
Subject: [PATCH 091/931] remove not anymore used javadoc tages
Signed-off-by: olivier lamy
---
pom.xml | 57 ---------------------------------------------------------
1 file changed, 57 deletions(-)
diff --git a/pom.xml b/pom.xml
index 79c2a6ac8ef..6cd93d66531 100644
--- a/pom.xml
+++ b/pom.xml
@@ -514,63 +514,6 @@
http://docs.oracle.com/javase/8/docs/api/
http://docs.oracle.com/javaee/7/api/
-
-
- org.apache.xbean.XBean
- X
-
-
-
- phase
- t
- Phase:
-
-
- goal
- t
- Goal:
-
-
- description
- a
- Description:
-
-
- parameter
- f
- Parameter:
-
-
- required
- f
- Required:
-
-
- readonly
- f
- Read-Only:
-
-
- execute
- X
-
-
-
- requiresDependencyResolution
- X
-
-
-
- requiresProject
- X
-
-
-
- threadSafe
- X
-
-
-
From 907e7afc76b2652e581c5ad2279beb18db4e3248 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Thu, 18 Oct 2018 16:55:33 +0200
Subject: [PATCH 092/931] Issue #2796 - Max local stream count exceeded when
request fails.
Updates after review.
Signed-off-by: Simone Bordet
---
.../main/java/org/eclipse/jetty/http2/HTTP2Session.java | 1 +
.../jetty/http2/client/http/HttpChannelOverHTTP2.java | 3 ++-
.../jetty/http2/client/http/HttpConnectionOverHTTP2.java | 9 +++++----
.../jetty/http2/client/http/HttpReceiverOverHTTP2.java | 3 ++-
4 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
index 0b3fff14705..cbd379b3cc6 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
@@ -763,6 +763,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
int localCount = localStreamCount.get();
int maxCount = getMaxLocalStreams();
if (maxCount >= 0 && localCount >= maxCount)
+ // TODO: remove the dump() in the exception message.
throw new IllegalStateException("Max local stream count " + maxCount + " exceeded" + System.lineSeparator() + dump());
if (localStreamCount.compareAndSet(localCount, localCount + 1))
break;
diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java
index 4a399926c4c..27c6022b642 100644
--- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java
+++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java
@@ -25,6 +25,7 @@ import org.eclipse.jetty.client.HttpReceiver;
import org.eclipse.jetty.client.HttpSender;
import org.eclipse.jetty.client.api.Result;
import org.eclipse.jetty.http2.ErrorCode;
+import org.eclipse.jetty.http2.IStream;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.frames.ResetFrame;
@@ -101,7 +102,7 @@ public class HttpChannelOverHTTP2 extends HttpChannel
connection.release(this);
}
- void onStreamClosed(Stream stream)
+ void onStreamClosed(IStream stream)
{
connection.onStreamClosed(stream, this);
}
diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java
index e805fe5f938..7863d3381ca 100644
--- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java
+++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java
@@ -35,8 +35,8 @@ import org.eclipse.jetty.client.HttpRequest;
import org.eclipse.jetty.client.SendFailure;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http2.ErrorCode;
+import org.eclipse.jetty.http2.IStream;
import org.eclipse.jetty.http2.api.Session;
-import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -94,7 +94,6 @@ public class HttpConnectionOverHTTP2 extends HttpConnection implements Sweeper.S
{
if (LOG.isDebugEnabled())
LOG.debug("Released {}", channel);
- // Only non-push channels are released.
if (activeChannels.remove(channel))
{
// Recycle only non-failed channels.
@@ -109,12 +108,14 @@ public class HttpConnectionOverHTTP2 extends HttpConnection implements Sweeper.S
}
}
- void onStreamClosed(Stream stream, HttpChannelOverHTTP2 channel)
+ void onStreamClosed(IStream stream, HttpChannelOverHTTP2 channel)
{
if (LOG.isDebugEnabled())
LOG.debug("{} closed for {}", stream, channel);
channel.setStream(null);
- getHttpDestination().release(this);
+ // Only non-push channels are released.
+ if (stream.isLocal())
+ getHttpDestination().release(this);
}
@Override
diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java
index dc4007ea366..5f1a6751239 100644
--- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java
+++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java
@@ -38,6 +38,7 @@ import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.ErrorCode;
+import org.eclipse.jetty.http2.IStream;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
@@ -187,7 +188,7 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements Stream.Listen
@Override
public void onClosed(Stream stream)
{
- getHttpChannel().onStreamClosed(stream);
+ getHttpChannel().onStreamClosed((IStream)stream);
}
private void notifyContent(HttpExchange exchange, DataFrame frame, Callback callback)
From 37a85152eb1a6a1aabbee226a660b07c700576aa Mon Sep 17 00:00:00 2001
From: Magnus Reftel
Date: Sat, 13 Oct 2018 08:39:15 +0200
Subject: [PATCH 093/931] Improve error message when binding to in-use port
Signed-off-by: Magnus Reftel
---
.../eclipse/jetty/server/ServerConnector.java | 7 +++-
.../jetty/server/ServerConnectorTest.java | 34 +++++++++++++++----
2 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java
index 3210ed8deb9..f8e9ee1d69c 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java
@@ -20,6 +20,7 @@ package org.eclipse.jetty.server;
import java.io.Closeable;
import java.io.IOException;
+import java.net.BindException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
@@ -336,7 +337,11 @@ public class ServerConnector extends AbstractNetworkConnector
InetSocketAddress bindAddress = getHost() == null ? new InetSocketAddress(getPort()) : new InetSocketAddress(getHost(), getPort());
serverChannel.socket().setReuseAddress(getReuseAddress());
- serverChannel.socket().bind(bindAddress, getAcceptQueueSize());
+ try {
+ serverChannel.socket().bind(bindAddress, getAcceptQueueSize());
+ } catch (BindException e) {
+ throw new IOException("Failed to bind to " + bindAddress, e);
+ }
}
return serverChannel;
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java
index 3ae014fb538..19cd1de2ef8 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java
@@ -33,8 +33,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.reflect.Field;
+import java.net.BindException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
+import java.net.ServerSocket;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
@@ -55,6 +57,7 @@ import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.log.StacklessLogging;
import org.hamcrest.Matchers;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class ServerConnectorTest
@@ -296,11 +299,30 @@ public class ServerConnectorTest
server.stop();
assertThat(connector.getTransport(),Matchers.nullValue());
-
-
-
-
-
-
+ }
+
+ @Test
+ public void testBindToAddressWhichIsInUse() throws Exception {
+ try (ServerSocket socket = new ServerSocket(0)) {
+ final int port = socket.getLocalPort();
+
+ Server server = new Server();
+ ServerConnector connector = new ServerConnector(server);
+ connector.setPort(port);
+ server.addConnector(connector);
+
+ HandlerList handlers = new HandlerList();
+ handlers.addHandler(new DefaultHandler());
+
+ server.setHandler(handlers);
+
+ try {
+ server.start();
+ Assertions.fail("No exception thrown");
+ } catch (IOException e) {
+ assertThat(e.getCause(), Matchers.instanceOf(BindException.class));
+ assertThat(e.getMessage(), Matchers.containsString("0.0.0.0:" + port));
+ }
+ }
}
}
From a10c84c40a8d89e69a2576d148d6cb93014ece99 Mon Sep 17 00:00:00 2001
From: Joakim Erdfelt
Date: Fri, 19 Oct 2018 10:20:10 -0500
Subject: [PATCH 094/931] Issue #3001 - making test more resilient to
environments without UTF-8 filesystem support
---
.../util/resource/FileSystemResourceTest.java | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java
index e764594f39b..abff1f5fe1b 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java
@@ -1457,9 +1457,22 @@ public class FileSystemResourceTest
public void testUtf8Dir(Class resourceClass) throws Exception
{
Path dir = workDir.getEmptyPathDir();
- Path utf8Dir = dir.resolve("bãm");
- Files.createDirectories(utf8Dir);
-
+ Path utf8Dir;
+
+ try
+ {
+ utf8Dir = dir.resolve("bãm");
+ Files.createDirectories(utf8Dir);
+ }
+ catch (InvalidPathException e)
+ {
+ // if unable to create file, no point testing the rest.
+ // this is the path that occurs if you have a system that doesn't support UTF-8
+ // directory names (or you simply don't have a Locale set properly)
+ assumeTrue(true, "Not supported on this OS");
+ return;
+ }
+
Path file = utf8Dir.resolve("file.txt");
Files.createFile(file);
From 35ea653f73dfb2ed260451d237dcd92264a35b17 Mon Sep 17 00:00:00 2001
From: Joakim Erdfelt
Date: Fri, 19 Oct 2018 10:36:26 -0500
Subject: [PATCH 095/931] Fixing PR #3003 - formatting and junit5 syntax
Signed-off-by: Joakim Erdfelt
---
.../eclipse/jetty/server/ServerConnector.java | 7 +++++--
.../jetty/server/ServerConnectorTest.java | 20 ++++++++-----------
2 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java
index f8e9ee1d69c..d18b3a08e1a 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java
@@ -337,9 +337,12 @@ public class ServerConnector extends AbstractNetworkConnector
InetSocketAddress bindAddress = getHost() == null ? new InetSocketAddress(getPort()) : new InetSocketAddress(getHost(), getPort());
serverChannel.socket().setReuseAddress(getReuseAddress());
- try {
+ try
+ {
serverChannel.socket().bind(bindAddress, getAcceptQueueSize());
- } catch (BindException e) {
+ }
+ catch (BindException e)
+ {
throw new IOException("Failed to bind to " + bindAddress, e);
}
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java
index 19cd1de2ef8..46621475643 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java
@@ -18,6 +18,7 @@
package org.eclipse.jetty.server;
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThan;
@@ -26,14 +27,13 @@ import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
-import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.reflect.Field;
-import java.net.BindException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
@@ -57,7 +57,6 @@ import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.log.StacklessLogging;
import org.hamcrest.Matchers;
-import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class ServerConnectorTest
@@ -302,8 +301,10 @@ public class ServerConnectorTest
}
@Test
- public void testBindToAddressWhichIsInUse() throws Exception {
- try (ServerSocket socket = new ServerSocket(0)) {
+ public void testBindToAddressWhichIsInUse() throws Exception
+ {
+ try (ServerSocket socket = new ServerSocket(0))
+ {
final int port = socket.getLocalPort();
Server server = new Server();
@@ -316,13 +317,8 @@ public class ServerConnectorTest
server.setHandler(handlers);
- try {
- server.start();
- Assertions.fail("No exception thrown");
- } catch (IOException e) {
- assertThat(e.getCause(), Matchers.instanceOf(BindException.class));
- assertThat(e.getMessage(), Matchers.containsString("0.0.0.0:" + port));
- }
+ IOException x = assertThrows(IOException.class, () -> server.start());
+ assertThat(x.getMessage(), containsString("0.0.0.0:" + port));
}
}
}
From 9e84c1ee930c953265df643c3fd6b22eb8bf50b8 Mon Sep 17 00:00:00 2001
From: Joakim Erdfelt
Date: Fri, 19 Oct 2018 10:38:09 -0500
Subject: [PATCH 096/931] Testing for BindException cause as well
Signed-off-by: Joakim Erdfelt
---
.../test/java/org/eclipse/jetty/server/ServerConnectorTest.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java
index 46621475643..6642057d8ab 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java
@@ -34,6 +34,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.reflect.Field;
+import java.net.BindException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
@@ -318,6 +319,7 @@ public class ServerConnectorTest
server.setHandler(handlers);
IOException x = assertThrows(IOException.class, () -> server.start());
+ assertThat(x.getCause(), instanceOf(BindException.class));
assertThat(x.getMessage(), containsString("0.0.0.0:" + port));
}
}
From efdf3c2473eb191d19169bd30742e22ece6365c0 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Sat, 20 Oct 2018 10:15:05 +1100
Subject: [PATCH 097/931] Issue #2970 ensure onComplete is called (#2971)
* Issue #2970 ensure onComplete is called
* Cleanup after review - single try
Signed-off-by: Greg Wilkins
---
.../org/eclipse/jetty/server/HttpChannel.java | 45 ++++++++++---------
1 file changed, 25 insertions(+), 20 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java
index 8b490299d21..43ab02dc183 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java
@@ -481,33 +481,38 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
case COMPLETE:
{
- if (!_response.isCommitted() && !_request.isHandled())
+ try
{
- _response.sendError(HttpStatus.NOT_FOUND_404);
- }
- else
- {
- // RFC 7230, section 3.3.
- int status = _response.getStatus();
- boolean hasContent = !(_request.isHead() ||
+ if (!_response.isCommitted() && !_request.isHandled())
+ {
+ _response.sendError(HttpStatus.NOT_FOUND_404);
+ }
+ else
+ {
+ // RFC 7230, section 3.3.
+ int status = _response.getStatus();
+ boolean hasContent = !(_request.isHead() ||
HttpMethod.CONNECT.is(_request.getMethod()) && status == HttpStatus.OK_200 ||
HttpStatus.isInformational(status) ||
status == HttpStatus.NO_CONTENT_204 ||
status == HttpStatus.NOT_MODIFIED_304);
- if (hasContent && !_response.isContentComplete(_response.getHttpOutput().getWritten()))
- {
- if (isCommitted())
- abort(new IOException("insufficient content written"));
- else
- _response.sendError(HttpStatus.INTERNAL_SERVER_ERROR_500,"insufficient content written");
+ if (hasContent && !_response.isContentComplete(_response.getHttpOutput().getWritten()))
+ {
+ if (isCommitted())
+ abort(new IOException("insufficient content written"));
+ else
+ _response.sendError(HttpStatus.INTERNAL_SERVER_ERROR_500, "insufficient content written");
+ }
}
+ _response.closeOutput();
+
+ }
+ finally
+ {
+ _request.setHandled(true);
+ _state.onComplete();
+ onCompleted();
}
- _response.closeOutput();
- _request.setHandled(true);
-
- _state.onComplete();
-
- onCompleted();
break loop;
}
From 15e1c73f9c89905da851344b55ff83e0b7af2584 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Mon, 22 Oct 2018 11:53:59 +1100
Subject: [PATCH 098/931] Cleanup the dump implementation (#2998)
* Cleanup the dump implementation
* improved the clarity of utility methods for dump and updated most dump methods
* fixed upgrade filter dump
* Improved dump after review
* Moved dumpObjects to Dumpable
* implemented dumpBeans with dumpObjects
* less verbose dump
* Dump streams
* fixed dump test
Signed-off-by: Greg Wilkins
Signed-off-by: Simone Bordet
---
examples/embedded/pom.xml | 7 +-
.../eclipse/jetty/embedded/LikeJettyXml.java | 2 +-
.../jetty/embedded/ManyConnectors.java | 2 +-
.../eclipse/jetty/embedded/ManyContexts.java | 1 +
.../OneServletContextWithSession.java | 1 +
.../jetty/embedded/ServerWithAnnotations.java | 5 +-
.../jetty/client/AbstractConnectionPool.java | 3 +-
.../jetty/client/DuplexConnectionPool.java | 17 +-
.../eclipse/jetty/client/HttpDestination.java | 3 +-
.../jetty/client/MultiplexConnectionPool.java | 16 +-
.../client/RoundRobinConnectionPool.java | 5 +-
.../client/ValidatingConnectionPool.java | 9 +-
.../jetty/http/pathmap/PathMappings.java | 6 +-
.../http2/AbstractFlowControlStrategy.java | 3 +-
.../org/eclipse/jetty/http2/HTTP2Flusher.java | 3 +-
.../org/eclipse/jetty/http2/HTTP2Session.java | 4 +-
.../org/eclipse/jetty/http2/HTTP2Stream.java | 3 +-
.../AbstractHTTP2ServerConnectionFactory.java | 6 +-
.../jetty/io/ConnectionStatistics.java | 17 +-
.../org/eclipse/jetty/io/ManagedSelector.java | 11 +-
.../org/eclipse/jetty/jmx/MBeanContainer.java | 5 +-
.../eclipse/jetty/proxy/ConnectHandler.java | 7 -
.../security/ConstraintSecurityHandler.java | 11 +-
.../eclipse/jetty/server/ClassLoaderDump.java | 29 +--
.../jetty/server/ConnectorStatistics.java | 11 +-
.../java/org/eclipse/jetty/server/Server.java | 3 +-
.../jetty/server/handler/ContextHandler.java | 11 +-
.../handler/ContextHandlerCollection.java | 2 +-
.../server/handler/HandlerCollection.java | 8 -
.../server/handler/InetAccessHandler.java | 5 +-
.../jetty/server/ClassLoaderDumptTest.java | 46 ++---
.../org/eclipse/jetty/servlet/BaseHolder.java | 6 +-
.../eclipse/jetty/servlet/FilterHolder.java | 32 +--
.../eclipse/jetty/servlet/FilterMapping.java | 3 +-
.../org/eclipse/jetty/servlet/Holder.java | 12 +-
.../eclipse/jetty/servlet/ServletHandler.java | 10 +-
.../eclipse/jetty/servlet/ServletHolder.java | 16 +-
.../org/eclipse/jetty/util/AttributesMap.java | 17 +-
.../util/component/ContainerLifeCycle.java | 158 ++++++--------
.../jetty/util/component/Dumpable.java | 192 +++++++++++++++++-
.../util/component/DumpableCollection.java | 16 +-
.../jetty/util/ssl/SslContextFactory.java | 19 +-
.../jetty/util/ssl/SslSelectionDump.java | 16 +-
.../jetty/util/thread/ExecutorThreadPool.java | 17 +-
.../jetty/util/thread/QueuedThreadPool.java | 13 +-
.../thread/ScheduledExecutorScheduler.java | 15 +-
.../jetty/util/URIUtilCanonicalPathTest.java | 2 +-
.../component/ContainerLifeCycleTest.java | 117 ++++++-----
.../eclipse/jetty/webapp/WebAppContext.java | 14 +-
.../websocket/client/WebSocketClient.java | 7 -
.../websocket/common/WebSocketSession.java | 25 +--
.../common/extensions/AbstractExtension.java | 3 +-
.../io/AbstractWebSocketConnection.java | 3 +-
.../server/WebSocketUpgradeFilter.java | 6 +-
.../java/org/eclipse/jetty/TestServer.java | 34 ++--
55 files changed, 584 insertions(+), 431 deletions(-)
diff --git a/examples/embedded/pom.xml b/examples/embedded/pom.xml
index 7280aaf5dac..1fcade91b31 100644
--- a/examples/embedded/pom.xml
+++ b/examples/embedded/pom.xml
@@ -128,7 +128,12 @@
org.eclipse.jetty.orbitjavax.mail.glassfish
-
+
+ javax.transaction
+ javax.transaction-api
+ compile
+
+ org.eclipse.jetty.toolchainjetty-test-helper
diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
index f592d061f30..356a9181978 100644
--- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
+++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
@@ -60,7 +60,7 @@ public class LikeJettyXml
public static void main( String[] args ) throws Exception
{
// Path to as-built jetty-distribution directory
- String jettyHomeBuild = "../../jetty-distribution/target/distribution";
+ String jettyHomeBuild = "jetty-distribution/target/distribution";
// Find jetty home and base directories
String homePath = System.getProperty("jetty.home", jettyHomeBuild);
diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java
index ef62bcbc2df..72285a31ee3 100644
--- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java
+++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java
@@ -137,7 +137,7 @@ public class ManyConnectors
// Start the server
server.start();
-
+ server.dumpStdErr();
server.join();
}
}
diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyContexts.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyContexts.java
index 87c39c0727b..1b7ad9bc8db 100644
--- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyContexts.java
+++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyContexts.java
@@ -50,6 +50,7 @@ public class ManyContexts
server.setHandler(contexts);
server.start();
+ server.dumpStdErr();
server.join();
}
}
diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneServletContextWithSession.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneServletContextWithSession.java
index d098589d0bc..023f169794b 100644
--- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneServletContextWithSession.java
+++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneServletContextWithSession.java
@@ -58,6 +58,7 @@ public class OneServletContextWithSession
context.addServlet(HelloSessionServlet.class, "/");
server.start();
+ server.dumpStdErr();
server.join();
}
}
diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ServerWithAnnotations.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ServerWithAnnotations.java
index d67880eef52..ca7ba901a84 100644
--- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ServerWithAnnotations.java
+++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ServerWithAnnotations.java
@@ -52,7 +52,7 @@ public class ServerWithAnnotations
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/");
File warFile = new File(
- "../../jetty-distribution/target/distribution/demo-base/webapps/test.war");
+ "jetty-distribution/target/distribution/demo-base/webapps/test.war");
webapp.setWar(warFile.getAbsolutePath());
webapp.setAttribute(
"org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
@@ -72,10 +72,11 @@ public class ServerWithAnnotations
// Configure a LoginService
HashLoginService loginService = new HashLoginService();
loginService.setName("Test Realm");
- loginService.setConfig("src/test/resources/realm.properties");
+ loginService.setConfig("examples/embedded/src/test/resources/realm.properties");
server.addBean(loginService);
server.start();
+ server.dumpStdErr();
server.join();
}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectionPool.java
index 29d85e8fd79..19d0d1f073c 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectionPool.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectionPool.java
@@ -28,7 +28,6 @@ import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -212,6 +211,6 @@ public abstract class AbstractConnectionPool implements ConnectionPool, Dumpable
@Override
public String dump()
{
- return ContainerLifeCycle.dump(this);
+ return Dumpable.dump(this);
}
}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexConnectionPool.java
index 5261751a62f..92bbd49311c 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexConnectionPool.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexConnectionPool.java
@@ -35,7 +35,8 @@ import org.eclipse.jetty.client.api.Destination;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
+import org.eclipse.jetty.util.component.DumpableCollection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Sweeper;
@@ -239,20 +240,24 @@ public class DuplexConnectionPool extends AbstractConnectionPool implements Swee
@Override
public void dump(Appendable out, String indent) throws IOException
{
- List connections = new ArrayList<>();
+ DumpableCollection active;
+ DumpableCollection idle;
lock();
try
{
- connections.addAll(activeConnections);
- connections.addAll(idleConnections);
+ active = new DumpableCollection("active",new ArrayList<>(activeConnections));
+ idle = new DumpableCollection("idle",new ArrayList<>(idleConnections));
}
finally
{
unlock();
}
+ dump(out, indent, active, idle);
+ }
- ContainerLifeCycle.dumpObject(out, this);
- ContainerLifeCycle.dump(out, indent, connections);
+ protected void dump(Appendable out, String indent, Object... items) throws IOException
+ {
+ Dumpable.dumpObjects(out, indent, this, items);
}
@Override
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java
index a19613ee3b9..7b7ebc432c2 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java
@@ -472,8 +472,7 @@ public abstract class HttpDestination extends ContainerLifeCycle implements Dest
@Override
public void dump(Appendable out, String indent) throws IOException
{
- super.dump(out, indent);
- ContainerLifeCycle.dump(out, indent, Collections.singleton(new DumpableCollection("exchanges", exchanges)));
+ dumpBeans(out, indent, new DumpableCollection("exchanges", exchanges));
}
public String asString()
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java
index 179d66e9ca3..8e3bdf31195 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java
@@ -31,7 +31,8 @@ import java.util.stream.Collectors;
import org.eclipse.jetty.client.api.Connection;
import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
+import org.eclipse.jetty.util.component.DumpableCollection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Sweeper;
@@ -310,21 +311,22 @@ public class MultiplexConnectionPool extends AbstractConnectionPool implements C
@Override
public void dump(Appendable out, String indent) throws IOException
{
- List connections = new ArrayList<>();
+ DumpableCollection busy;
+ DumpableCollection muxed;
+ DumpableCollection idle;
lock();
try
{
- connections.addAll(busyConnections.values());
- connections.addAll(muxedConnections.values());
- connections.addAll(idleConnections);
+ busy = new DumpableCollection("busy", new ArrayList<>(busyConnections.values()));
+ muxed = new DumpableCollection("muxed", new ArrayList<>(muxedConnections.values()));
+ idle = new DumpableCollection("idle", new ArrayList<>(idleConnections));
}
finally
{
unlock();
}
- ContainerLifeCycle.dumpObject(out, this);
- ContainerLifeCycle.dump(out, indent, connections);
+ Dumpable.dumpObjects(out, indent, this, busy, muxed, idle);
}
@Override
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/RoundRobinConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/RoundRobinConnectionPool.java
index f69cbf63eea..2986d1a3189 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/RoundRobinConnectionPool.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/RoundRobinConnectionPool.java
@@ -26,7 +26,7 @@ import org.eclipse.jetty.client.api.Connection;
import org.eclipse.jetty.client.api.Destination;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.annotation.ManagedObject;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
@ManagedObject
public class RoundRobinConnectionPool extends AbstractConnectionPool implements ConnectionPool.Multiplexable
@@ -192,8 +192,7 @@ public class RoundRobinConnectionPool extends AbstractConnectionPool implements
{
connections = new ArrayList<>(entries);
}
- ContainerLifeCycle.dumpObject(out, this);
- ContainerLifeCycle.dump(out, indent, connections);
+ Dumpable.dumpObjects(out, indent, out, connections);
}
@Override
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/ValidatingConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/ValidatingConnectionPool.java
index 5d539284ee3..bc1aa22ac56 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/ValidatingConnectionPool.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/ValidatingConnectionPool.java
@@ -23,12 +23,13 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Stream;
import org.eclipse.jetty.client.api.Connection;
import org.eclipse.jetty.client.api.Destination;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
+import org.eclipse.jetty.util.component.DumpableCollection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Scheduler;
@@ -129,10 +130,10 @@ public class ValidatingConnectionPool extends DuplexConnectionPool
}
@Override
- public void dump(Appendable out, String indent) throws IOException
+ protected void dump(Appendable out, String indent, Object... items) throws IOException
{
- super.dump(out, indent);
- ContainerLifeCycle.dump(out, indent, quarantine.values());
+ DumpableCollection toDump = new DumpableCollection("quarantine", quarantine.values());
+ super.dump(out, indent, Stream.concat(Stream.of(items), Stream.of(toDump)));
}
@Override
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java
index 6bd3d6b7217..1954da4228c 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java
@@ -31,7 +31,6 @@ import org.eclipse.jetty.util.ArrayTernaryTrie;
import org.eclipse.jetty.util.Trie;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -56,14 +55,13 @@ public class PathMappings implements Iterable>, Dumpable
@Override
public String dump()
{
- return ContainerLifeCycle.dump(this);
+ return Dumpable.dump(this);
}
@Override
public void dump(Appendable out, String indent) throws IOException
{
- out.append("PathMappings[size=").append(Integer.toString(_mappings.size())).append("]\n");
- ContainerLifeCycle.dump(out, indent, _mappings);
+ Dumpable.dumpObjects(out, indent, toString(), _mappings);
}
@ManagedAttribute(value = "mappings", readonly = true)
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/AbstractFlowControlStrategy.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/AbstractFlowControlStrategy.java
index 16a0068a8e6..fe8deaaa6a0 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/AbstractFlowControlStrategy.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/AbstractFlowControlStrategy.java
@@ -29,7 +29,6 @@ import org.eclipse.jetty.http2.frames.WindowUpdateFrame;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.annotation.ManagedOperation;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -243,7 +242,7 @@ public abstract class AbstractFlowControlStrategy implements FlowControlStrategy
@Override
public String dump()
{
- return ContainerLifeCycle.dump(this);
+ return Dumpable.dump(this);
}
@Override
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Flusher.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Flusher.java
index 61b9c69acad..219c36e8d48 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Flusher.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Flusher.java
@@ -34,7 +34,6 @@ import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.IteratingCallback;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -353,7 +352,7 @@ public class HTTP2Flusher extends IteratingCallback implements Dumpable
@Override
public String dump()
{
- return ContainerLifeCycle.dump(this);
+ return Dumpable.dump(this);
}
@Override
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
index fe2b90e6526..da4f3ad5b69 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
@@ -62,6 +62,7 @@ import org.eclipse.jetty.util.Retainable;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.component.DumpableCollection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -1205,8 +1206,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
@Override
public void dump(Appendable out, String indent) throws IOException
{
- super.dump(out, indent);
- dump(out, indent, Collections.singleton(new DumpableCollection("streams", streams.values())));
+ Dumpable.dumpObjects(out, indent, this, new DumpableCollection("streams", streams.values()));
}
@Override
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java
index 3cc9d531ce0..14002387880 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java
@@ -42,7 +42,6 @@ import org.eclipse.jetty.http2.frames.WindowUpdateFrame;
import org.eclipse.jetty.io.IdleTimeout;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Promise;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -616,7 +615,7 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa
@Override
public String dump()
{
- return ContainerLifeCycle.dump(this);
+ return Dumpable.dump(this);
}
@Override
diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java
index 46d3e46960e..da37a88d485 100644
--- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java
+++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java
@@ -43,7 +43,6 @@ import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.annotation.Name;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.component.LifeCycle;
@@ -288,14 +287,13 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
@Override
public String dump()
{
- return ContainerLifeCycle.dump(this);
+ return Dumpable.dump(this);
}
@Override
public void dump(Appendable out, String indent) throws IOException
{
- ContainerLifeCycle.dumpObject(out, this);
- ContainerLifeCycle.dump(out, indent, sessions);
+ Dumpable.dumpObjects(out,indent,this, sessions);
}
@Override
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java
index 871d57c6353..f13877f430e 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java
@@ -19,8 +19,6 @@
package org.eclipse.jetty.io;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
@@ -29,7 +27,6 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.annotation.ManagedOperation;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.statistic.CounterStatistic;
import org.eclipse.jetty.util.statistic.SampleStatistic;
@@ -210,19 +207,17 @@ public class ConnectionStatistics extends AbstractLifeCycle implements Connectio
@Override
public String dump()
{
- return ContainerLifeCycle.dump(this);
+ return Dumpable.dump(this);
}
@Override
public void dump(Appendable out, String indent) throws IOException
{
- ContainerLifeCycle.dumpObject(out, this);
- List children = new ArrayList<>();
- children.add(String.format("connections=%s", _connections));
- children.add(String.format("durations=%s", _connectionsDuration));
- children.add(String.format("bytes in/out=%s/%s", getReceivedBytes(), getSentBytes()));
- children.add(String.format("messages in/out=%s/%s", getReceivedMessages(), getSentMessages()));
- ContainerLifeCycle.dump(out, indent, children);
+ Dumpable.dumpObjects(out,indent,this,
+ String.format("connections=%s", _connections),
+ String.format("durations=%s", _connectionsDuration),
+ String.format("bytes in/out=%s/%s", getReceivedBytes(), getSentBytes()),
+ String.format("messages in/out=%s/%s", getReceivedMessages(), getSentMessages()));
}
@Override
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java
index d476885b1e0..3197f2ad1f8 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java
@@ -296,8 +296,10 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable
String keysAt = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now());
if (keys==null)
keys = Collections.singletonList("No dump keys retrieved");
- dumpBeans(out, indent, Arrays.asList(new DumpableCollection("updates @ "+updatesAt, updates),
- new DumpableCollection("keys @ "+keysAt, keys)));
+
+ dumpBeans(out, indent,
+ new DumpableCollection("updates @ "+updatesAt, updates),
+ new DumpableCollection("keys @ "+keysAt, keys));
}
else
{
@@ -543,7 +545,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable
*/
public interface SelectorUpdate
{
- public void update(Selector selector);
+ void update(Selector selector);
}
private class Start implements SelectorUpdate
@@ -567,8 +569,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable
public void update(Selector selector)
{
Set selector_keys = selector.keys();
- List list = new ArrayList<>(selector_keys.size()+1);
- list.add(selector + " keys=" + selector_keys.size());
+ List list = new ArrayList<>(selector_keys.size());
for (SelectionKey key : selector_keys)
{
if (key==null)
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
index 17ef201b4e7..c63b9446d4c 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
@@ -398,14 +398,13 @@ public class MBeanContainer implements Container.InheritedListener, Dumpable, De
@Override
public void dump(Appendable out, String indent) throws IOException
{
- ContainerLifeCycle.dumpObject(out, this);
- ContainerLifeCycle.dump(out, indent, _mbeans.entrySet());
+ Dumpable.dumpObjects(out, indent, this, _mbeans.entrySet());
}
@Override
public String dump()
{
- return ContainerLifeCycle.dump(this);
+ return Dumpable.dump(this);
}
@Override
diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java
index a6120df2191..34826102b05 100644
--- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java
+++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java
@@ -486,13 +486,6 @@ public class ConnectHandler extends HandlerWrapper
return true;
}
- @Override
- public void dump(Appendable out, String indent) throws IOException
- {
- dumpThis(out);
- dump(out, indent, getBeans(), TypeUtil.asList(getHandlers()));
- }
-
protected class ConnectManager extends SelectorManager
{
protected ConnectManager(Executor executor, Scheduler scheduler, int selectors)
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
index 8540bfb53bf..6825ecde4d1 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
@@ -46,6 +46,7 @@ import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.component.DumpableCollection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.security.Constraint;
@@ -767,11 +768,11 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
{
// TODO these should all be beans
dumpBeans(out,indent,
- Collections.singleton(getLoginService()),
- Collections.singleton(getIdentityService()),
- Collections.singleton(getAuthenticator()),
- Collections.singleton(_roles),
- _constraintMap.entrySet());
+ getLoginService(),
+ getIdentityService(),
+ getAuthenticator(),
+ DumpableCollection.from("roles",_roles),
+ DumpableCollection.from("constraints",_constraintMap.entrySet()));
}
/* ------------------------------------------------------------ */
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ClassLoaderDump.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ClassLoaderDump.java
index 3ca4321424d..44072e42b65 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ClassLoaderDump.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ClassLoaderDump.java
@@ -20,11 +20,9 @@ package org.eclipse.jetty.server;
import java.io.IOException;
import java.net.URLClassLoader;
-import java.util.Collections;
-import org.eclipse.jetty.util.TypeUtil;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
+import org.eclipse.jetty.util.component.DumpableCollection;
public class ClassLoaderDump implements Dumpable
{
@@ -38,7 +36,7 @@ public class ClassLoaderDump implements Dumpable
@Override
public String dump()
{
- return ContainerLifeCycle.dump(this);
+ return Dumpable.dump(this);
}
@Override
@@ -48,31 +46,34 @@ public class ClassLoaderDump implements Dumpable
out.append("No ClassLoader\n");
else if (_loader instanceof Dumpable)
{
- ContainerLifeCycle.dump(out,indent,Collections.singleton(_loader));
+ ((Dumpable)_loader).dump(out,indent);
}
else if (_loader instanceof URLClassLoader)
{
- out.append(String.valueOf(_loader)).append("\n");
+ String loader = _loader.toString();
+ DumpableCollection urls = DumpableCollection.fromArray("URLs", ((URLClassLoader)_loader).getURLs());
ClassLoader parent = _loader.getParent();
if (parent==null)
- ContainerLifeCycle.dump(out,indent,TypeUtil.asList(((URLClassLoader)_loader).getURLs()));
+ Dumpable.dumpObjects(out,indent,loader,urls);
else if (parent == Server.class.getClassLoader())
- ContainerLifeCycle.dump(out,indent,TypeUtil.asList(((URLClassLoader)_loader).getURLs()),Collections.singleton(parent.toString()));
+ Dumpable.dumpObjects(out,indent,loader,urls,parent.toString());
else if (parent instanceof Dumpable)
- ContainerLifeCycle.dump(out,indent,TypeUtil.asList(((URLClassLoader)_loader).getURLs()),Collections.singleton(parent));
+ Dumpable.dumpObjects(out,indent,loader,urls,parent);
else
- ContainerLifeCycle.dump(out,indent,TypeUtil.asList(((URLClassLoader)_loader).getURLs()),Collections.singleton(new ClassLoaderDump(parent)));
+ Dumpable.dumpObjects(out,indent,loader,urls,new ClassLoaderDump(parent));
}
else
{
- out.append(String.valueOf(_loader)).append("\n");
+ String loader = _loader.toString();
ClassLoader parent = _loader.getParent();
+ if (parent==null)
+ Dumpable.dumpObject(out,loader);
if (parent==Server.class.getClassLoader())
- ContainerLifeCycle.dump(out,indent,Collections.singleton(parent.toString()));
+ Dumpable.dumpObjects(out,indent,loader,parent.toString());
else if (parent instanceof Dumpable)
- ContainerLifeCycle.dump(out,indent,Collections.singleton(parent));
+ Dumpable.dumpObjects(out,indent,loader,parent);
else if (parent!=null)
- ContainerLifeCycle.dump(out,indent,Collections.singleton(new ClassLoaderDump(parent)));
+ Dumpable.dumpObjects(out,indent,loader,new ClassLoaderDump(parent));
}
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectorStatistics.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectorStatistics.java
index 519f71e7561..ae42690537c 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectorStatistics.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectorStatistics.java
@@ -19,7 +19,6 @@
package org.eclipse.jetty.server;
import java.io.IOException;
-import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -33,7 +32,6 @@ import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.annotation.ManagedOperation;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.Container;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.statistic.CounterStatistic;
import org.eclipse.jetty.util.statistic.SampleStatistic;
@@ -240,14 +238,17 @@ public class ConnectorStatistics extends AbstractLifeCycle implements Dumpable,
@ManagedOperation("dump thread state")
public String dump()
{
- return ContainerLifeCycle.dump(this);
+ return Dumpable.dump(this);
}
@Override
public void dump(Appendable out, String indent) throws IOException
{
- ContainerLifeCycle.dumpObject(out,this);
- ContainerLifeCycle.dump(out,indent,Arrays.asList(new String[]{"connections="+_connectionStats,"duration="+_connectionDurationStats,"in="+_messagesIn,"out="+_messagesOut}));
+ Dumpable.dumpObjects(out,indent,this,
+ "connections="+_connectionStats,
+ "duration="+_connectionDurationStats,
+ "in="+_messagesIn,
+ "out="+_messagesOut);
}
public static void addToAllConnectors(Server server)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java
index 97838eff969..cc7f6312a98 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java
@@ -628,6 +628,7 @@ public class Server extends HandlerWrapper implements Attributes
@Override
public void setAttribute(String name, Object attribute)
{
+ // TODO this is a crude way to get attribute values managed by JMX.
Object old=_attributes.getAttribute(name);
updateBean(old,attribute);
_attributes.setAttribute(name, attribute);
@@ -690,7 +691,7 @@ public class Server extends HandlerWrapper implements Attributes
@Override
public void dump(Appendable out,String indent) throws IOException
{
- dumpBeans(out,indent,Collections.singleton(new ClassLoaderDump(this.getClass().getClassLoader())));
+ dumpBeans(out,indent,new ClassLoaderDump(this.getClass().getClassLoader()),_attributes);
}
/* ------------------------------------------------------------ */
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
index e9560d603b2..ae7003247f2 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
@@ -256,11 +256,12 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
@Override
public void dump(Appendable out, String indent) throws IOException
{
- dumpBeans(out,indent,Collections.singletonList(new ClassLoaderDump(getClassLoader())),
- Collections.singletonList(new DumpableCollection("eventListeners "+this,_eventListeners)),
- Collections.singletonList(new DumpableCollection("handler attributes " + this,((AttributesMap)getAttributes()).getAttributeEntrySet())),
- Collections.singletonList(new DumpableCollection("context attributes " + this,((Context)getServletContext()).getAttributeEntrySet())),
- Collections.singletonList(new DumpableCollection("initparams " + this,getInitParams().entrySet())));
+ dumpBeans(out, indent,
+ new ClassLoaderDump(getClassLoader()),
+ new DumpableCollection("eventListeners " + this, _eventListeners),
+ new DumpableCollection("handler attributes " + this, ((AttributesMap)getAttributes()).getAttributeEntrySet()),
+ new DumpableCollection("context attributes " + this, ((Context)getServletContext()).getAttributeEntrySet()),
+ new DumpableCollection("initparams " + this,getInitParams().entrySet()));
}
/* ------------------------------------------------------------ */
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java
index 25f62ae8002..4b264af1949 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java
@@ -335,7 +335,7 @@ public class ContextHandlerCollection extends HandlerCollection
{
return _handler;
}
-
+
@Override
public String toString()
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java
index 2c28806fae9..0018d17ed7c 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java
@@ -202,12 +202,4 @@ public class HandlerCollection extends AbstractHandlerContainer
child.destroy();
super.destroy();
}
-
- /* ------------------------------------------------------------ */
- @Override
- public String toString()
- {
- Handler[] handlers=getHandlers();
- return super.toString()+(handlers==null?"[]":Arrays.asList(handlers).toString());
- }
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/InetAccessHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/InetAccessHandler.java
index 0aed271810d..4529f3fa7a8 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/InetAccessHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/InetAccessHandler.java
@@ -32,6 +32,7 @@ import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.IncludeExcludeSet;
import org.eclipse.jetty.util.InetAddressSet;
+import org.eclipse.jetty.util.component.DumpableCollection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -137,6 +138,8 @@ public class InetAccessHandler extends HandlerWrapper
@Override
public void dump(Appendable out, String indent) throws IOException
{
- dumpBeans(out, indent, _set.getIncluded(), _set.getExcluded());
+ dumpBeans(out, indent,
+ DumpableCollection.from("included",_set.getIncluded()),
+ DumpableCollection.from("excluded",_set.getExcluded()));
}
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ClassLoaderDumptTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ClassLoaderDumptTest.java
index b69e4652f41..3354d9511a6 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ClassLoaderDumptTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ClassLoaderDumptTest.java
@@ -48,8 +48,8 @@ public class ClassLoaderDumptTest
StringBuilder out = new StringBuilder();
server.dump(out);
String dump = out.toString();
- assertThat(dump,containsString("+- SimpleLoader"));
- assertThat(dump,containsString("+> "+Server.class.getClassLoader()));
+ assertThat(dump,containsString("+-SimpleLoader"));
+ assertThat(dump,containsString("+>"+Server.class.getClassLoader()));
}
@Test
@@ -69,9 +69,9 @@ public class ClassLoaderDumptTest
StringBuilder out = new StringBuilder();
server.dump(out);
String dump = out.toString();
- assertThat(dump,containsString("+- ParentedLoader"));
- assertThat(dump,containsString("| +- "+Server.class.getClassLoader()));
- assertThat(dump,containsString("+> "+Server.class.getClassLoader()));
+ assertThat(dump,containsString("+-ParentedLoader"));
+ assertThat(dump,containsString("| +>"+Server.class.getClassLoader()));
+ assertThat(dump,containsString("+>"+Server.class.getClassLoader()));
}
@Test
@@ -98,10 +98,10 @@ public class ClassLoaderDumptTest
StringBuilder out = new StringBuilder();
server.dump(out);
String dump = out.toString();
- assertThat(dump,containsString("+- TopLoader"));
- assertThat(dump,containsString("| +- MiddleLoader"));
- assertThat(dump,containsString("| +- "+Server.class.getClassLoader()));
- assertThat(dump,containsString("+> "+Server.class.getClassLoader()));
+ assertThat(dump,containsString("+-TopLoader"));
+ assertThat(dump,containsString("| +>MiddleLoader"));
+ assertThat(dump,containsString("| +>"+Server.class.getClassLoader()));
+ assertThat(dump,containsString("+>"+Server.class.getClassLoader()));
}
@Test
@@ -122,10 +122,10 @@ public class ClassLoaderDumptTest
StringBuilder out = new StringBuilder();
server.dump(out);
String dump = out.toString();
- assertThat(dump,containsString("+- TopLoader"));
- assertThat(dump,containsString("| +- DumpableClassLoader"));
- assertThat(dump,not(containsString("| +- "+Server.class.getClassLoader())));
- assertThat(dump,containsString("+> "+Server.class.getClassLoader()));
+ assertThat(dump,containsString("+-TopLoader"));
+ assertThat(dump,containsString("| +>DumpableClassLoader"));
+ assertThat(dump,not(containsString("| +>"+Server.class.getClassLoader())));
+ assertThat(dump,containsString("+>"+Server.class.getClassLoader()));
}
public static class DumpableClassLoader extends ClassLoader implements Dumpable
@@ -184,15 +184,15 @@ public class ClassLoaderDumptTest
server.dump(out);
String dump = out.toString();
// System.err.println(dump);
- assertThat(dump,containsString("+- TopLoader"));
- assertThat(dump,containsString("| +- file:/ONE"));
- assertThat(dump,containsString("| +- file:/TWO"));
- assertThat(dump,containsString("| +- file:/THREE"));
- assertThat(dump,containsString("| +- MiddleLoader"));
- assertThat(dump,containsString("| +- file:/one"));
- assertThat(dump,containsString("| +- file:/two"));
- assertThat(dump,containsString("| +- file:/three"));
- assertThat(dump,containsString("| +- "+Server.class.getClassLoader()));
- assertThat(dump,containsString("+> "+Server.class.getClassLoader()));
+ assertThat(dump,containsString("+-TopLoader"));
+ assertThat(dump,containsString("| | +>file:/ONE"));
+ assertThat(dump,containsString("| | +>file:/TWO"));
+ assertThat(dump,containsString("| | +>file:/THREE"));
+ assertThat(dump,containsString("| +>MiddleLoader"));
+ assertThat(dump,containsString("| | +>file:/one"));
+ assertThat(dump,containsString("| | +>file:/two"));
+ assertThat(dump,containsString("| | +>file:/three"));
+ assertThat(dump,containsString("| +>"+Server.class.getClassLoader()));
+ assertThat(dump,containsString("+>"+Server.class.getClassLoader()));
}
}
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/BaseHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/BaseHolder.java
index ef4ab0e8616..3b244704249 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/BaseHolder.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/BaseHolder.java
@@ -27,7 +27,6 @@ import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -194,14 +193,13 @@ public abstract class BaseHolder extends AbstractLifeCycle implements Dumpabl
@Override
public void dump(Appendable out, String indent) throws IOException
{
- out.append(toString())
- .append(" - ").append(AbstractLifeCycle.getState(this)).append("\n");
+ Dumpable.dumpObject(out, this);
}
/* ------------------------------------------------------------ */
@Override
public String dump()
{
- return ContainerLifeCycle.dump(this);
+ return Dumpable.dump(this);
}
}
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java
index 9e214dd7045..b4e03591156 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java
@@ -34,10 +34,11 @@ import javax.servlet.ServletException;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.component.Dumpable;
+import org.eclipse.jetty.util.component.DumpableCollection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-public class FilterHolder extends Holder
+public class FilterHolder extends Holder
{
private static final Logger LOG = Log.getLogger(FilterHolder.class);
@@ -100,10 +101,6 @@ public class FilterHolder extends Holder
}
}
-
-
-
-
/* ------------------------------------------------------------ */
@Override
@@ -195,21 +192,24 @@ public class FilterHolder extends Holder
return _filter;
}
- /* ------------------------------------------------------------ */
- @Override
- public String toString()
- {
- return getName();
- }
-
/* ------------------------------------------------------------ */
@Override
public void dump(Appendable out, String indent) throws IOException
{
- super.dump(out, indent);
- if(_filter instanceof Dumpable) {
- ((Dumpable) _filter).dump(out, indent);
- }
+ if (_initParams.isEmpty())
+ Dumpable.dumpObjects(out, indent, this,
+ _filter == null?getHeldClass():_filter);
+ else
+ Dumpable.dumpObjects(out, indent, this,
+ _filter == null?getHeldClass():_filter,
+ new DumpableCollection("initParams", _initParams.entrySet()));
+ }
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public String toString()
+ {
+ return String.format("%s@%x==%s,inst=%b,async=%b",_name,hashCode(),_className,_filter!=null,isAsyncSupported());
}
/* ------------------------------------------------------------ */
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java
index 50a1f6bf94e..5b66fea8b1d 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java
@@ -29,7 +29,6 @@ import org.eclipse.jetty.http.PathMap;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
@ManagedObject("Filter Mappings")
@@ -334,6 +333,6 @@ public class FilterMapping implements Dumpable
@Override
public String dump()
{
- return ContainerLifeCycle.dump(this);
+ return Dumpable.dump(this);
}
}
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java
index a2e9924207d..66a16d6f552 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java
@@ -32,6 +32,7 @@ import javax.servlet.ServletContext;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
+import org.eclipse.jetty.util.component.DumpableCollection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -45,7 +46,7 @@ import org.eclipse.jetty.util.log.Logger;
* @param the type of holder
*/
@ManagedObject("Holder - a container for servlets and the like")
-public class Holder extends BaseHolder
+public abstract class Holder extends BaseHolder
{
private static final Logger LOG = Log.getLogger(Holder.class);
@@ -188,15 +189,6 @@ public class Holder extends BaseHolder
return _asyncSupported;
}
-
- /* ------------------------------------------------------------ */
- @Override
- public void dump(Appendable out, String indent) throws IOException
- {
- super.dump(out,indent);
- ContainerLifeCycle.dump(out,indent,_initParams.entrySet());
- }
-
/* ------------------------------------------------------------ */
@Override
public String dump()
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
index 34adff4bf68..d64b86c98f7 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
@@ -138,11 +138,11 @@ public class ServletHandler extends ScopedHandler
public void dump(Appendable out, String indent) throws IOException
{
dumpBeans(out,indent,
- Collections.singletonList(new DumpableCollection("listeners "+this,_listeners)),
- Collections.singletonList(new DumpableCollection("filters "+this,_filters)),
- Collections.singletonList(new DumpableCollection("filterMappings "+this,_filterMappings)),
- Collections.singletonList(new DumpableCollection("servlets "+this,_servlets)),
- Collections.singletonList(new DumpableCollection("servletMappings "+this,_servletMappings)));
+ DumpableCollection.fromArray("listeners "+this,_listeners),
+ DumpableCollection.fromArray("filters "+this,_filters),
+ DumpableCollection.fromArray("filterMappings "+this,_filterMappings),
+ DumpableCollection.fromArray("servlets "+this,_servlets),
+ DumpableCollection.fromArray("servletMappings "+this,_servletMappings));
}
/* ----------------------------------------------------------------- */
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java
index e4681ab1a52..4ddec3bb15b 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java
@@ -55,6 +55,8 @@ import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
+import org.eclipse.jetty.util.component.Dumpable;
+import org.eclipse.jetty.util.component.DumpableCollection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -1312,11 +1314,23 @@ public class ServletHolder extends Holder implements UserIdentity.Scope
}
}
+ /* ------------------------------------------------------------ */
+ @Override
+ public void dump(Appendable out, String indent) throws IOException
+ {
+ if (_initParams.isEmpty())
+ Dumpable.dumpObjects(out, indent, this,
+ _servlet == null?getHeldClass():_servlet);
+ else
+ Dumpable.dumpObjects(out, indent, this,
+ _servlet == null?getHeldClass():_servlet,
+ new DumpableCollection("initParams", _initParams.entrySet()));
+ }
/* ------------------------------------------------------------ */
@Override
public String toString()
{
- return String.format("%s@%x==%s,jsp=%s,order=%d,inst=%b",_name,hashCode(),_className,_forcedPath,_initOrder,_servlet!=null);
+ return String.format("%s@%x==%s,jsp=%s,order=%d,inst=%b,async=%b",_name,hashCode(),_className,_forcedPath,_initOrder,_servlet!=null,isAsyncSupported());
}
}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/AttributesMap.java b/jetty-util/src/main/java/org/eclipse/jetty/util/AttributesMap.java
index b086228589a..4ff033d6673 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/AttributesMap.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/AttributesMap.java
@@ -18,6 +18,9 @@
package org.eclipse.jetty.util;
+import org.eclipse.jetty.util.component.Dumpable;
+
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
@@ -28,7 +31,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReference;
-public class AttributesMap implements Attributes
+public class AttributesMap implements Attributes, Dumpable
{
private final AtomicReference> _map = new AtomicReference<>();
@@ -148,4 +151,16 @@ public class AttributesMap implements Attributes
setAttribute(name, attributes.getAttribute(name));
}
}
+
+ @Override
+ public String dump()
+ {
+ return Dumpable.dump(this);
+ }
+
+ @Override
+ public void dump(Appendable out, String indent) throws IOException
+ {
+ Dumpable.dumpObjects(out,indent,String.format("%s@%x",this.getClass().getSimpleName(),hashCode()),map());
+ }
}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/ContainerLifeCycle.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/ContainerLifeCycle.java
index 4b6d963969e..fd1f70447cc 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/component/ContainerLifeCycle.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/ContainerLifeCycle.java
@@ -230,6 +230,30 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
return false;
}
+ /**
+ * @param bean the bean to test
+ * @return whether this aggregate contains the bean in auto state
+ */
+ public boolean isAuto(Object bean)
+ {
+ for (Bean b : _beans)
+ if (b._bean == bean)
+ return b._managed==Managed.AUTO;
+ return false;
+ }
+
+ /**
+ * @param bean the bean to test
+ * @return whether this aggregate contains the bean in auto state
+ */
+ public boolean isUnmanaged(Object bean)
+ {
+ for (Bean b : _beans)
+ if (b._bean == bean)
+ return b._managed==Managed.UNMANAGED;
+ return false;
+ }
+
/**
* Adds the given bean, detecting whether to manage it or not.
* If the bean is a {@link LifeCycle}, then it will be managed if it is not
@@ -616,6 +640,7 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
try
{
dump(System.err, "");
+ System.err.println(Dumpable.KEY);
}
catch (IOException e)
{
@@ -627,46 +652,7 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
@ManagedOperation("Dump the object to a string")
public String dump()
{
- return dump(this);
- }
-
- public static String dump(Dumpable dumpable)
- {
- StringBuilder b = new StringBuilder();
- try
- {
- dumpable.dump(b, "");
- }
- catch (IOException e)
- {
- LOG.warn(e);
- }
- return b.toString();
- }
-
- public void dump(Appendable out) throws IOException
- {
- dump(out, "");
- }
-
- protected void dumpThis(Appendable out) throws IOException
- {
- out.append(String.valueOf(this)).append(" - ").append(getState()).append("\n");
- }
-
- public static void dumpObject(Appendable out, Object o) throws IOException
- {
- try
- {
- if (o instanceof LifeCycle)
- out.append(String.valueOf(o)).append(" - ").append((AbstractLifeCycle.getState((LifeCycle)o))).append("\n");
- else
- out.append(String.valueOf(o)).append("\n");
- }
- catch (Throwable th)
- {
- out.append(" => ").append(th.toString()).append('\n');
- }
+ return Dumpable.dump(this);
}
@Override
@@ -675,63 +661,41 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
dumpBeans(out,indent);
}
- protected void dumpBeans(Appendable out, String indent, Collection>... collections) throws IOException
+ /**
+ * Dump this object to an Appendable with no indent.
+ * @param out The appendable to dump to.
+ * @throws IOException May be thrown by the Appendable
+ */
+ public void dump(Appendable out) throws IOException
{
- dumpThis(out);
- int size = _beans.size();
- for (Collection> c : collections)
- size += c.size();
- int i = 0;
- for (Bean b : _beans)
- {
- ++i;
- switch(b._managed)
- {
- case POJO:
- out.append(indent).append(" +- ");
- if (b._bean instanceof Dumpable)
- ((Dumpable)b._bean).dump(out, indent + (i == size ? " " : " | "));
- else
- dumpObject(out, b._bean);
- break;
-
- case MANAGED:
- out.append(indent).append(" += ");
- if (b._bean instanceof Dumpable)
- ((Dumpable)b._bean).dump(out, indent + (i == size ? " " : " | "));
- else
- dumpObject(out, b._bean);
- break;
-
- case UNMANAGED:
- out.append(indent).append(" +~ ");
- dumpObject(out, b._bean);
- break;
-
- case AUTO:
- out.append(indent).append(" +? ");
- if (b._bean instanceof Dumpable)
- ((Dumpable)b._bean).dump(out, indent + (i == size ? " " : " | "));
- else
- dumpObject(out, b._bean);
- break;
- }
- }
-
- for (Collection> c : collections)
- {
- for (Object o : c)
- {
- i++;
- out.append(indent).append(" +> ");
- if (o instanceof Dumpable)
- ((Dumpable)o).dump(out, indent + (i == size ? " " : " | "));
- else
- dumpObject(out, o);
- }
- }
+ dump(out, "");
}
+ /**
+ * Dump just this object, but not it's children. Typically used to
+ * implement {@link #dump(Appendable, String)}
+ * @param out The appendable to dump to
+ * @throws IOException May be thrown by the Appendable
+ */
+ @Deprecated
+ protected void dumpThis(Appendable out) throws IOException
+ {
+ out.append(String.valueOf(this)).append(" - ").append(getState()).append("\n");
+ }
+
+
+ /** Dump this object, it's contained beans and additional items to an Appendable
+ * @param out The appendable to dump to
+ * @param indent The indent to apply after any new lines
+ * @param items Additional items to be dumped as contained.
+ * @throws IOException May be thrown by the Appendable
+ */
+ protected void dumpBeans(Appendable out, String indent, Object... items) throws IOException
+ {
+ Dumpable.dumpObjects(out,indent,this, items);
+ }
+
+ @Deprecated
public static void dump(Appendable out, String indent, Collection>... collections) throws IOException
{
if (collections.length == 0)
@@ -749,11 +713,7 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
{
i++;
out.append(indent).append(" +- ");
-
- if (o instanceof Dumpable)
- ((Dumpable)o).dump(out, indent + (i == size ? " " : " | "));
- else
- dumpObject(out, o);
+ Dumpable.dumpObjects(out,indent + (i)o).size());
+ else
+ s = String.valueOf(o).replace("\r\n","|").replace("\n","|");
+
+ if (o instanceof LifeCycle)
+ out.append(s).append(" - ").append((AbstractLifeCycle.getState((LifeCycle)o))).append("\n");
+ else
+ out.append(s).append("\n");
+ }
+ catch (Throwable th)
+ {
+ out.append("=>").append(th.toString()).append("\n");
+ }
+ }
+
+ /**
+ * Dump an Object, it's contained items and additional items to an {@link Appendable}.
+ * If the object in an {@link Iterable} or an {@link Array}, then its contained items
+ * are also dumped.
+ * @param out the Appendable to dump to
+ * @param indent The indent to apply after any new lines
+ * @param object The object to dump. If the object is an instance
+ * of {@link Container}, {@link Stream}, {@link Iterable}, {@link Array} or {@link Map},
+ * then children of the object a recursively dumped.
+ * @param extraChildren Items to be dumped as children of the object, in addition to any discovered children of object
+ * @throws IOException May be thrown by the Appendable
+ */
+ static void dumpObjects(Appendable out, String indent, Object object, Object... extraChildren) throws IOException
+ {
+ dumpObject(out,object);
+
+ int size = extraChildren==null?0:extraChildren.length;
+
+ if (object instanceof Stream)
+ object = ((Stream)object).toArray();
+ if (object instanceof Array)
+ object = Arrays.asList((Object[])object);
+
+ if (object instanceof Container)
+ {
+ Container container = (Container)object;
+ ContainerLifeCycle containerLifeCycle = container instanceof ContainerLifeCycle ? (ContainerLifeCycle)container : null;
+ for (Iterator
-
- javax.transaction
- javax.transaction-api
- org.eclipse.jettyjetty-proxy
From 5d837309c322d54fc30291fe6ea13b56beab8e6f Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Tue, 30 Oct 2018 17:42:11 +0100
Subject: [PATCH 108/931] Issue #2941 - JDK 11: UnsupportedOperationException
at AnnotationParser.scanClass.
Downgraded OSGi ASM version to 6.2.
Waiting for the SPI Fly library to support JDK 11.
Signed-off-by: Simone Bordet
---
jetty-osgi/pom.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml
index 090cc250a42..503b4cba7e3 100644
--- a/jetty-osgi/pom.xml
+++ b/jetty-osgi/pom.xml
@@ -15,6 +15,7 @@
pom
+ 6.23.6.0.v201005173.2.100.v201005031.0.0-v20070606
From 31cab3dc0884e1cc26ce514aa9cdf92ae40856d8 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Tue, 30 Oct 2018 19:36:02 +0100
Subject: [PATCH 109/931] Issue #2796 - Max local stream count exceeded when
request fails.
Restored smaller maxContentLength to avoid that the test takes
too much time and fails.
Signed-off-by: Simone Bordet
---
.../org/eclipse/jetty/http/client/HttpClientLoadTest.java | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java
index 65b72262eac..814d9bd011b 100644
--- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java
+++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java
@@ -19,6 +19,7 @@
package org.eclipse.jetty.http.client;
import java.io.IOException;
+import java.io.InterruptedIOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
@@ -199,7 +200,7 @@ public class HttpClientLoadTest extends AbstractTest
Date: Wed, 31 Oct 2018 09:24:20 +1000
Subject: [PATCH 110/931] *issue #2923 add LICENSE and NOTICE files (#2940)
*remove html license version
* use org.eclipse.jetty.toolchain:jetty-artifact-remote-resources:1.2 released version
Signed-off-by: olivier lamy
---
LICENSE | 414 ++++++++++++++++++++++++++
LICENSE-eplv10-aslv20.html | 576 -------------------------------------
pom.xml | 2 +-
3 files changed, 415 insertions(+), 577 deletions(-)
create mode 100644 LICENSE
delete mode 100644 LICENSE-eplv10-aslv20.html
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000000..46f4f252464
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,414 @@
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License 2.0 which is available at
+http://www.eclipse.org/legal/epl-2.0, or the Apache Software License
+2.0 which is available at https://www.apache.org/licenses/LICENSE-2.0.
+
+
+
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
+LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
+CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and documentation
+ distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+ i) changes to the Program, and
+ ii) additions to the Program;
+
+ where such changes and/or additions to the Program originate from and are
+ distributed by that particular Contributor. A Contribution 'originates'
+ from a Contributor if it was added to the Program by such Contributor
+ itself or anyone acting on such Contributor's behalf. Contributions do not
+ include additions to the Program which: (i) are separate modules of
+ software distributed in conjunction with the Program under their own
+ license agreement, and (ii) are not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents" mean patent claims licensable by a Contributor which are
+necessarily infringed by the use or sale of its Contribution alone or when
+combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this
+Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement,
+including all Contributors.
+
+2. GRANT OF RIGHTS
+ a) Subject to the terms of this Agreement, each Contributor hereby grants
+ Recipient a non-exclusive, worldwide, royalty-free copyright license to
+ reproduce, prepare derivative works of, publicly display, publicly
+ perform, distribute and sublicense the Contribution of such Contributor,
+ if any, and such derivative works, in source code and object code form.
+ b) Subject to the terms of this Agreement, each Contributor hereby grants
+ Recipient a non-exclusive, worldwide, royalty-free patent license under
+ Licensed Patents to make, use, sell, offer to sell, import and otherwise
+ transfer the Contribution of such Contributor, if any, in source code and
+ object code form. This patent license shall apply to the combination of
+ the Contribution and the Program if, at the time the Contribution is
+ added by the Contributor, such addition of the Contribution causes such
+ combination to be covered by the Licensed Patents. The patent license
+ shall not apply to any other combinations which include the Contribution.
+ No hardware per se is licensed hereunder.
+ c) Recipient understands that although each Contributor grants the licenses
+ to its Contributions set forth herein, no assurances are provided by any
+ Contributor that the Program does not infringe the patent or other
+ intellectual property rights of any other entity. Each Contributor
+ disclaims any liability to Recipient for claims brought by any other
+ entity based on infringement of intellectual property rights or
+ otherwise. As a condition to exercising the rights and licenses granted
+ hereunder, each Recipient hereby assumes sole responsibility to secure
+ any other intellectual property rights needed, if any. For example, if a
+ third party patent license is required to allow Recipient to distribute
+ the Program, it is Recipient's responsibility to acquire that license
+ before distributing the Program.
+ d) Each Contributor represents that to its knowledge it has sufficient
+ copyright rights in its Contribution, if any, to grant the copyright
+ license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under
+its own license agreement, provided that:
+
+ a) it complies with the terms and conditions of this Agreement; and
+ b) its license agreement:
+ i) effectively disclaims on behalf of all Contributors all warranties
+ and conditions, express and implied, including warranties or
+ conditions of title and non-infringement, and implied warranties or
+ conditions of merchantability and fitness for a particular purpose;
+ ii) effectively excludes on behalf of all Contributors all liability for
+ damages, including direct, indirect, special, incidental and
+ consequential damages, such as lost profits;
+ iii) states that any provisions which differ from this Agreement are
+ offered by that Contributor alone and not by any other party; and
+ iv) states that source code for the Program is available from such
+ Contributor, and informs licensees how to obtain it in a reasonable
+ manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+ a) it must be made available under this Agreement; and
+ b) a copy of this Agreement must be included with each copy of the Program.
+ Contributors may not remove or alter any copyright notices contained
+ within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution,
+if
+any, in a manner that reasonably allows subsequent Recipients to identify the
+originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with
+respect to end users, business partners and the like. While this license is
+intended to facilitate the commercial use of the Program, the Contributor who
+includes the Program in a commercial product offering should do so in a manner
+which does not create potential liability for other Contributors. Therefore,
+if a Contributor includes the Program in a commercial product offering, such
+Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
+every other Contributor ("Indemnified Contributor") against any losses,
+damages and costs (collectively "Losses") arising from claims, lawsuits and
+other legal actions brought by a third party against the Indemnified
+Contributor to the extent caused by the acts or omissions of such Commercial
+Contributor in connection with its distribution of the Program in a commercial
+product offering. The obligations in this section do not apply to any claims
+or Losses relating to any actual or alleged intellectual property
+infringement. In order to qualify, an Indemnified Contributor must:
+a) promptly notify the Commercial Contributor in writing of such claim, and
+b) allow the Commercial Contributor to control, and cooperate with the
+Commercial Contributor in, the defense and any related settlement
+negotiations. The Indemnified Contributor may participate in any such claim at
+its own expense.
+
+For example, a Contributor might include the Program in a commercial product
+offering, Product X. That Contributor is then a Commercial Contributor. If
+that Commercial Contributor then makes performance claims, or offers
+warranties related to Product X, those performance claims and warranties are
+such Commercial Contributor's responsibility alone. Under this section, the
+Commercial Contributor would have to defend claims against the other
+Contributors related to those performance claims and warranties, and if a
+court requires any other Contributor to pay any damages as a result, the
+Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
+Recipient is solely responsible for determining the appropriateness of using
+and distributing the Program and assumes all risks associated with its
+exercise of rights under this Agreement , including but not limited to the
+risks and costs of program errors, compliance with applicable laws, damage to
+or loss of data, programs or equipment, and unavailability or interruption of
+operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
+CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
+LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
+EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
+OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of the
+remainder of the terms of this Agreement, and without further action by the
+parties hereto, such provision shall be reformed to the minimum extent
+necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Program itself
+(excluding combinations of the Program with other software or hardware)
+infringes such Recipient's patent(s), then such Recipient's rights granted
+under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to
+comply with any of the material terms or conditions of this Agreement and does
+not cure such failure in a reasonable period of time after becoming aware of
+such noncompliance. If all Recipient's rights under this Agreement terminate,
+Recipient agrees to cease use and distribution of the Program as soon as
+reasonably practicable. However, Recipient's obligations under this Agreement
+and any licenses granted by Recipient relating to the Program shall continue
+and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in
+order to avoid inconsistency the Agreement is copyrighted and may only be
+modified in the following manner. The Agreement Steward reserves the right to
+publish new versions (including revisions) of this Agreement from time to
+time. No one other than the Agreement Steward has the right to modify this
+Agreement. The Eclipse Foundation is the initial Agreement Steward. The
+Eclipse Foundation may assign the responsibility to serve as the Agreement
+Steward to a suitable separate entity. Each new version of the Agreement will
+be given a distinguishing version number. The Program (including
+Contributions) may always be distributed subject to the version of the
+Agreement under which it was received. In addition, after a new version of the
+Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly
+stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
+licenses to the intellectual property of any Contributor under this Agreement,
+whether expressly, by implication, estoppel or otherwise. All rights in the
+Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the
+intellectual property laws of the United States of America. No party to this
+Agreement will bring a legal action under this Agreement more than one year
+after the cause of action arose. Each party waives its rights to a jury trial in
+any resulting litigation.
+
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/LICENSE-eplv10-aslv20.html b/LICENSE-eplv10-aslv20.html
deleted file mode 100644
index 48addaaddf7..00000000000
--- a/LICENSE-eplv10-aslv20.html
+++ /dev/null
@@ -1,576 +0,0 @@
-
-
-
-
-
-
-
-
-Eclipse Public License - Version 1.0 / Apache License - Version 2.0
-
-
-
-
-
-
-
Eclipse Public License - v 1.0
-
-
-
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
-THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE,
-REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
-OF THIS AGREEMENT.
-
-
1. DEFINITIONS
-
-
"Contribution" means:
-
-
a)
-in the case of the initial Contributor, the initial code and documentation
-distributed under this Agreement, and
-b) in the case of each subsequent Contributor:
-
-
i)
-changes to the Program, and
-
-
ii)
-additions to the Program;
-
-
where
-such changes and/or additions to the Program originate from and are distributed
-by that particular Contributor. A Contribution 'originates' from a Contributor
-if it was added to the Program by such Contributor itself or anyone acting on
-such Contributor's behalf. Contributions do not include additions to the
-Program which: (i) are separate modules of software distributed in conjunction
-with the Program under their own license agreement, and (ii) are not derivative
-works of the Program.
-
-
"Contributor" means any person or
-entity that distributes the Program.
-
-
"Licensed Patents " mean patent
-claims licensable by a Contributor which are necessarily infringed by the use
-or sale of its Contribution alone or when combined with the Program.
-
-
"Program" means the Contributions
-distributed in accordance with this Agreement.
-
-
"Recipient" means anyone who
-receives the Program under this Agreement, including all Contributors.
-
-
2. GRANT OF RIGHTS
-
-
a)
-Subject to the terms of this Agreement, each Contributor hereby grants Recipient
-a non-exclusive, worldwide, royalty-free copyright license toreproduce, prepare derivative works of, publicly
-display, publicly perform, distribute and sublicense the Contribution of such
-Contributor, if any, and such derivative works, in source code and object code
-form.
-
-
b)
-Subject to the terms of this Agreement, each Contributor hereby grants
-Recipient a non-exclusive, worldwide,royalty-free
-patent license under Licensed Patents to make, use, sell, offer to sell, import
-and otherwise transfer the Contribution of such Contributor, if any, in source
-code and object code form. This patent license shall apply to the combination
-of the Contribution and the Program if, at the time the Contribution is added
-by the Contributor, such addition of the Contribution causes such combination
-to be covered by the Licensed Patents. The patent license shall not apply to
-any other combinations which include the Contribution. No hardware per se is
-licensed hereunder.
-
-
c)
-Recipient understands that although each Contributor grants the licenses to its
-Contributions set forth herein, no assurances are provided by any Contributor
-that the Program does not infringe the patent or other intellectual property
-rights of any other entity. Each Contributor disclaims any liability to Recipient
-for claims brought by any other entity based on infringement of intellectual
-property rights or otherwise. As a condition to exercising the rights and
-licenses granted hereunder, each Recipient hereby assumes sole responsibility
-to secure any other intellectual property rights needed, if any. For example,
-if a third party patent license is required to allow Recipient to distribute
-the Program, it is Recipient's responsibility to acquire that license before
-distributing the Program.
-
-
d)
-Each Contributor represents that to its knowledge it has sufficient copyright
-rights in its Contribution, if any, to grant the copyright license set forth in
-this Agreement.
-
-
3. REQUIREMENTS
-
-
A Contributor may choose to distribute the
-Program in object code form under its own license agreement, provided that:
-
-
-
a)
-it complies with the terms and conditions of this Agreement; and
-
-
b)
-its license agreement:
-
-
i)
-effectively disclaims on behalf of all Contributors all warranties and
-conditions, express and implied, including warranties or conditions of title
-and non-infringement, and implied warranties or conditions of merchantability
-and fitness for a particular purpose;
-
-
ii)
-effectively excludes on behalf of all Contributors all liability for damages,
-including direct, indirect, special, incidental and consequential damages, such
-as lost profits;
-
-
iii)
-states that any provisions which differ from this Agreement are offered by that
-Contributor alone and not by any other party; and
-
-
iv)
-states that source code for the Program is available from such Contributor, and
-informs licensees how to obtain it in a reasonable manner on or through a
-medium customarily used for software exchange.
-
-
When the Program is made available in source
-code form:
-
-
a)
-it must be made available under this Agreement; and
-
-
b) a
-copy of this Agreement must be included with each copy of the Program.
-
-
Contributors may not remove or alter any
-copyright notices contained within the Program.
-
-
Each Contributor must identify itself as the
-originator of its Contribution, if any, in a manner that reasonably allows
-subsequent Recipients to identify the originator of the Contribution.
-
-
4. COMMERCIAL DISTRIBUTION
-
-
Commercial distributors of software may
-accept certain responsibilities with respect to end users, business partners
-and the like. While this license is intended to facilitate the commercial use
-of the Program, the Contributor who includes the Program in a commercial
-product offering should do so in a manner which does not create potential
-liability for other Contributors. Therefore, if a Contributor includes the
-Program in a commercial product offering, such Contributor ("Commercial
-Contributor") hereby agrees to defend and indemnify every other
-Contributor ("Indemnified Contributor") against any losses, damages and
-costs (collectively "Losses") arising from claims, lawsuits and other
-legal actions brought by a third party against the Indemnified Contributor to
-the extent caused by the acts or omissions of such Commercial Contributor in
-connection with its distribution of the Program in a commercial product
-offering. The obligations in this section do not apply to any claims or Losses
-relating to any actual or alleged intellectual property infringement. In order
-to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
-Contributor in writing of such claim, and b) allow the Commercial Contributor
-to control, and cooperate with the Commercial Contributor in, the defense and
-any related settlement negotiations. The Indemnified Contributor may participate
-in any such claim at its own expense.
-
-
For example, a Contributor might include the
-Program in a commercial product offering, Product X. That Contributor is then a
-Commercial Contributor. If that Commercial Contributor then makes performance
-claims, or offers warranties related to Product X, those performance claims and
-warranties are such Commercial Contributor's responsibility alone. Under this
-section, the Commercial Contributor would have to defend claims against the
-other Contributors related to those performance claims and warranties, and if a
-court requires any other Contributor to pay any damages as a result, the
-Commercial Contributor must pay those damages.
-
-
5. NO WARRANTY
-
-
EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
-WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
-MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
-responsible for determining the appropriateness of using and distributing the
-Program and assumes all risks associated with its exercise of rights under this
-Agreement , including but not limited to the risks and costs of program errors,
-compliance with applicable laws, damage to or loss of data, programs or
-equipment, and unavailability or interruption of operations.
-
-
6. DISCLAIMER OF LIABILITY
-
-
EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
-THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGES.
-
-
7. GENERAL
-
-
If any provision of this Agreement is invalid
-or unenforceable under applicable law, it shall not affect the validity or
-enforceability of the remainder of the terms of this Agreement, and without
-further action by the parties hereto, such provision shall be reformed to the
-minimum extent necessary to make such provision valid and enforceable.
-
-
If Recipient institutes patent litigation
-against any entity (including a cross-claim or counterclaim in a lawsuit)
-alleging that the Program itself (excluding combinations of the Program with
-other software or hardware) infringes such Recipient's patent(s), then such
-Recipient's rights granted under Section 2(b) shall terminate as of the date
-such litigation is filed.
-
-
All Recipient's rights under this Agreement
-shall terminate if it fails to comply with any of the material terms or
-conditions of this Agreement and does not cure such failure in a reasonable
-period of time after becoming aware of such noncompliance. If all Recipient's
-rights under this Agreement terminate, Recipient agrees to cease use and
-distribution of the Program as soon as reasonably practicable. However,
-Recipient's obligations under this Agreement and any licenses granted by
-Recipient relating to the Program shall continue and survive.
-
-
Everyone is permitted to copy and distribute
-copies of this Agreement, but in order to avoid inconsistency the Agreement is
-copyrighted and may only be modified in the following manner. The Agreement
-Steward reserves the right to publish new versions (including revisions) of
-this Agreement from time to time. No one other than the Agreement Steward has
-the right to modify this Agreement. The Eclipse Foundation is the initial
-Agreement Steward. The Eclipse Foundation may assign the responsibility to
-serve as the Agreement Steward to a suitable separate entity. Each new version
-of the Agreement will be given a distinguishing version number. The Program
-(including Contributions) may always be distributed subject to the version of
-the Agreement under which it was received. In addition, after a new version of
-the Agreement is published, Contributor may elect to distribute the Program
-(including its Contributions) under the new version. Except as expressly stated
-in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
-the intellectual property of any Contributor under this Agreement, whether
-expressly, by implication, estoppel or otherwise. All rights in the Program not
-expressly granted under this Agreement are reserved.
-
-
This Agreement is governed by the laws of the
-State of New York and the intellectual property laws of the United States of
-America. No party to this Agreement will bring a legal action under this
-Agreement more than one year after the cause of action arose. Each party waives
-its rights to a jury trial in any resulting litigation.
-
-
-
-
-
-
-
-
Apache License
-Version 2.0, January 2004
-http://www.apache.org/licenses/
-
-
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-
2. Grant of Copyright License.
-
-Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-
-
3. Grant of Patent License.
-
-
- Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-
- 4. Redistribution.
-
-
-
You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
-
-
-
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-
- 5. Submission of Contributions.
-
-
-
Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-
- 6. Trademarks.
-
-
-
This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-
- 7. Disclaimer of Warranty.
-
-
-
Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-
- 8. Limitation of Liability.
-
-
-
In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-
- 9. Accepting Warranty or Additional Liability.
-
-
While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-
-
- END OF TERMS AND CONDITIONS
-
-
-
- APPENDIX: How to apply the Apache License to your work.
-
-
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-
-
- Copyright [yyyy] [name of copyright owner]
-
-
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-
-
-
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 18221c13ddc..28d30d6cda2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -285,7 +285,7 @@
- org.eclipse.jetty.toolchain:jetty-artifact-remote-resources:1.1
+ org.eclipse.jetty.toolchain:jetty-artifact-remote-resources:1.2
From 94bfeacba5851f8dfd541b22bdfc6bd818d055fb Mon Sep 17 00:00:00 2001
From: WalkerWatch
Date: Wed, 31 Oct 2018 16:56:25 -0400
Subject: [PATCH 111/931] Added note on stopping the server. Resolves #3033
---
.../asciidoc/quick-start/getting-started/jetty-running.adoc | 2 ++
1 file changed, 2 insertions(+)
diff --git a/jetty-documentation/src/main/asciidoc/quick-start/getting-started/jetty-running.adoc b/jetty-documentation/src/main/asciidoc/quick-start/getting-started/jetty-running.adoc
index 4e497fe43fc..de8808a3193 100644
--- a/jetty-documentation/src/main/asciidoc/quick-start/getting-started/jetty-running.adoc
+++ b/jetty-documentation/src/main/asciidoc/quick-start/getting-started/jetty-running.adoc
@@ -38,6 +38,8 @@ $ java -jar start.jar
You can point a browser at this server at link:http://localhost:8080[].
However, as there are no webapps deployed in the `$JETTY_HOME` directory, you will see a 404 error page served by Jetty.
+To stop the server, press `CTRL` + `c` or `CTRL` + `z` in your terminal.
+
*Note* the `HomeBaseWarning` - it is *not* recommended to run Jetty from the `$JETTY_HOME` directory.
Instead, see how to link:#creating-jetty-base[create a Jetty Base] below.
From 392260a2323c4202a34103fddd159d804dc85cb7 Mon Sep 17 00:00:00 2001
From: olivier lamy
Date: Thu, 1 Nov 2018 12:38:48 +1000
Subject: [PATCH 112/931] maven-plugin-plugin 3.6.0
Signed-off-by: olivier lamy
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 28d30d6cda2..15998e537a1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -524,7 +524,7 @@
org.apache.maven.pluginsmaven-plugin-plugin
- 3.5.2
+ 3.6.0org.apache.maven.plugins
From 8dcd7e44d8e0a9042d5e1103715992774e0ae6fa Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Thu, 1 Nov 2018 11:43:11 +0100
Subject: [PATCH 113/931] Allows commas to separate cookies in RFC2965
compliance mode (#3045)
* Allows commas to separate cookies in RFC2965 compliance mode
* cleanup after review
Signed-off-by: Greg Wilkins
* revert accidental change
Signed-off-by: Greg Wilkins
---
.../eclipse/jetty/server/CookieCutter.java | 242 ++++++++----------
.../org/eclipse/jetty/server/Request.java | 13 +-
.../jetty/server/CookieCutterTest.java | 13 +-
.../server/CookieCutter_LenientTest.java | 7 +-
4 files changed, 125 insertions(+), 150 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java
index 2a186b18026..d9e7971df05 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/CookieCutter.java
@@ -129,7 +129,6 @@ public class CookieCutter
{
// Parse the header
String name = null;
- String value = null;
Cookie cookie = null;
@@ -139,11 +138,11 @@ public class CookieCutter
boolean escaped=false;
int tokenstart=-1;
int tokenend=-1;
- for (int i = 0, length = hdr.length(), last=length-1; i < length; i++)
+ for (int i = 0, length = hdr.length(); i <= length; i++)
{
- char c = hdr.charAt(i);
+ char c = i==length?0:hdr.charAt(i);
- // System.err.printf("i=%d c=%s v=%b q=%b e=%b u=%s s=%d e=%d%n" ,i,""+c,invalue,inQuoted,escaped,unquoted,tokenstart,tokenend);
+ // System.err.printf("i=%d/%d c=%s v=%b q=%b/%b e=%b u=%s s=%d e=%d \t%s=%s%n" ,i,length,c==0?"|":(""+c),invalue,inQuoted,quoted,escaped,unquoted,tokenstart,tokenend,name,value);
// Handle quoted values for name or value
if (inQuoted)
@@ -151,52 +150,39 @@ public class CookieCutter
if (escaped)
{
escaped=false;
- unquoted.append(c);
+ if (c>0)
+ unquoted.append(c);
+ else
+ {
+ unquoted.setLength(0);
+ inQuoted = false;
+ i--;
+ }
continue;
}
switch (c)
{
case '"':
- inQuoted=false;
- if (i==last)
- {
- value = unquoted.toString();
- unquoted.setLength(0);
- }
- else
- {
- quoted=true;
- tokenstart=i;
- tokenend=-1;
- }
+ inQuoted = false;
+ quoted = true;
+ tokenstart = i;
+ tokenend = -1;
break;
-
+
case '\\':
- if (i==last)
- {
- unquoted.setLength(0);
- inQuoted = false;
- i--;
- }
- else
- {
- escaped=true;
- }
+ escaped = true;
+ continue;
+
+ case 0:
+ // unterminated quote, let's ignore quotes
+ unquoted.setLength(0);
+ inQuoted = false;
+ i--;
continue;
default:
- if (i==last)
- {
- // unterminated quote, let's ignore quotes
- unquoted.setLength(0);
- inQuoted = false;
- i--;
- }
- else
- {
- unquoted.append(c);
- }
+ unquoted.append(c);
continue;
}
}
@@ -211,22 +197,88 @@ public class CookieCutter
case ' ':
case '\t':
break;
-
+
+ case ',':
+ if (_compliance!=CookieCompliance.RFC2965)
+ {
+ if (quoted)
+ {
+ // must have been a bad internal quote. let's fix as best we can
+ unquoted.append(hdr,tokenstart,i--);
+ inQuoted = true;
+ quoted = false;
+ continue;
+ }
+ if (tokenstart<0)
+ tokenstart = i;
+ tokenend=i;
+ continue;
+ }
+ // fall through
+ case 0:
case ';':
+ {
+ String value;
+
if (quoted)
{
value = unquoted.toString();
unquoted.setLength(0);
quoted = false;
}
- else if(tokenstart>=0 && tokenend>=0)
- value = hdr.substring(tokenstart, tokenend+1);
+ else if(tokenstart>=0)
+ value = tokenend>=tokenstart?hdr.substring(tokenstart, tokenend+1):hdr.substring(tokenstart);
else
value = "";
-
+
+ try
+ {
+ if (name.startsWith("$"))
+ {
+ if (_compliance==CookieCompliance.RFC2965)
+ {
+ String lowercaseName = name.toLowerCase(Locale.ENGLISH);
+ switch(lowercaseName)
+ {
+ case "$path":
+ if (cookie!=null)
+ cookie.setPath(value);
+ break;
+ case "$domain":
+ if (cookie!=null)
+ cookie.setDomain(value);
+ break;
+ case "$port":
+ if (cookie!=null)
+ cookie.setComment("$port="+value);
+ break;
+ case "$version":
+ version = Integer.parseInt(value);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else
+ {
+ cookie = new Cookie(name, value);
+ if (version > 0)
+ cookie.setVersion(version);
+ cookies.add(cookie);
+ }
+ }
+ catch (Exception e)
+ {
+ LOG.debug(e);
+ }
+
+ name = null;
tokenstart = -1;
invalue=false;
+
break;
+ }
case '"':
if (tokenstart<0)
@@ -243,20 +295,14 @@ public class CookieCutter
if (quoted)
{
// must have been a bad internal quote. let's fix as best we can
- unquoted.append(hdr.substring(tokenstart,i));
+ unquoted.append(hdr,tokenstart,i--);
inQuoted = true;
quoted = false;
- i--;
continue;
}
if (tokenstart<0)
- tokenstart=i;
+ tokenstart = i;
tokenend=i;
- if (i==last)
- {
- value = hdr.substring(tokenstart, tokenend+1);
- break;
- }
continue;
}
}
@@ -269,21 +315,6 @@ public class CookieCutter
case '\t':
continue;
- case ';':
- if (quoted)
- {
- name = unquoted.toString();
- unquoted.setLength(0);
- quoted = false;
- }
- else if(tokenstart>=0 && tokenend>=0)
- {
- name = hdr.substring(tokenstart, tokenend+1);
- }
-
- tokenstart = -1;
- break;
-
case '=':
if (quoted)
{
@@ -291,98 +322,29 @@ public class CookieCutter
unquoted.setLength(0);
quoted = false;
}
- else if(tokenstart>=0 && tokenend>=0)
- {
- name = hdr.substring(tokenstart, tokenend+1);
- }
+ else if(tokenstart>=0)
+ name = tokenend>=tokenstart?hdr.substring(tokenstart, tokenend+1):hdr.substring(tokenstart);
+
tokenstart = -1;
- invalue=true;
+ invalue = true;
break;
default:
if (quoted)
{
// must have been a bad internal quote. let's fix as best we can
- unquoted.append(hdr.substring(tokenstart,i));
+ unquoted.append(hdr,tokenstart,i--);
inQuoted = true;
quoted = false;
- i--;
continue;
}
if (tokenstart<0)
tokenstart=i;
tokenend=i;
- if (i==last)
- break;
continue;
}
}
}
-
- if (invalue && i==last && value==null)
- {
- if (quoted)
- {
- value = unquoted.toString();
- unquoted.setLength(0);
- quoted = false;
- }
- else if(tokenstart>=0 && tokenend>=0)
- {
- value = hdr.substring(tokenstart, tokenend+1);
- }
- else
- value = "";
- }
-
- // If after processing the current character we have a value and a name, then it is a cookie
- if (name!=null && value!=null)
- {
- try
- {
- if (name.startsWith("$"))
- {
- String lowercaseName = name.toLowerCase(Locale.ENGLISH);
- if (_compliance==CookieCompliance.RFC6265)
- {
- // Ignore
- }
- else if ("$path".equals(lowercaseName))
- {
- if (cookie!=null)
- cookie.setPath(value);
- }
- else if ("$domain".equals(lowercaseName))
- {
- if (cookie!=null)
- cookie.setDomain(value);
- }
- else if ("$port".equals(lowercaseName))
- {
- if (cookie!=null)
- cookie.setComment("$port="+value);
- }
- else if ("$version".equals(lowercaseName))
- {
- version = Integer.parseInt(value);
- }
- }
- else
- {
- cookie = new Cookie(name, value);
- if (version > 0)
- cookie.setVersion(version);
- cookies.add(cookie);
- }
- }
- catch (Exception e)
- {
- LOG.debug(e);
- }
-
- name = null;
- value = null;
- }
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
index ac5198063a5..b13d1cc0c16 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
@@ -764,12 +764,15 @@ public class Request implements HttpServletRequest
}
_cookiesExtracted = true;
-
- for (String c : metadata.getFields().getValuesList(HttpHeader.COOKIE))
+
+ for (HttpField field : metadata.getFields())
{
- if (_cookies == null)
- _cookies = new CookieCutter(getHttpChannel().getHttpConfiguration().getCookieCompliance());
- _cookies.addCookieField(c);
+ if (field.getHeader()==HttpHeader.COOKIE)
+ {
+ if (_cookies==null)
+ _cookies = new CookieCutter(getHttpChannel().getHttpConfiguration().getCookieCompliance());
+ _cookies.addCookieField(field.getValue());
+ }
}
//Javadoc for Request.getCookies() stipulates null for no cookies
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterTest.java
index 69962f57967..8419d9462f5 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutterTest.java
@@ -139,17 +139,22 @@ public class CookieCutterTest
* Example from RFC2965
*/
@Test
- @Disabled("comma separation no longer supported by new RFC6265")
public void testRFC2965_CookieSpoofingExample()
{
String rawCookie = "$Version=\"1\"; session_id=\"1234\", " +
"$Version=\"1\"; session_id=\"1111\"; $Domain=\".cracker.edu\"";
-
- Cookie cookies[] = parseCookieHeaders(CookieCompliance.RFC6265,rawCookie);
-
+
+
+ Cookie cookies[] = parseCookieHeaders(CookieCompliance.RFC2965,rawCookie);
+
assertThat("Cookies.length", cookies.length, is(2));
assertCookie("Cookies[0]", cookies[0], "session_id", "1234", 1, null);
assertCookie("Cookies[1]", cookies[1], "session_id", "1111", 1, null);
+
+ cookies = parseCookieHeaders(CookieCompliance.RFC6265,rawCookie);
+ assertThat("Cookies.length", cookies.length, is(2));
+ assertCookie("Cookies[0]", cookies[0], "session_id", "1234\", $Version=\"1", 0, null);
+ assertCookie("Cookies[1]", cookies[1], "session_id", "1111", 0, null);
}
/**
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutter_LenientTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutter_LenientTest.java
index e22f3961a06..906a0a22b06 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutter_LenientTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCutter_LenientTest.java
@@ -144,7 +144,12 @@ public class CookieCutter_LenientTest
Arguments.of("GAPS=1:A1aaaAaAA1aaAAAaa1a11a:aAaaAa-aaA1-", "GAPS", "1:A1aaaAaAA1aaAAAaa1a11a:aAaaAa-aaA1-"),
// Strong abuse of cookie spec (lots of tspecials)
- Arguments.of("$Version=0; rToken=F_TOKEN''!--\"=&{()}", "rToken", "F_TOKEN''!--\"=&{()}")
+ Arguments.of("$Version=0; rToken=F_TOKEN''!--\"=&{()}", "rToken", "F_TOKEN''!--\"=&{()}"),
+
+ // Commas that were not commas
+ Arguments.of("name=foo,bar","name","foo,bar"),
+ Arguments.of("name=foo , bar","name","foo , bar"),
+ Arguments.of("name=foo , bar, bob","name","foo , bar, bob")
);
}
From 7b8bda80705ad0f61e4d9a7869b9088f590a4316 Mon Sep 17 00:00:00 2001
From: Joakim Erdfelt
Date: Thu, 1 Nov 2018 10:13:16 -0500
Subject: [PATCH 114/931] Issue #3051 - New Simplified Jenkinsfile
Signed-off-by: Joakim Erdfelt
---
Jenkinsfile | 182 ++++++++++++++++++----------------------------------
1 file changed, 61 insertions(+), 121 deletions(-)
diff --git a/Jenkinsfile b/Jenkinsfile
index 9ad5fa93007..b7a4e84d8e8 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,19 +1,18 @@
#!groovy
-// in case of change update method isMainBuild
-def jdks = ["jdk8","jdk9","jdk10","jdk11"]
+def mainJdk = "jdk8"
+def jdks = [mainJdk, "jdk9", "jdk10", "jdk11"]
def oss = ["linux"]
def builds = [:]
for (def os in oss) {
for (def jdk in jdks) {
- builds[os+"_"+jdk] = getFullBuild( jdk, os )
+ builds[os+"_"+jdk] = getFullBuild( jdk, os, mainJdk == jdk )
}
}
parallel builds
-
-def getFullBuild(jdk, os) {
+def getFullBuild(jdk, os, mainJdk) {
return {
node(os) {
// System Dependent Locations
@@ -22,70 +21,10 @@ def getFullBuild(jdk, os) {
def settingsName = 'oss-settings.xml'
def mavenOpts = '-Xms1g -Xmx4g -Djava.awt.headless=true'
- try {
- stage("Build ${jdk}/${os}") {
- timeout(time: 90, unit: 'MINUTES') {
- // Run test phase / ignore test failures
- checkout scm
- withMaven(
- maven: mvnName,
- jdk: "$jdk",
- publisherStrategy: 'EXPLICIT',
- globalMavenSettingsConfig: settingsName,
- //options: [invokerPublisher(disabled: false)],
- mavenOpts: mavenOpts,
- mavenLocalRepo: localRepo) {
- sh "mvn -V -B install -Dmaven.test.failure.ignore=true -e -Pmongodb -T3 -Djetty.testtracker.log=true -Dunix.socket.tmp="+env.JENKINS_HOME
- sh "mvn -V -B javadoc:javadoc -T6 -e"
- }
- // withMaven doesn't label..
- // Report failures in the jenkins UI
- junit testResults:'**/target/surefire-reports/TEST-*.xml,**/target/failsafe-reports/TEST-*.xml'
- consoleParsers = [[parserName: 'JavaDoc'],
- [parserName: 'JavaC']];
- if (isMainBuild( jdk )) {
- // Collect up the jacoco execution results
- def jacocoExcludes =
- // build tools
- "**/org/eclipse/jetty/ant/**" + ",**/org/eclipse/jetty/maven/**" +
- ",**/org/eclipse/jetty/jspc/**" +
- // example code / documentation
- ",**/org/eclipse/jetty/embedded/**" + ",**/org/eclipse/jetty/asyncrest/**" +
- ",**/org/eclipse/jetty/demo/**" +
- // special environments / late integrations
- ",**/org/eclipse/jetty/gcloud/**" + ",**/org/eclipse/jetty/infinispan/**" +
- ",**/org/eclipse/jetty/osgi/**" + ",**/org/eclipse/jetty/spring/**" +
- ",**/org/eclipse/jetty/http/spi/**" +
- // test classes
- ",**/org/eclipse/jetty/tests/**" + ",**/org/eclipse/jetty/test/**";
- jacoco inclusionPattern: '**/org/eclipse/jetty/**/*.class',
- exclusionPattern: jacocoExcludes,
- execPattern : '**/target/jacoco.exec',
- classPattern : '**/target/classes',
- sourcePattern : '**/src/main/java'
- consoleParsers = [[parserName: 'Maven'],
- [parserName: 'JavaDoc'],
- [parserName: 'JavaC']];
- step([$class: 'MavenInvokerRecorder', reportsFilenamePattern: "**/target/invoker-reports/BUILD*.xml",
- invokerBuildDir: "**/target/its"])
- }
-
- // Report on Maven and Javadoc warnings
- step( [$class : 'WarningsPublisher',
- consoleParsers: consoleParsers] )
- }
- if(isUnstable()) {
- notifyBuild("Unstable / Test Errors", jdk)
- }
- }
- } catch(Exception e) {
- notifyBuild("Test Failure", jdk)
- throw e
- }
-
- try
- {
- stage ("Compact3 - ${jdk}") {
+ stage("Build / Test - $jdk") {
+ timeout(time: 120, unit: 'MINUTES') {
+ // Checkout
+ checkout scm
withMaven(
maven: mvnName,
jdk: "$jdk",
@@ -93,63 +32,64 @@ def getFullBuild(jdk, os) {
globalMavenSettingsConfig: settingsName,
mavenOpts: mavenOpts,
mavenLocalRepo: localRepo) {
- sh "mvn -f aggregates/jetty-all-compact3 -V -B -Pcompact3 clean install -T6"
+ // Testing
+ sh "mvn -V -B install -Dmaven.test.failure.ignore=true -T5 -e -Djetty.testtracker.log=true -Pmongodb -Dunix.socket.tmp=" + env.JENKINS_HOME
+ // Javadoc only
+ sh "mvn -V -B javadoc:javadoc -T6 -e -Dmaven.test.failure.ignore=false"
}
}
- } catch(Exception e) {
- notifyBuild("Compact3 Failure", jdk)
- throw e
+
+ // Report failures in the jenkins UI
+ junit testResults: '**/target/surefire-reports/TEST-*.xml,**/target/failsafe-reports/TEST-*.xml'
+ consoleParsers = [[parserName: 'JavaDoc'],
+ [parserName: 'JavaC']]
+
+ if (mainJdk) {
+ // Collect up the jacoco execution results
+ def jacocoExcludes =
+ // build tools
+ "**/org/eclipse/jetty/ant/**" + ",**/org/eclipse/jetty/maven/**" +
+ ",**/org/eclipse/jetty/jspc/**" +
+ // example code / documentation
+ ",**/org/eclipse/jetty/embedded/**" + ",**/org/eclipse/jetty/asyncrest/**" +
+ ",**/org/eclipse/jetty/demo/**" +
+ // special environments / late integrations
+ ",**/org/eclipse/jetty/gcloud/**" + ",**/org/eclipse/jetty/infinispan/**" +
+ ",**/org/eclipse/jetty/osgi/**" + ",**/org/eclipse/jetty/spring/**" +
+ ",**/org/eclipse/jetty/http/spi/**" +
+ // test classes
+ ",**/org/eclipse/jetty/tests/**" + ",**/org/eclipse/jetty/test/**"
+ jacoco inclusionPattern: '**/org/eclipse/jetty/**/*.class',
+ exclusionPattern: jacocoExcludes,
+ execPattern: '**/target/jacoco.exec',
+ classPattern: '**/target/classes',
+ sourcePattern: '**/src/main/java'
+ consoleParsers = [[parserName: 'Maven'],
+ [parserName: 'JavaDoc'],
+ [parserName: 'JavaC']]
+
+ step([$class: 'MavenInvokerRecorder', reportsFilenamePattern: "**/target/invoker-reports/BUILD*.xml",
+ invokerBuildDir: "**/target/its"])
+ }
+
+ // Report on Maven and Javadoc warnings
+ step([$class : 'WarningsPublisher',
+ consoleParsers: consoleParsers])
}
+ stage ("Compact3 - ${jdk}") {
+ withMaven(
+ maven: mvnName,
+ jdk: "$jdk",
+ publisherStrategy: 'EXPLICIT',
+ globalMavenSettingsConfig: settingsName,
+ mavenOpts: mavenOpts,
+ mavenLocalRepo: localRepo) {
+ sh "mvn -f aggregates/jetty-all-compact3 -V -B -Pcompact3 clean install -T6"
+ }
+ }
}
}
}
-def isMainBuild(jdk) {
- return jdk == "jdk8"
-}
-
-
-// True if this build is part of the "active" branches
-// for Jetty.
-def isActiveBranch() {
- def branchName = "${env.BRANCH_NAME}"
- return ( branchName == "master" ||
- ( branchName.startsWith("jetty-") && branchName.endsWith(".x") ) );
-}
-
-// Test if the Jenkins Pipeline or Step has marked the
-// current build as unstable
-def isUnstable() {
- return currentBuild.result == "UNSTABLE"
-}
-
-// Send a notification about the build status
-def notifyBuild(String buildStatus, String jdk) {
- if ( !isActiveBranch() ) {
- // don't send notifications on transient branches
- return
- }
-
- // default the value
- buildStatus = buildStatus ?: "UNKNOWN"
-
- def email = "${env.EMAILADDRESS}"
- def summary = "${env.JOB_NAME}#${env.BUILD_NUMBER} - ${buildStatus} with jdk ${jdk}"
- def detail = """
+ list.setHandlers(new Handler[] { param, new GzipHandler() });
+ handlers.setHandlers(new Handler[] { list, dft });
server.setHandler(handlers);
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/ServerProxyImpl.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/ServerProxyImpl.java
index 2dd2fdb9ee0..ac62bfc280a 100644
--- a/jetty-ant/src/main/java/org/eclipse/jetty/ant/ServerProxyImpl.java
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/ServerProxyImpl.java
@@ -40,7 +40,6 @@ import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
-import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.xml.XmlConfiguration;
@@ -407,9 +406,8 @@ public class ServerProxyImpl implements ServerProxy
*/
private void configureHandlers()
{
- RequestLogHandler requestLogHandler = new RequestLogHandler();
if (requestLog != null)
- requestLogHandler.setRequestLog(requestLog);
+ server.setRequestLog(requestLog);
contexts = (ContextHandlerCollection) server
.getChildHandlerByClass(ContextHandlerCollection.class);
@@ -422,8 +420,7 @@ public class ServerProxyImpl implements ServerProxy
{
handlers = new HandlerCollection();
server.setHandler(handlers);
- handlers.setHandlers(new Handler[] { contexts, new DefaultHandler(),
- requestLogHandler });
+ handlers.setHandlers(new Handler[] { contexts, new DefaultHandler() });
}
else
{
diff --git a/jetty-jmh/src/main/java/org/eclipse/jetty/requestlog/jmh/RequestLogBenchmark.java b/jetty-jmh/src/main/java/org/eclipse/jetty/requestlog/jmh/RequestLogBenchmark.java
new file mode 100644
index 00000000000..9092a5fca6f
--- /dev/null
+++ b/jetty-jmh/src/main/java/org/eclipse/jetty/requestlog/jmh/RequestLogBenchmark.java
@@ -0,0 +1,222 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2018 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.requestlog.jmh;
+
+import static java.lang.invoke.MethodHandles.dropArguments;
+import static java.lang.invoke.MethodHandles.foldArguments;
+import static java.lang.invoke.MethodType.methodType;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.util.TypeUtil;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.profile.GCProfiler;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+
+
+@State(Scope.Benchmark)
+@Threads(4)
+@Warmup(iterations = 7, time = 500, timeUnit = TimeUnit.MILLISECONDS)
+@Measurement(iterations = 7, time = 500, timeUnit = TimeUnit.MILLISECONDS)
+public class RequestLogBenchmark
+{
+
+ public static void append(String s, StringBuilder b)
+ {
+ b.append(s);
+ }
+
+ public static void logURI(StringBuilder b, String request)
+ {
+ b.append(request);
+ }
+
+ public static void logLength(StringBuilder b, String request)
+ {
+ b.append(request.length());
+ }
+
+ public static void logAddr(StringBuilder b, String request)
+ {
+ try
+ {
+ TypeUtil.toHex(request.hashCode(), b);
+ }
+ catch(Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private ThreadLocal buffers = new ThreadLocal()
+ {
+ @Override
+ protected StringBuilder initialValue()
+ {
+ return new StringBuilder(256);
+ }
+ };
+ MethodHandle logHandle;
+ Object[] iteratedLog;
+
+ public RequestLogBenchmark()
+ {
+ try
+ {
+ MethodType logType = methodType(Void.TYPE, StringBuilder.class, String.class);
+
+ MethodHandle append = MethodHandles.lookup()
+ .findStatic(RequestLogBenchmark.class, "append", methodType(Void.TYPE, String.class, StringBuilder.class));
+ MethodHandle logURI = MethodHandles.lookup().findStatic(RequestLogBenchmark.class, "logURI", logType);
+ MethodHandle logAddr = MethodHandles.lookup().findStatic(RequestLogBenchmark.class, "logAddr", logType);
+ MethodHandle logLength = MethodHandles.lookup().findStatic(RequestLogBenchmark.class, "logLength", logType);
+
+ // setup iteration
+ iteratedLog = new Object[]
+ {
+ logURI,
+ " - ",
+ logAddr,
+ " ",
+ logLength,
+ "\n"
+ };
+
+ // setup methodHandle
+ logHandle = dropArguments(append.bindTo("\n"), 1, String.class);
+ logHandle = foldArguments(logHandle, logLength);
+ logHandle = foldArguments(logHandle, dropArguments(append.bindTo(" "), 1, String.class));
+ logHandle = foldArguments(logHandle, logAddr);
+ logHandle = foldArguments(logHandle, dropArguments(append.bindTo(" - "), 1, String.class));
+ logHandle = foldArguments(logHandle, logURI);
+
+ }
+ catch (Throwable th)
+ {
+ throw new RuntimeException(th);
+ }
+ }
+
+
+ public String logFixed(String request)
+ {
+ StringBuilder b = buffers.get();
+ logURI(b,request);
+ append(" - ",b);
+ logAddr(b,request);
+ append(" ",b);
+ logLength(b,request);
+ append("\n",b);
+ String l = b.toString();
+ b.setLength(0);
+ return l;
+ }
+
+ public String logIterate(String request)
+ {
+ try
+ {
+
+ StringBuilder b = buffers.get();
+ for (Object o : iteratedLog)
+ {
+ if (o instanceof String)
+ append((String)o, b);
+ else if (o instanceof MethodHandle)
+ ((MethodHandle)o).invoke(b, request);
+ }
+ String l = b.toString();
+ b.setLength(0);
+ return l;
+ }
+ catch(Throwable th)
+ {
+ throw new RuntimeException(th);
+ }
+ }
+
+ public String logMethodHandle(String request)
+ {
+ try
+ {
+ StringBuilder b = buffers.get();
+ logHandle.invoke(buffers.get(), request);
+ String l = b.toString();
+ b.setLength(0);
+ return l;
+ }
+ catch (Throwable th)
+ {
+ throw new RuntimeException(th);
+ }
+ }
+
+
+ @Benchmark
+ @BenchmarkMode({ Mode.Throughput})
+ public String testFixed()
+ {
+ return logFixed(Long.toString(ThreadLocalRandom.current().nextLong()));
+ };
+
+ @Benchmark
+ @BenchmarkMode({ Mode.Throughput})
+ public String testIterate()
+ {
+ return logIterate(Long.toString(ThreadLocalRandom.current().nextLong()));
+ };
+
+ @Benchmark
+ @BenchmarkMode({ Mode.Throughput})
+ public String testHandle()
+ {
+ return logMethodHandle(Long.toString(ThreadLocalRandom.current().nextLong()));
+ };
+
+
+ public static void main(String[] args) throws RunnerException
+ {
+ Options opt = new OptionsBuilder()
+ .include(RequestLogBenchmark.class.getSimpleName())
+ .warmupIterations(20)
+ .measurementIterations(10)
+ .addProfiler(GCProfiler.class)
+ .forks(1)
+ .threads(100)
+ .build();
+
+ new Runner(opt).run();
+ }
+
+}
diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerSupport.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerSupport.java
index 36eab2e0418..00c8e6c9c4c 100644
--- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerSupport.java
+++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerSupport.java
@@ -33,7 +33,6 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
-import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
@@ -69,9 +68,8 @@ public class ServerSupport
throw new IllegalArgumentException ("Server is null");
DefaultHandler defaultHandler = new DefaultHandler();
- RequestLogHandler requestLogHandler = new RequestLogHandler();
if (requestLog != null)
- requestLogHandler.setRequestLog(requestLog);
+ server.setRequestLog(requestLog);
ContextHandlerCollection contexts = findContextHandlerCollection(server);
if (contexts == null)
@@ -82,7 +80,7 @@ public class ServerSupport
{
handlers = new HandlerCollection();
server.setHandler(handlers);
- handlers.setHandlers(new Handler[]{contexts, defaultHandler, requestLogHandler});
+ handlers.setHandlers(new Handler[]{contexts, defaultHandler});
}
else
{
diff --git a/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java b/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java
index 12fe3a27ca6..9348f82858f 100644
--- a/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java
+++ b/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java
@@ -43,7 +43,6 @@ import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
-import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.server.handler.StatisticsHandler;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
@@ -88,7 +87,6 @@ public class Runner
protected URLClassLoader _classLoader;
protected Classpath _classpath = new Classpath();
protected ContextHandlerCollection _contexts;
- protected RequestLogHandler _logHandler;
protected String _logFile;
protected ArrayList _configFiles;
protected boolean _enableStats=false;
@@ -392,14 +390,6 @@ public class Runner
handlers.addHandler(new DefaultHandler());
}
- //ensure a log handler is present
- _logHandler = (RequestLogHandler) handlers.getChildHandlerByClass(RequestLogHandler.class);
- if (_logHandler == null)
- {
- _logHandler = new RequestLogHandler();
- handlers.addHandler(_logHandler);
- }
-
//check a connector is configured to listen on
Connector[] connectors = _server.getConnectors();
@@ -509,7 +499,7 @@ public class Runner
{
NCSARequestLog requestLog = new NCSARequestLog(_logFile);
requestLog.setExtended(false);
- _logHandler.setRequestLog(requestLog);
+ _server.setRequestLog(requestLog);
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java
index 43ab02dc183..95012aee8b5 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java
@@ -888,7 +888,6 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
@Override
public void write(ByteBuffer content, boolean complete, Callback callback)
{
- _written+=BufferUtil.length(content);
sendResponse(null,content,complete,callback);
}
@@ -1226,18 +1225,21 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
private class CommitCallback extends Callback.Nested
{
private final ByteBuffer _content;
+ private final int _length;
private final boolean _complete;
private CommitCallback(Callback callback, ByteBuffer content, boolean complete)
{
super(callback);
- this._content = content == null ? BufferUtil.EMPTY_BUFFER : content.slice();
- this._complete = complete;
+ _content = content == null ? BufferUtil.EMPTY_BUFFER : content.slice();
+ _length = _content.remaining();
+ _complete = complete;
}
@Override
public void succeeded()
{
+ _written += _length;
super.succeeded();
notifyResponseCommit(_request);
if (_content.hasRemaining())
@@ -1299,18 +1301,21 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
private class ContentCallback extends Callback.Nested
{
private final ByteBuffer _content;
+ private final int _length;
private final boolean _complete;
private ContentCallback(Callback callback, ByteBuffer content, boolean complete)
{
super(callback);
- this._content = content == null ? BufferUtil.EMPTY_BUFFER : content.slice();
- this._complete = complete;
+ _content = content == null ? BufferUtil.EMPTY_BUFFER : content.slice();
+ _length = _content.remaining();
+ _complete = complete;
}
@Override
public void succeeded()
{
+ _written += _length;
super.succeeded();
if (_content.hasRemaining())
notifyResponseContent(_request, _content);
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
index 28f6d2622e1..d4592a72607 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
@@ -286,7 +286,12 @@ public class HttpInput extends ServletInputStream implements Runnable
{
long minimum_data = minRequestDataRate * TimeUnit.NANOSECONDS.toMillis(period) / TimeUnit.SECONDS.toMillis(1);
if (_contentArrived < minimum_data)
- throw new BadMessageException(HttpStatus.REQUEST_TIMEOUT_408,String.format("Request content data rate < %d B/s",minRequestDataRate));
+ {
+ BadMessageException bad = new BadMessageException(HttpStatus.REQUEST_TIMEOUT_408,
+ String.format("Request content data rate < %d B/s", minRequestDataRate));
+ _channelState.getHttpChannel().abort(bad);
+ throw bad;
+ }
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
index 6fcd6370435..4402d193a93 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
@@ -25,6 +25,7 @@ import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritePendingException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
+
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
@@ -934,7 +935,11 @@ public class HttpOutput extends ServletOutputStream implements Runnable
if (LOG.isDebugEnabled())
LOG.debug("Flushed bytes min/actual {}/{}", minFlushed, _flushed);
if (_flushed < minFlushed)
- throw new IOException(String.format("Response content data rate < %d B/s", minDataRate));
+ {
+ IOException ioe = new IOException(String.format("Response content data rate < %d B/s", minDataRate));
+ _channel.abort(ioe);
+ throw ioe;
+ }
}
public void recycle()
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java
index 838d3323422..e30764a2e92 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java
@@ -31,11 +31,11 @@ import org.eclipse.jetty.server.Server;
/**
- * RequestLogHandler.
- * This handler can be used to wrap an individual context for context logging.
- * To set a {@link RequestLog} instance for the entire {@link Server}, use
- * {@link Server#setRequestLog(RequestLog)} instead of this handler.
- *
+ *
This handler provides an alternate way (other than {@link Server#setRequestLog(RequestLog)})
+ * to log request, that can be applied to a particular handler (eg context).
+ * This handler can be used to wrap an individual context for context logging, or can be listed
+ * prior to a handler.
+ *
* @see Server#setRequestLog(RequestLog)
*/
public class RequestLogHandler extends HandlerWrapper
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/BadRequestLogHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/BadRequestLogHandlerTest.java
deleted file mode 100644
index 1c54de4ca0a..00000000000
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/BadRequestLogHandlerTest.java
+++ /dev/null
@@ -1,194 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2018 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.server.handler;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.nio.charset.StandardCharsets;
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Stream;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.RequestLog;
-import org.eclipse.jetty.server.Response;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.util.IO;
-import org.eclipse.jetty.util.component.AbstractLifeCycle;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Tag;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.MethodSource;
-
-/**
- * Testing oddball request scenarios (like error 400) where the error should
- * be logged
- */
-@Tag("Unstable")
-@Disabled
-public class BadRequestLogHandlerTest
-{
- private static final Logger LOG = Log.getLogger(BadRequestLogHandlerTest.class);
-
- public static class CaptureLog extends AbstractLifeCycle implements RequestLog
- {
- public List captured = new ArrayList<>();
-
- @Override
- public void log(Request request, Response response)
- {
- int status = response.getCommittedMetaData().getStatus();
- captured.add(String.format("%s %s %s %03d",request.getMethod(),request.getHttpURI(),request.getProtocol(),status));
- }
- }
-
- private static class HelloHandler extends AbstractHandler
- {
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- response.setContentType("text/plain");
- response.getWriter().print("Hello World");
- baseRequest.setHandled(true);
- }
- }
-
- public static Stream data()
- {
- List
From 3995cd2ec0ffb6f756507ad99295bfced287ba0b Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Fri, 2 Nov 2018 16:38:43 +0100
Subject: [PATCH 123/931] Issue #3023 redirect to / when pathInfoOnly (#3047)
Issue #3023 redirect to / when pathInfoOnly (#3047)
---
.../org/eclipse/jetty/server/ResourceService.java | 4 ++--
.../eclipse/jetty/servlet/DefaultServletTest.java | 14 ++++++++++++++
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceService.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceService.java
index 4a3dde749a7..58823b77edb 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceService.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceService.java
@@ -226,7 +226,7 @@ public class ResourceService
String pathInContext=URIUtil.addPaths(servletPath,pathInfo);
- boolean endsWithSlash=(pathInfo==null?servletPath:pathInfo).endsWith(URIUtil.SLASH);
+ boolean endsWithSlash=(pathInfo==null?(_pathInfoOnly?"":servletPath):pathInfo).endsWith(URIUtil.SLASH);
boolean checkPrecompressedVariants=_precompressedFormats.length > 0 && !endsWithSlash && !included && reqRanges==null;
HttpContent content=null;
@@ -373,7 +373,7 @@ public class ResourceService
throws ServletException, IOException
{
// Redirect to directory
- if (!endsWithSlash || (pathInContext.length()==1 && request.getAttribute("org.eclipse.jetty.server.nullPathInfo")!=null))
+ if (!endsWithSlash)
{
StringBuffer buf=request.getRequestURL();
synchronized(buf)
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java
index ab861d0bb7c..e78fbd65e08 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java
@@ -555,6 +555,14 @@ public class DefaultServletTest
altholder.setInitParameter("welcomeServlets", "false");
altholder.setInitParameter("gzip", "false");
+ ServletHolder otherholder = context.addServlet(DefaultServlet.class, "/other/*");
+ otherholder.setInitParameter("resourceBase", altRoot.toUri().toASCIIString());
+ otherholder.setInitParameter("pathInfoOnly", "true");
+ otherholder.setInitParameter("dirAllowed", "true");
+ otherholder.setInitParameter("redirectWelcome", "false");
+ otherholder.setInitParameter("welcomeServlets", "false");
+ otherholder.setInitParameter("gzip", "false");
+
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
defholder.setInitParameter("dirAllowed", "false");
defholder.setInitParameter("redirectWelcome", "false");
@@ -567,6 +575,12 @@ public class DefaultServletTest
String rawResponse;
HttpTester.Response response;
+ // Test other redirect
+ rawResponse = connector.getResponse("GET /context/other HTTP/1.0\r\n\r\n");
+ response = HttpTester.parseResponse(rawResponse);
+ assertThat(response.toString(), response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
+ assertThat(response, containsHeaderValue("Location", "http://0.0.0.0/context/other/"));
+
// Test alt default
rawResponse = connector.getResponse("GET /context/alt/dir/ HTTP/1.0\r\n\r\n");
response = HttpTester.parseResponse(rawResponse);
From 5a17a33045ee5865314889b2c3695bdd2ec0e497 Mon Sep 17 00:00:00 2001
From: Joakim Erdfelt
Date: Fri, 2 Nov 2018 11:34:05 -0500
Subject: [PATCH 124/931] Fixed #2458 - Removing jdk9 and jdk10 CI builds
Signed-off-by: Joakim Erdfelt
---
Jenkinsfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Jenkinsfile b/Jenkinsfile
index b7a4e84d8e8..09071967d8d 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,7 +1,7 @@
#!groovy
def mainJdk = "jdk8"
-def jdks = [mainJdk, "jdk9", "jdk10", "jdk11"]
+def jdks = [mainJdk, "jdk11"]
def oss = ["linux"]
def builds = [:]
for (def os in oss) {
From 4a9265d4b402b45a14fb96b97eb86b0b18b5c187 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Sat, 3 Nov 2018 17:53:32 +0100
Subject: [PATCH 125/931] backports from 10.0.x websocket refactor
Signed-off-by: Greg Wilkins
---
.../java/org/eclipse/jetty/client/HttpClient.java | 3 ++-
.../java/org/eclipse/jetty/io/ChannelEndPoint.java | 13 ++++++-------
.../org/eclipse/jetty/util/IteratingCallback.java | 10 +++++-----
3 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
index 308e79daf6c..e22b3dc7194 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
@@ -212,8 +212,8 @@ public class HttpClient extends ContainerLifeCycle
QueuedThreadPool threadPool = new QueuedThreadPool();
threadPool.setName(name);
executor = threadPool;
+ addBean(executor);
}
- addBean(executor);
if (byteBufferPool == null)
byteBufferPool = new MappedByteBufferPool(2048,
@@ -796,6 +796,7 @@ public class HttpClient extends ContainerLifeCycle
*/
public void setExecutor(Executor executor)
{
+ updateBean(this.executor, executor);
this.executor = executor;
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ChannelEndPoint.java
index ed6a761c041..0421176298f 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ChannelEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ChannelEndPoint.java
@@ -229,29 +229,28 @@ public abstract class ChannelEndPoint extends AbstractEndPoint implements Manage
return -1;
int pos=BufferUtil.flipToFill(buffer);
+ int filled;
try
{
- int filled = _channel.read(buffer);
- if (LOG.isDebugEnabled()) // Avoid boxing of variable 'filled'
- LOG.debug("filled {} {}", filled, this);
-
+ filled = _channel.read(buffer);
if (filled>0)
notIdle();
else if (filled==-1)
shutdownInput();
-
- return filled;
}
catch(IOException e)
{
LOG.debug(e);
shutdownInput();
- return -1;
+ filled = -1;
}
finally
{
BufferUtil.flipToFlush(buffer,pos);
}
+ if (LOG.isDebugEnabled())
+ LOG.debug("filled {} {}", filled, BufferUtil.toDetailString(buffer));
+ return filled;
}
@Override
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/IteratingCallback.java b/jetty-util/src/main/java/org/eclipse/jetty/util/IteratingCallback.java
index 4fb91db63ec..bdbfc5f9db1 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/IteratingCallback.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/IteratingCallback.java
@@ -18,7 +18,7 @@
package org.eclipse.jetty.util;
-import java.nio.channels.ClosedChannelException;
+import java.io.IOException;
import org.eclipse.jetty.util.thread.Locker;
@@ -403,7 +403,7 @@ public abstract class IteratingCallback implements Callback
public void close()
{
- boolean failure=false;
+ String failure=null;
try(Locker.Lock lock = _locker.lock())
{
switch (_state)
@@ -418,13 +418,13 @@ public abstract class IteratingCallback implements Callback
break;
default:
+ failure=String.format("Close %s in state %s",this,_state);
_state=State.CLOSED;
- failure=true;
}
}
- if(failure)
- onCompleteFailure(new ClosedChannelException());
+ if(failure!=null)
+ onCompleteFailure(new IOException(failure));
}
/*
From 67cef441b21ffc900ad5fb112cbd43434d281760 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Mon, 5 Nov 2018 14:05:02 +0100
Subject: [PATCH 126/931] Support direct buffers in hpack (#3058)
Signed-off-by: Greg Wilkins
---
.../eclipse/jetty/http2/hpack/Huffman.java | 30 +---
.../eclipse/jetty/http2/hpack/HpackTest.java | 9 +-
.../jetty/http2/hpack/HuffmanTest.java | 3 +-
.../jetty/io/jmh/ByteBufferBenchmark.java | 154 ++++++++++++++++++
4 files changed, 169 insertions(+), 27 deletions(-)
create mode 100644 jetty-jmh/src/main/java/org/eclipse/jetty/io/jmh/ByteBufferBenchmark.java
diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java
index ddb2c4a97df..a0ed7b538e1 100644
--- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java
+++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/Huffman.java
@@ -350,23 +350,16 @@ public class Huffman
return decode(buffer,buffer.remaining());
}
- public static String decode(ByteBuffer buffer,int length) throws HpackException.CompressionException
+ public static String decode(ByteBuffer buffer, int length) throws HpackException.CompressionException
{
StringBuilder out = new StringBuilder(length*2);
int node = 0;
int current = 0;
int bits = 0;
- byte[] array = buffer.array();
- int position=buffer.position();
- int start=buffer.arrayOffset()+position;
- int end=start+length;
- buffer.position(position+length);
-
-
- for (int i=start; i= 8)
@@ -460,10 +453,6 @@ public class Huffman
{
long current = 0;
int n = 0;
-
- byte[] array = buffer.array();
- int p=buffer.arrayOffset()+buffer.position();
-
int len = s.length();
for (int i=0;i= 8)
{
n -= 8;
- array[p++]=(byte)(current >> n);
+ buffer.put((byte)(current >> n));
}
}
- if (n > 0)
+ if (n > 0)
{
- current <<= (8 - n);
- current |= (0xFF >>> n);
- array[p++]=(byte)current;
+ current <<= (8 - n);
+ current |= (0xFF >>> n);
+ buffer.put((byte)(current));
}
-
- buffer.position(p-buffer.arrayOffset());
+
}
}
diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java
index 355ffb2953f..5962fdfb65e 100644
--- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java
+++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java
@@ -19,10 +19,9 @@
package org.eclipse.jetty.http2.hpack;
import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
import java.nio.ByteBuffer;
@@ -51,7 +50,7 @@ public class HpackTest
{
HpackEncoder encoder = new HpackEncoder();
HpackDecoder decoder = new HpackDecoder(4096,8192);
- ByteBuffer buffer = BufferUtil.allocate(16*1024);
+ ByteBuffer buffer = BufferUtil.allocateDirect(16*1024);
HttpFields fields0 = new HttpFields();
fields0.add(HttpHeader.CONTENT_TYPE,"text/html");
@@ -104,7 +103,7 @@ public class HpackTest
{
HpackEncoder encoder = new HpackEncoder();
HpackDecoder decoder = new HpackDecoder(4096,164);
- ByteBuffer buffer = BufferUtil.allocate(16*1024);
+ ByteBuffer buffer = BufferUtil.allocateDirect(16*1024);
HttpFields fields0 = new HttpFields();
fields0.add("1234567890","1234567890123456789012345678901234567890");
@@ -144,7 +143,7 @@ public class HpackTest
{
HpackEncoder encoder = new HpackEncoder(200,200);
HpackDecoder decoder = new HpackDecoder(200,1024);
- ByteBuffer buffer = BufferUtil.allocate(16*1024);
+ ByteBuffer buffer = BufferUtil.allocateDirect(16*1024);
HttpFields fields0 = new HttpFields();
fields0.add("123456789012345678901234567890123456788901234567890","value");
diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java
index bf7a935458c..c909d383d54 100644
--- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java
+++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java
@@ -21,6 +21,7 @@ package org.eclipse.jetty.http2.hpack;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.util.Locale;
import java.util.stream.Stream;
@@ -79,7 +80,7 @@ public class HuffmanTest
assertThrows(IllegalArgumentException.class,
() -> Huffman.octetsNeeded(s));
- assertThrows(IllegalArgumentException.class,
+ assertThrows(BufferOverflowException.class,
() -> Huffman.encode(BufferUtil.allocate(32), s));
}
}
diff --git a/jetty-jmh/src/main/java/org/eclipse/jetty/io/jmh/ByteBufferBenchmark.java b/jetty-jmh/src/main/java/org/eclipse/jetty/io/jmh/ByteBufferBenchmark.java
new file mode 100644
index 00000000000..eb2ba3ec9b2
--- /dev/null
+++ b/jetty-jmh/src/main/java/org/eclipse/jetty/io/jmh/ByteBufferBenchmark.java
@@ -0,0 +1,154 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2018 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.io.jmh;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+
+@State(Scope.Benchmark)
+@Threads(4)
+@Warmup(iterations = 7, time = 500, timeUnit = TimeUnit.MILLISECONDS)
+@Measurement(iterations = 7, time = 500, timeUnit = TimeUnit.MILLISECONDS)
+public class ByteBufferBenchmark
+{
+ public long test(ByteBuffer buffer)
+ {
+ buffer.clear();
+ while(buffer.hasRemaining())
+ {
+ int size = ThreadLocalRandom.current().nextInt(1024);
+ byte[] bytes = new byte[size];
+ ThreadLocalRandom.current().nextBytes(bytes);
+ buffer.put(bytes,0,Math.min(bytes.length,buffer.remaining()));
+ }
+
+ buffer.flip();
+
+ long sum = 0;
+ while(buffer.hasRemaining())
+ sum += buffer.get();
+
+ return sum;
+ }
+
+
+ public long testArray(ByteBuffer buffer)
+ {
+ buffer.clear();
+ byte[] array = buffer.array();
+ int offset = buffer.arrayOffset();
+ int end = offset + buffer.remaining();
+ while(offset
Date: Tue, 6 Nov 2018 09:29:43 +0100
Subject: [PATCH 127/931] Issue #3060 WriteFlusher fails callback on all
Throwables
Signed-off-by: Greg Wilkins
---
jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java b/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java
index a2d9c8fa008..d567f45577d 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java
@@ -294,7 +294,7 @@ abstract public class WriteFlusher
else
fail(callback);
}
- catch (IOException e)
+ catch (Throwable e)
{
if (DEBUG)
LOG.debug("write exception", e);
@@ -366,7 +366,7 @@ abstract public class WriteFlusher
else
fail(callback);
}
- catch (IOException e)
+ catch (Throwable e)
{
if (DEBUG)
LOG.debug("completeWrite exception", e);
From 871f73cdf617063fae254268776a63715a80a977 Mon Sep 17 00:00:00 2001
From: Jan Bartel
Date: Tue, 6 Nov 2018 10:03:48 +0100
Subject: [PATCH 128/931] Jetty 9.4.x 2932 switchable classloader for session
attribute values (#2964)
---
.../session-configuration-infinispan.adoc | 41 ++++
.../session/GCloudSessionDataStore.java | 195 ++++++---------
.../session/HazelcastSessionDataStore.java | 48 ++--
.../HazelcastSessionDataStoreFactory.java | 14 +-
.../session/SessionDataSerializer.java | 110 +++++++++
jetty-infinispan/pom.xml | 17 ++
.../config/etc/sessions/infinispan/remote.xml | 61 ++++-
.../infinispan/InfinispanSessionData.java | 69 ++++++
.../InfinispanSessionDataStore.java | 137 +++++------
.../InfinispanSessionLegacyConverter.java | 224 +++++++++++++++++
.../infinispan/SessionDataMarshaller.java | 106 ++++++++
.../session/infinispan/WebAppMarshaller.java | 1 +
.../src/main/resources/session.proto | 19 ++
.../jetty-memcached-sessions/pom.xml | 2 +-
.../session-data-cache/xmemcached.mod | 2 +-
.../session/MemcachedSessionDataMap.java | 55 +++--
.../nosql/mongodb/MongoSessionDataStore.java | 232 ++++++++----------
.../authentication/SessionAuthentication.java | 20 +-
.../session/AbstractSessionDataStore.java | 119 +++++----
.../server/session/FileSessionDataStore.java | 160 ++++--------
.../server/session/JDBCSessionDataStore.java | 165 +++++--------
.../server/session/NullSessionDataStore.java | 28 +--
.../jetty/server/session/SessionData.java | 90 ++++++-
.../util/ClassLoadingObjectInputStream.java | 36 ++-
.../jetty/server/session/FileTestHelper.java | 41 +---
.../test-gcloud-sessions/pom.xml | 1 -
.../session/ClusteredOrphanedSessionTest.java | 8 +-
.../ClusteredSessionScavengingTest.java | 7 +-
.../session/GCloudSessionTestSupport.java | 67 ++---
.../session/InvalidationSessionTest.java | 6 +-
.../session/HazelcastTestHelper.java | 23 +-
.../test-infinispan-sessions/pom.xml | 10 +
.../remote/RemoteInfinispanTestSupport.java | 38 ++-
.../jetty/server/session/JdbcTestHelper.java | 33 +--
.../test-memcached-sessions/pom.xml | 6 +
.../sessions/MemcachedTestHelper.java | 22 +-
.../mongodb/MongoSessionDataStoreTest.java | 64 +++++
.../jetty/nosql/mongodb/MongoTestHelper.java | 113 ++++++---
.../server/session/TestSessionDataStore.java | 2 +-
.../session/DeleteUnloadableSessionTest.java | 26 +-
.../session/SessionEvictionFailureTest.java | 23 +-
.../src/main/java/com/acme/SessionDump.java | 5 +
42 files changed, 1562 insertions(+), 884 deletions(-)
create mode 100644 jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/SessionDataSerializer.java
create mode 100644 jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java
create mode 100644 jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionLegacyConverter.java
create mode 100644 jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java
create mode 100644 jetty-infinispan/src/main/resources/session.proto
diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-infinispan.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-infinispan.adoc
index 07528662522..67e99562104 100644
--- a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-infinispan.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-infinispan.adoc
@@ -179,3 +179,44 @@ In a clustered environment, there is a risk of the last access time of the sessi
This allows the possibility that a node may prematurely expire the session, even though it is in use by another node.
Thorough consideration of the `maxIdleTime` of the session when setting the `savePeriod` is imperative - there is no point in setting a `savePeriod` that is larger than the `maxIdleTime`.
____
+
+==== Converting session format for jetty-9.4.13
+
+From jetty-9.4.13 onwards, we have changed the format of the serialized session when using a remote cache (ie using hotrod).
+Prior to release 9.4.13 we used the default Infinispan serialization, however this was not able to store sufficient information to allow jetty to properly deserialize session attributes in all circumstances.
+See issue https://github.com/eclipse/jetty.project/issues/2919 for more background.
+
+We have provided a conversion program which will convert any sessions stored in Infinispan to the new format.
+____
+[IMPORTANT]
+We recommend that you backup your stored sessions before running the conversion program.
+____
+
+How to use the converter:
+
+[source, screen, subs="{sub-order}"]
+----
+java -cp servlet-api-3.1.jar:jetty-util-9.4.13.jar:jetty-server-9.4.13.jar:infinispan-remote-9.1.0.Final.jar:jetty-infinispan-9.4.13.jar:[other classpath] org.eclipse.jetty.session.infinispan.InfinispanSessionLegacyConverter
+
+Usage: InfinispanSessionLegacyConverter [-Dhost=127.0.0.1] [-Dverbose=true|false] [check]
+----
+
+The classpath::
+Must contain the servlet-api, jetty-util, jetty-server, jetty-infinispan and infinispan-remote jars. If your sessions contain attributes that use application classes, you will also need to also put those classes onto the classpath. If your session has been authenticated, you may also need to include the jetty-security and jetty-http jars on the classpath.
+Parameters::
+When used with no arguments the usage message is printed. When used with the `cache-name` parameter the conversion is performed. When used with both `cache-name` and `check` parameters, sessions are checked for whether or not they are converted.
+
+ -Dhost::: you can optionally provide a system property with the address of your remote Infinispan server. Defaults to the localhost.
+ -Dverbose::: defaults to false. If true, prints more comprehensive stacktrace information about failures. Useful to diagnose why a session is not converted.
+ cache-name::: the name of the remote cache containing your sessions. This is mandatory.
+ check::: the optional check command will verify sessions have been converted. Use it _after_ doing the conversion.
+
+To perform the conversion, run the InfinispanSessionLegacyConverter with just the `cache-name`, and optionally the `host` system property.
+The following command will attempt to convert all sessions in the cached named `my-remote-cache` on the machine `myhost`, ensuring that application classes in the `/my/custom/classes` directory are on the classpath:
+
+[source, screen, subs="{sub-order}"]
+----
+java -cp servlet-api-3.1.jar:jetty-util-9.4.13.jar:jetty-server-9.4.13.jar:infinispan-remote-9.1.0.Final.jar:jetty-infinispan-9.4.13.jar:/my/custom/classes org.eclipse.jetty.session.infinispan.InfinispanSessionLegacyConverter -Dhost=myhost my-remote-cache
+----
+
+If the converter fails to convert a session, an error message and stacktrace will be printed and the conversion will abort. The failed session should be untouched, however _it is prudent to take a backup of your cache before attempting the conversion_.
diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java
index c8a6f30fca6..cd85db19ccb 100644
--- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java
+++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java
@@ -22,9 +22,7 @@ package org.eclipse.jetty.gcloud.session;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.util.HashSet;
-import java.util.Map;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.server.session.AbstractSessionDataStore;
import org.eclipse.jetty.server.session.SessionContext;
@@ -324,18 +322,14 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
_lastSaved = lastSaved;
}
- /**
- * @see java.lang.Object#toString()
- */
+
@Override
public String toString()
{
return String.format("%s==%s:%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s",this.getClass().getName(),
_kind,_accessed,_attributes,_contextPath,_cookieSetTime,_createTime,_expiry,_id,_lastAccessed,_lastNode,_maxInactive,_vhost);
}
-
-
-
+
}
@@ -437,9 +431,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
return _maxRetries;
}
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStart()
- */
+
@Override
protected void doStart() throws Exception
{
@@ -466,9 +458,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
super.doStart();
}
- /**
- * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
- */
+
@Override
protected void doStop() throws Exception
{
@@ -501,12 +491,8 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
}
-
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#load(java.lang.String)
- */
@Override
- public SessionData load(String id) throws Exception
+ public SessionData doLoad(String id) throws Exception
{
if (LOG.isDebugEnabled()) LOG.debug("Loading session {} from DataStore", id);
@@ -529,9 +515,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
}
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String)
- */
+
@Override
public boolean delete(String id) throws Exception
{
@@ -540,9 +524,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
return true;
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
- */
+
@Override
public Set doGetExpired(Set candidates)
{
@@ -701,9 +683,6 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
- */
@Override
public boolean exists(String id) throws Exception
{
@@ -766,6 +745,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
}
}
+
/**
* Check to see if the given time is in the past.
*
@@ -780,9 +760,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
return timestamp < System.currentTimeMillis();
}
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
- */
+
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
{
@@ -874,6 +852,8 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
return false;
}
}
+
+
/**
* Generate a gcloud datastore Entity from SessionData
* @param session the session data
@@ -889,28 +869,27 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
Entity entity = null;
//serialize the attribute map
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(session.getAllAttributes());
- oos.flush();
-
- //turn a session into an entity
- entity = Entity.newBuilder(key)
- .set(_model.getId(), session.getId())
- .set(_model.getContextPath(), session.getContextPath())
- .set(_model.getVhost(), session.getVhost())
- .set(_model.getAccessed(), session.getAccessed())
- .set(_model.getLastAccessed(), session.getLastAccessed())
- .set(_model.getCreateTime(), session.getCreated())
- .set(_model.getCookieSetTime(), session.getCookieSet())
- .set(_model.getLastNode(),session.getLastNode())
- .set(_model.getExpiry(), session.getExpiry())
- .set(_model.getMaxInactive(), session.getMaxInactiveMs())
- .set(_model.getLastSaved(), session.getLastSaved())
- .set(_model.getAttributes(), BlobValue.newBuilder(Blob.copyFrom(baos.toByteArray())).setExcludeFromIndexes(true).build()).build();
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos))
+ {
+ SessionData.serializeAttributes(session, oos);
-
- return entity;
+ //turn a session into an entity
+ entity = Entity.newBuilder(key)
+ .set(_model.getId(), session.getId())
+ .set(_model.getContextPath(), session.getContextPath())
+ .set(_model.getVhost(), session.getVhost())
+ .set(_model.getAccessed(), session.getAccessed())
+ .set(_model.getLastAccessed(), session.getLastAccessed())
+ .set(_model.getCreateTime(), session.getCreated())
+ .set(_model.getCookieSetTime(), session.getCookieSet())
+ .set(_model.getLastNode(),session.getLastNode())
+ .set(_model.getExpiry(), session.getExpiry())
+ .set(_model.getMaxInactive(), session.getMaxInactiveMs())
+ .set(_model.getLastSaved(), session.getLastSaved())
+ .set(_model.getAttributes(), BlobValue.newBuilder(Blob.copyFrom(baos.toByteArray())).setExcludeFromIndexes(true).build()).build();
+ return entity;
+ }
}
/**
@@ -924,79 +903,51 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
if (entity == null)
return null;
- final AtomicReference reference = new AtomicReference<>();
- final AtomicReference exception = new AtomicReference<>();
- Runnable load = new Runnable()
- {
- @Override
- public void run ()
- {
- try
- {
- //turn an Entity into a Session
- String id = entity.getString(_model.getId());
- String contextPath = entity.getString(_model.getContextPath());
- String vhost = entity.getString(_model.getVhost());
- long accessed = entity.getLong(_model.getAccessed());
- long lastAccessed = entity.getLong(_model.getLastAccessed());
- long createTime = entity.getLong(_model.getCreateTime());
- long cookieSet = entity.getLong(_model.getCookieSetTime());
- String lastNode = entity.getString(_model.getLastNode());
+ //turn an Entity into a Session
+ String id = entity.getString(_model.getId());
+ String contextPath = entity.getString(_model.getContextPath());
+ String vhost = entity.getString(_model.getVhost());
+ long accessed = entity.getLong(_model.getAccessed());
+ long lastAccessed = entity.getLong(_model.getLastAccessed());
+ long createTime = entity.getLong(_model.getCreateTime());
+ long cookieSet = entity.getLong(_model.getCookieSetTime());
+ String lastNode = entity.getString(_model.getLastNode());
- long lastSaved = 0;
- //for compatibility with previously saved sessions, lastSaved may not be present
- try
- {
- lastSaved = entity.getLong(_model.getLastSaved());
- }
- catch (DatastoreException e)
- {
- LOG.ignore(e);
- }
- long expiry = entity.getLong(_model.getExpiry());
- long maxInactive = entity.getLong(_model.getMaxInactive());
- Blob blob = (Blob) entity.getBlob(_model.getAttributes());
-
- SessionData session = newSessionData (id, createTime, accessed, lastAccessed, maxInactive);
- session.setLastNode(lastNode);
- session.setContextPath(contextPath);
- session.setVhost(vhost);
- session.setCookieSet(cookieSet);
- session.setLastNode(lastNode);
- session.setLastSaved(lastSaved);
- session.setExpiry(expiry);
- try (ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(blob.asInputStream()))
- {
- Object o = ois.readObject();
- session.putAllAttributes((Map)o);
- }
- catch (Exception e)
- {
- throw new UnreadableSessionDataException (id, _context, e);
- }
- reference.set(session);
- }
- catch (Exception e)
- {
- exception.set(e);
- }
- }
- };
-
- //ensure this runs in the context classloader
- _context.run(load);
-
- if (exception.get() != null)
+ long lastSaved = 0;
+ //for compatibility with previously saved sessions, lastSaved may not be present
+ try
{
- throw exception.get();
+ lastSaved = entity.getLong(_model.getLastSaved());
}
-
- return reference.get();
+ catch (DatastoreException e)
+ {
+ LOG.ignore(e);
+ }
+ long expiry = entity.getLong(_model.getExpiry());
+ long maxInactive = entity.getLong(_model.getMaxInactive());
+ Blob blob = (Blob) entity.getBlob(_model.getAttributes());
+
+ SessionData session = newSessionData (id, createTime, accessed, lastAccessed, maxInactive);
+ session.setLastNode(lastNode);
+ session.setContextPath(contextPath);
+ session.setVhost(vhost);
+ session.setCookieSet(cookieSet);
+ session.setLastNode(lastNode);
+ session.setLastSaved(lastSaved);
+ session.setExpiry(expiry);
+ try (ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(blob.asInputStream()))
+ {
+ SessionData.deserializeAttributes(session, ois);
+ }
+ catch (Exception e)
+ {
+ throw new UnreadableSessionDataException (id, _context, e);
+ }
+ return session;
+
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
- */
+
@ManagedAttribute(value="does gcloud serialize session data", readonly=true)
@Override
public boolean isPassivating()
@@ -1005,14 +956,10 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
}
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#toString()
- */
@Override
public String toString()
{
return String.format("%s[namespace=%s,backoff=%d,maxRetries=%d,maxResults=%d,indexes=%b]",super.toString(), _namespace, _backoff, _maxRetries, _maxResults,_indexesPresent);
}
-
}
diff --git a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java
index 26ff7c7f30c..8e813da6c35 100644
--- a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java
+++ b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java
@@ -18,7 +18,10 @@
package org.eclipse.jetty.hazelcast.session;
-import com.hazelcast.core.IMap;
+import java.util.Collections;
+import java.util.Set;
+import java.util.stream.Collectors;
+
import org.eclipse.jetty.server.session.AbstractSessionDataStore;
import org.eclipse.jetty.server.session.SessionContext;
import org.eclipse.jetty.server.session.SessionData;
@@ -28,10 +31,7 @@ import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-import java.util.Collections;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.stream.Collectors;
+import com.hazelcast.core.IMap;
/**
* Session data stored in Hazelcast
@@ -52,36 +52,24 @@ public class HazelcastSessionDataStore
}
@Override
- public SessionData load( String id )
- throws Exception
+ public SessionData doLoad( String id )
+ throws Exception
{
-
- final AtomicReference reference = new AtomicReference<>();
- final AtomicReference exception = new AtomicReference<>();
-
- //ensure the load runs in the context classloader scope
- _context.run( () -> {
- try
- {
- if (LOG.isDebugEnabled())
- LOG.debug( "Loading session {} from hazelcast", id );
-
- SessionData sd = sessionDataMap.get( getCacheKey( id ) );
- reference.set(sd);
- }
- catch (Exception e)
- {
- exception.set(new UnreadableSessionDataException(id, _context, e));
- }
- } );
-
- if (exception.get() != null)
+ try
{
- throw exception.get();
+ if (LOG.isDebugEnabled())
+ LOG.debug( "Loading session {} from hazelcast", id );
+
+ SessionData sd = sessionDataMap.get( getCacheKey( id ) );
+ return sd;
+ }
+ catch (Exception e)
+ {
+ throw new UnreadableSessionDataException(id, _context, e);
}
- return reference.get();
}
+
@Override
public boolean delete( String id )
throws Exception
diff --git a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java
index 7fce2facb04..aa076cf4011 100644
--- a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java
+++ b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java
@@ -23,10 +23,12 @@ import com.hazelcast.client.config.ClientConfig;
import com.hazelcast.client.config.XmlClientConfigBuilder;
import com.hazelcast.config.Config;
import com.hazelcast.config.MapConfig;
+import com.hazelcast.config.SerializerConfig;
import com.hazelcast.config.XmlConfigBuilder;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import org.eclipse.jetty.server.session.AbstractSessionDataStoreFactory;
+import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.server.session.SessionDataStore;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.eclipse.jetty.server.session.SessionHandler;
@@ -68,7 +70,12 @@ public class HazelcastSessionDataStoreFactory
{
if ( configurationLocation == null )
{
- hazelcastInstance = HazelcastClient.newHazelcastClient( new ClientConfig() );
+ ClientConfig config = new ClientConfig();
+ SerializerConfig sc = new SerializerConfig().
+ setImplementation(new SessionDataSerializer()).
+ setTypeClass(SessionData.class);
+ config.getSerializationConfig().addSerializerConfig(sc);
+ hazelcastInstance = HazelcastClient.newHazelcastClient(config);
}
else
{
@@ -82,7 +89,12 @@ public class HazelcastSessionDataStoreFactory
Config config;
if ( configurationLocation == null )
{
+
+ SerializerConfig sc = new SerializerConfig().
+ setImplementation(new SessionDataSerializer()).
+ setTypeClass(SessionData.class);
config = new Config();
+ config.getSerializationConfig().addSerializerConfig(sc);
// configure a default Map if null
if ( mapConfig == null )
{
diff --git a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/SessionDataSerializer.java b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/SessionDataSerializer.java
new file mode 100644
index 00000000000..e5dc9d3514c
--- /dev/null
+++ b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/SessionDataSerializer.java
@@ -0,0 +1,110 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2018 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.hazelcast.session;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+
+import org.eclipse.jetty.server.session.SessionData;
+import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
+
+import com.hazelcast.nio.ObjectDataInput;
+import com.hazelcast.nio.ObjectDataOutput;
+import com.hazelcast.nio.serialization.StreamSerializer;
+
+/**
+ * SessionDataSerializer
+ *
+ * Handles serialization on behalf of the SessionData object, and
+ * ensures that we use jetty's classloading knowledge.
+ */
+public class SessionDataSerializer implements StreamSerializer
+{
+ public static final int __TYPEID = 99;
+ @Override
+ public int getTypeId()
+ {
+ return __TYPEID;
+ }
+
+ @Override
+ public void destroy()
+ {
+ }
+
+ @Override
+ public void write(ObjectDataOutput out, SessionData data) throws IOException
+ {
+ out.writeUTF(data.getId());
+ out.writeUTF(data.getContextPath());
+ out.writeUTF(data.getVhost());
+
+ out.writeLong(data.getAccessed());
+ out.writeLong(data.getLastAccessed());
+ out.writeLong(data.getCreated());
+ out.writeLong(data.getCookieSet());
+ out.writeUTF(data.getLastNode());
+
+ out.writeLong(data.getExpiry());
+ out.writeLong(data.getMaxInactiveMs());
+
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos))
+ {
+ SessionData.serializeAttributes(data, oos);
+ out.writeByteArray(baos.toByteArray());
+ }
+ }
+
+ @Override
+ public SessionData read(ObjectDataInput in) throws IOException
+ {
+ String id = in.readUTF();
+ String contextPath = in.readUTF();
+ String vhost = in.readUTF();
+
+ long accessed = in.readLong();
+ long lastAccessed = in.readLong();
+ long created = in.readLong();
+ long cookieSet = in.readLong();
+ String lastNode = in.readUTF();
+ long expiry = in.readLong();
+ long maxInactiveMs = in.readLong();
+
+ SessionData sd = new SessionData(id, contextPath, vhost, created, accessed, lastAccessed, maxInactiveMs);
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(in.readByteArray());
+ try (ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(bais))
+ {
+ SessionData.deserializeAttributes(sd, ois);
+ }
+ catch(ClassNotFoundException e)
+ {
+ throw new IOException(e);
+ }
+ sd.setCookieSet(cookieSet);
+ sd.setLastNode(lastNode);
+ sd.setExpiry(expiry);
+ return sd;
+ }
+
+}
diff --git a/jetty-infinispan/pom.xml b/jetty-infinispan/pom.xml
index 6ad0e56f451..921c93aaf4b 100644
--- a/jetty-infinispan/pom.xml
+++ b/jetty-infinispan/pom.xml
@@ -40,10 +40,27 @@
infinispan-core${infinispan.version}
+
+ org.infinispan.protostream
+ protostream
+ 4.1.0.Final
+ org.eclipse.jettyjetty-server${project.version}
+
+ org.infinispan
+ infinispan-client-hotrod
+ 9.1.0.Final
+ provided
+
+
+ org.infinispan
+ infinispan-remote-query-client
+ 9.1.0.Final
+ provided
+
diff --git a/jetty-infinispan/src/main/config/etc/sessions/infinispan/remote.xml b/jetty-infinispan/src/main/config/etc/sessions/infinispan/remote.xml
index 5f2bb705404..356cd48b29c 100644
--- a/jetty-infinispan/src/main/config/etc/sessions/infinispan/remote.xml
+++ b/jetty-infinispan/src/main/config/etc/sessions/infinispan/remote.xml
@@ -4,15 +4,72 @@
+
+
+
+
+
+
+
+
+
+
+ /resources/hotrod-client.properties
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /session.proto
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
+
diff --git a/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java
new file mode 100644
index 00000000000..dbca0652dc3
--- /dev/null
+++ b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java
@@ -0,0 +1,69 @@
+package org.eclipse.jetty.session.infinispan;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.util.Map;
+
+import org.eclipse.jetty.server.session.SessionData;
+import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
+
+/**
+ * InfinispanSessionData
+ *
+ * Specialization of SessionData to hold the attributes as a serialized byte
+ * array. This is necessary because to deserialize the attributes correctly, we
+ * need to know which classloader to use, which is normally provided as the
+ * thread context classloader. However, infinispan marshalling uses a thread
+ * pool and thus these threads have no knowledge of the correct classloader to
+ * use.
+ *
+ */
+public class InfinispanSessionData extends SessionData
+{
+ protected byte[] _serializedAttributes;
+
+ public InfinispanSessionData(String id, String cpath, String vhost, long created, long accessed, long lastAccessed, long maxInactiveMs)
+ {
+ super(id, cpath, vhost, created, accessed, lastAccessed, maxInactiveMs);
+ }
+
+ public InfinispanSessionData(String id, String cpath, String vhost, long created, long accessed, long lastAccessed, long maxInactiveMs,
+ Map attributes)
+ {
+ super(id, cpath, vhost, created, accessed, lastAccessed, maxInactiveMs, attributes);
+ }
+
+ public byte[] getSerializedAttributes()
+ {
+ return _serializedAttributes;
+ }
+
+ public void setSerializedAttributes(byte[] serializedAttributes)
+ {
+ _serializedAttributes = serializedAttributes;
+ }
+
+ public void deserializeAttributes() throws ClassNotFoundException, IOException
+ {
+ if (_serializedAttributes == null) return;
+
+ try (ByteArrayInputStream bais = new ByteArrayInputStream(_serializedAttributes);
+ ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(bais))
+ {
+ SessionData.deserializeAttributes(this, ois);
+ _serializedAttributes = null;
+ }
+ }
+
+ public void serializeAttributes() throws IOException
+ {
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos))
+ {
+ SessionData.serializeAttributes(this, oos);
+ _serializedAttributes = baos.toByteArray();
+ }
+ }
+}
\ No newline at end of file
diff --git a/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java
index 5d649b76bfd..fa21de58ade 100644
--- a/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java
+++ b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java
@@ -45,7 +45,6 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
-
/**
* Clustered cache of sessions
*/
@@ -54,6 +53,8 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
private int _infinispanIdleTimeoutSec;
+ private boolean _passivating;
+
/**
* Get the clustered cache instance.
@@ -77,50 +78,55 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
this._cache = cache;
}
-
-
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#load(String)
- */
- @Override
- public SessionData load(String id) throws Exception
- {
- final AtomicReference reference = new AtomicReference<>();
- final AtomicReference exception = new AtomicReference<>();
-
- Runnable load = new Runnable()
- {
- @Override
- public void run ()
- {
- try
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Loading session {} from infinispan", id);
-
- SessionData sd = (SessionData)_cache.get(getCacheKey(id));
- reference.set(sd);
- }
- catch (Exception e)
- {
- exception.set(new UnreadableSessionDataException(id, _context, e));
- }
- }
- };
-
- //ensure the load runs in the context classloader scope
- _context.run(load);
-
- if (exception.get() != null)
- throw exception.get();
-
- return reference.get();
+
+ @Override
+ protected void doStart() throws Exception
+ {
+ super.doStart();
+ if (_cache == null)
+ throw new IllegalStateException ("No cache");
+
+ try
+ {
+ _passivating = false;
+ Class> remoteClass = Thread.currentThread().getContextClassLoader().loadClass("org.infinispan.client.hotrod.RemoteCache");
+ if (remoteClass.isAssignableFrom(_cache.getClass()))
+ _passivating = true;
+ }
+ catch (ClassNotFoundException e)
+ {
+ //expected if not running with remote cache
+ }
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#delete(String)
- */
+
+
+ @Override
+ public SessionData doLoad(String id) throws Exception
+ {
+ try
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("Loading session {} from infinispan", id);
+
+ InfinispanSessionData sd = (InfinispanSessionData)_cache.get(getCacheKey(id));
+ if (isPassivating() && sd != null)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("Deserializing session attributes for {}", id);
+ sd.deserializeAttributes();
+ }
+
+ return sd;
+ }
+ catch (Exception e)
+ {
+ throw new UnreadableSessionDataException(id, _context, e);
+ }
+ }
+
+
@Override
public boolean delete(String id) throws Exception
{
@@ -129,9 +135,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
return (_cache.remove(getCacheKey(id)) != null);
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
- */
+
@Override
public Set doGetExpired(Set candidates)
{
@@ -199,9 +203,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
return expired;
}
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(String, SessionData, long)
- */
+
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
{
@@ -210,9 +212,9 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
//scavenges the session before this timeout occurs, the session will be removed.
//NOTE: that no session listeners can be called for this.
if (data.getMaxInactiveMs() > 0 && getInfinispanIdleTimeoutSec() > 0)
- _cache.put(getCacheKey(id), data, -1, TimeUnit.MILLISECONDS, getInfinispanIdleTimeoutSec(), TimeUnit.SECONDS);
+ _cache.put(getCacheKey(id), (InfinispanSessionData)data, -1, TimeUnit.MILLISECONDS, getInfinispanIdleTimeoutSec(), TimeUnit.SECONDS);
else
- _cache.put(getCacheKey(id), data);
+ _cache.put(getCacheKey(id), (InfinispanSessionData)data);
if (LOG.isDebugEnabled())
LOG.debug("Session {} saved to infinispan, expires {} ", id, data.getExpiry());
@@ -225,35 +227,15 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
}
-
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
- */
@ManagedAttribute(value="does store serialize sessions", readonly=true)
@Override
public boolean isPassivating()
{
- //TODO run in the _context to ensure classloader is set
- try
- {
- Class> remoteClass = Thread.currentThread().getContextClassLoader().loadClass("org.infinispan.client.hotrod.RemoteCache");
- if (remoteClass.isAssignableFrom(_cache.getClass()))
- {
- return true;
- }
- return false;
- }
- catch (ClassNotFoundException e)
- {
- return false;
- }
+ return _passivating;
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
- */
@Override
public boolean exists(String id) throws Exception
{
@@ -299,6 +281,13 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
+ @Override
+ public SessionData newSessionData(String id, long created, long accessed, long lastAccessed, long maxInactiveMs)
+ {
+ return new InfinispanSessionData(id, _context.getCanonicalContextPath(), _context.getVhost(), created, accessed, lastAccessed, maxInactiveMs);
+ }
+
+
/**
* @param sec the infinispan-specific idle timeout in sec or 0 if not set
*/
@@ -315,15 +304,9 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
}
-
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#toString()
- */
@Override
public String toString()
{
return String.format("%s[cache=%s,idleTimeoutSec=%d]",super.toString(), (_cache==null?"":_cache.getName()),_infinispanIdleTimeoutSec);
}
-
-
}
diff --git a/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionLegacyConverter.java b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionLegacyConverter.java
new file mode 100644
index 00000000000..2571e52bcc0
--- /dev/null
+++ b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionLegacyConverter.java
@@ -0,0 +1,224 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2018 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.session.infinispan;
+
+import java.util.List;
+import java.util.Properties;
+import java.util.stream.Collectors;
+
+import org.eclipse.jetty.server.session.SessionData;
+import org.infinispan.client.hotrod.RemoteCache;
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
+import org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller;
+import org.infinispan.protostream.FileDescriptorSource;
+import org.infinispan.protostream.SerializationContext;
+
+
+/**
+ * InfinispanSessionLegacyConverter
+ *
+ * Converts sessions saved in the old serialization
+ * format into the new protobuf-based serialization.
+ *
+ * Use the -Dverbose=true system property to
+ * print out more information about conversion failures.
+ *
+ */
+public class InfinispanSessionLegacyConverter
+{
+ RemoteCacheManager _protoManager;
+ RemoteCache _protoCache;
+ RemoteCacheManager _legacyManager;
+ RemoteCache _legacyCache;
+ boolean _verbose = false;
+
+
+ public InfinispanSessionLegacyConverter (String cacheName)
+ throws Exception
+ {
+ //legacy serialization
+ _legacyManager = new RemoteCacheManager();
+ _legacyCache = _legacyManager.getCache(cacheName);
+
+ //new protobuf based
+ String host = System.getProperty("host", "127.0.0.1");
+ _verbose = Boolean.getBoolean("verbose");
+
+ Properties properties = new Properties();
+ ConfigurationBuilder clientBuilder = new ConfigurationBuilder();
+ clientBuilder.withProperties(properties).addServer().host(host).marshaller(new ProtoStreamMarshaller());
+ _protoManager = new RemoteCacheManager(clientBuilder.build());
+ FileDescriptorSource fds = new FileDescriptorSource();
+ fds.addProtoFiles("/session.proto");
+ SerializationContext serCtx = ProtoStreamMarshaller.getSerializationContext(_protoManager);
+ serCtx.registerProtoFiles(fds);
+ serCtx.registerMarshaller(new SessionDataMarshaller());
+ _protoCache = _protoManager.getCache(cacheName);
+ }
+
+ /**
+ * Convert all sessions to protobuf format sessions.
+ */
+ public void convert ()
+ {
+ long conversions = 0;
+ List keys = null;
+
+ //Get all sessions stored in the legacy format
+ try
+ {
+ keys = _legacyCache.keySet().stream().collect(Collectors.toList());
+ }
+ catch (Exception e)
+ {
+ System.err.println("Error listing legacy sessions, assuming previously converted. Run again using 'check' argument to verify conversion");
+ if (_verbose) e.printStackTrace();
+ System.exit(1);
+ }
+
+ for (String s:keys)
+ {
+ SessionData data = null;
+ try
+ {
+ data = (SessionData)_legacyCache.get(s);
+ }
+ catch (Exception e)
+ {
+ System.err.println("Read of session "+s+" failed. Assuming session already converted and skipping.");
+ if (_verbose) e.printStackTrace();
+ continue;
+ }
+
+ if (data != null)
+ {
+ try
+ {
+ _legacyCache.remove(s);
+ }
+ catch (Exception e)
+ {
+ System.err.println("Remove legacy session failed for "+s+" skipping conversion.");
+ if (_verbose) e.printStackTrace();
+ continue;
+ }
+
+ try
+ {
+ InfinispanSessionData isd = new InfinispanSessionData(data.getId(), data.getContextPath(), data.getVhost(), data.getCreated(),
+ data.getAccessed(), data.getLastAccessed(), data.getMaxInactiveMs());
+ isd.putAllAttributes(data.getAllAttributes());
+ isd.setExpiry(data.getExpiry());
+ isd.setCookieSet(data.getCookieSet());
+ isd.setLastSaved(data.getLastSaved());
+ isd.setLastNode(data.getLastNode());
+ // now write it out to the protobuf format
+ _protoCache.put(s, isd);
+ System.err.println("Converted " + s);
+ conversions++;
+ }
+ catch (Exception e)
+ {
+ if (_verbose) e.printStackTrace();
+ System.err.println("Conversion failed for " + s + " re-instating legacy session.");
+ try
+ {
+ _legacyCache.put(s, data);
+ }
+ catch (Exception x)
+ {
+ System.err.println("FAILED REINSTATING SESSION " + s + ". ABORTING.");
+ x.printStackTrace();
+ System.exit(1);
+ }
+ }
+ }
+ else
+ System.err.println("Unreadable legacy session "+s);
+ }
+
+ System.err.println("Total sessions converted: "+conversions);
+ }
+
+ /**
+ * Retrieve the sessions using protobuf format and print them out to
+ * confirm they're ok.
+ */
+ public void checkConverted ()
+ {
+ List keys = null;
+ try
+ {
+ keys = _protoCache.keySet().stream().collect(Collectors.toList());
+ }
+ catch (Exception e)
+ {
+ System.err.println("Unable to read converted sessions, assuming still in legacy format. Run again without 'check' option to convert.");
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ for (String s:keys)
+ {
+ InfinispanSessionData converted = (InfinispanSessionData)_protoCache.get(s);
+ if (converted != null)
+ {
+ System.err.println("OK: "+converted);
+ converted.getKeys().stream().forEach((ss)->{System.err.println(ss+":"+converted.getAttribute(ss));});
+ }
+ else
+ System.err.println("Failed: "+s);
+ }
+
+ System.err.println("Total converted sessions: "+keys.size());
+ }
+
+ public static final void usage ()
+ {
+ System.err.println("Usage: InfinispanSessionLegacyConverter [-Dhost=127.0.0.1] [-Dverbose=true] [check]");
+ }
+
+ public static final void main (String... args)
+ {
+ if (args == null || args.length < 1)
+ {
+ usage();
+ System.exit(1);
+ }
+
+ try
+ {
+ InfinispanSessionLegacyConverter converter = new InfinispanSessionLegacyConverter(args[0]);
+
+ if (args.length == 1)
+ converter.convert();
+ else if (args[1].equals("check"))
+ converter.checkConverted();
+ else
+ usage();
+ }
+ catch (Exception e)
+ {
+ System.err.println("Conversion failure");
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java
new file mode 100644
index 00000000000..0d380d4cb22
--- /dev/null
+++ b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java
@@ -0,0 +1,106 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2018 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.session.infinispan;
+
+import java.io.IOException;
+
+import org.infinispan.protostream.MessageMarshaller;
+
+/**
+ * SessionDataMarshaller
+ *
+ * A marshaller for converting a SessionData object into protobuf format which
+ * gives greater control over serialization/deserialization. We use that extra
+ * control to ensure that session attributes can be deserialized using either
+ * the container class loader or the webapp classloader, as appropriate.
+ */
+public class SessionDataMarshaller implements MessageMarshaller
+{
+ /**
+ * The version of the serializer.
+ */
+ private static final int VERSION = 0;
+
+ @Override
+ public Class extends InfinispanSessionData> getJavaClass()
+ {
+ return InfinispanSessionData.class;
+ }
+
+ @Override
+ public String getTypeName()
+ {
+ return "org_eclipse_jetty_session_infinispan.InfinispanSessionData";
+ }
+
+ @Override
+ public InfinispanSessionData readFrom(ProtoStreamReader in) throws IOException
+ {
+ int version = in.readInt("version");// version of serialized session
+ String id = in.readString("id"); // session id
+ String cpath = in.readString("contextPath"); // context path
+ String vhost = in.readString("vhost"); // first vhost
+
+ long accessed = in.readLong("accessed");// accessTime
+ long lastAccessed = in.readLong("lastAccessed"); // lastAccessTime
+ long created = in.readLong("created"); // time created
+ long cookieSet = in.readLong("cookieSet");// time cookie was set
+ String lastNode = in.readString("lastNode"); // name of last node
+ // managing
+
+ long expiry = in.readLong("expiry");
+ long maxInactiveMs = in.readLong("maxInactiveMs");
+
+ InfinispanSessionData sd = new InfinispanSessionData(id, cpath, vhost, created, accessed, lastAccessed, maxInactiveMs);
+ sd.setCookieSet(cookieSet);
+ sd.setLastNode(lastNode);
+ sd.setExpiry(expiry);
+
+ if (version == 0)
+ {
+ byte[] attributeArray = in.readBytes("attributes");
+ sd.setSerializedAttributes(attributeArray);
+ return sd;
+ }
+ else
+ throw new IOException("Unrecognized infinispan session version " + version);
+ }
+
+ @Override
+ public void writeTo(ProtoStreamWriter out, InfinispanSessionData sdata) throws IOException
+ {
+ out.writeInt("version", VERSION);
+ out.writeString("id", sdata.getId()); // session id
+ out.writeString("contextPath", sdata.getContextPath()); // context path
+ out.writeString("vhost", sdata.getVhost()); // first vhost
+
+ out.writeLong("accessed", sdata.getAccessed());// accessTime
+ out.writeLong("lastAccessed", sdata.getLastAccessed()); // lastAccessTime
+ out.writeLong("created", sdata.getCreated()); // time created
+ out.writeLong("cookieSet", sdata.getCookieSet());// time cookie was set
+ out.writeString("lastNode", sdata.getLastNode()); // name of last node
+ // managing
+
+ out.writeLong("expiry", sdata.getExpiry());
+ out.writeLong("maxInactiveMs", sdata.getMaxInactiveMs());
+
+ sdata.serializeAttributes();
+ out.writeBytes("attributes", sdata.getSerializedAttributes());
+ }
+}
diff --git a/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/WebAppMarshaller.java b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/WebAppMarshaller.java
index 741b2d0a074..1d3c52e5eef 100644
--- a/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/WebAppMarshaller.java
+++ b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/WebAppMarshaller.java
@@ -49,6 +49,7 @@ import org.jboss.marshalling.ContextClassResolver;
* </Call>
*
*/
+@Deprecated
public class WebAppMarshaller extends AbstractJBossMarshaller
{
diff --git a/jetty-infinispan/src/main/resources/session.proto b/jetty-infinispan/src/main/resources/session.proto
new file mode 100644
index 00000000000..ecadbaaf66c
--- /dev/null
+++ b/jetty-infinispan/src/main/resources/session.proto
@@ -0,0 +1,19 @@
+package org_eclipse_jetty_session_infinispan;
+
+message InfinispanSessionData
+{
+ required int32 version = 1;
+ required string id = 2;
+ required string contextPath = 3;
+ required string vhost = 4;
+
+ required sint64 accessed = 5;
+ required sint64 lastAccessed = 6;
+ required sint64 created = 7;
+ required sint64 cookieSet = 8;
+ required string lastNode = 9;
+
+ required sint64 expiry = 10;
+ required sint64 maxInactiveMs = 11;
+ required bytes attributes = 12;
+}
\ No newline at end of file
diff --git a/jetty-memcached/jetty-memcached-sessions/pom.xml b/jetty-memcached/jetty-memcached-sessions/pom.xml
index fe4b89009f4..f76ba891883 100644
--- a/jetty-memcached/jetty-memcached-sessions/pom.xml
+++ b/jetty-memcached/jetty-memcached-sessions/pom.xml
@@ -19,7 +19,7 @@
com.googlecode.xmemcachedxmemcached
- 2.0.0
+ 2.4.5org.slf4j
diff --git a/jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod b/jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod
index 0618c02950a..77a21ea759f 100644
--- a/jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod
+++ b/jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod
@@ -11,7 +11,7 @@ session-store
slf4j-api
[files]
-maven://com.googlecode.xmemcached/xmemcached/2.0.0|lib/xmemcached/xmemcached-2.0.0.jar
+maven://com.googlecode.xmemcached/xmemcached/2.4.5|lib/xmemcached/xmemcached-2.4.5.jar
[lib]
lib/jetty-memcached-sessions-${jetty.version}.jar
diff --git a/jetty-memcached/jetty-memcached-sessions/src/main/java/org/eclipse/jetty/memcached/session/MemcachedSessionDataMap.java b/jetty-memcached/jetty-memcached-sessions/src/main/java/org/eclipse/jetty/memcached/session/MemcachedSessionDataMap.java
index fbeff56d73d..1b3d01da1ee 100644
--- a/jetty-memcached/jetty-memcached-sessions/src/main/java/org/eclipse/jetty/memcached/session/MemcachedSessionDataMap.java
+++ b/jetty-memcached/jetty-memcached-sessions/src/main/java/org/eclipse/jetty/memcached/session/MemcachedSessionDataMap.java
@@ -18,6 +18,7 @@
package org.eclipse.jetty.memcached.session;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.List;
@@ -25,12 +26,14 @@ import java.util.List;
import org.eclipse.jetty.server.session.SessionContext;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.server.session.SessionDataMap;
+import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
+import net.rubyeye.xmemcached.transcoders.SerializingTranscoder;
@@ -50,6 +53,39 @@ public class MemcachedSessionDataMap extends AbstractLifeCycle implements Sessio
protected XMemcachedClientBuilder _builder;
+ /**
+ * SessionDataTranscoder
+ *
+ * We override memcached deserialization to use our classloader-aware
+ * ObjectInputStream.
+ */
+ public static class SessionDataTranscoder extends SerializingTranscoder
+ {
+
+ @Override
+ protected Object deserialize(byte[] in)
+ {
+ Object rv = null;
+
+ if (in != null)
+ {
+ try (ByteArrayInputStream bis = new ByteArrayInputStream(in);
+ ClassLoadingObjectInputStream is = new ClassLoadingObjectInputStream(bis))
+ {
+ rv = is.readObject();
+ }
+ catch (IOException e)
+ {
+ log.error("Caught IOException decoding " + in.length + " bytes of data", e);
+ }
+ catch (ClassNotFoundException e)
+ {
+ log.error("Caught CNFE decoding " + in.length + " bytes of data", e);
+ }
+ }
+ return rv;
+ }
+ }
/**
@@ -117,14 +153,12 @@ public class MemcachedSessionDataMap extends AbstractLifeCycle implements Sessio
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataMap#initialize(org.eclipse.jetty.server.session.SessionContext)
- */
@Override
public void initialize(SessionContext context)
{
try
{
+ _builder.setTranscoder(new SessionDataTranscoder ());
_client = _builder.build();
_client.setEnableHeartBeat(isHeartbeats());
}
@@ -134,9 +168,7 @@ public class MemcachedSessionDataMap extends AbstractLifeCycle implements Sessio
}
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataMap#load(java.lang.String)
- */
+
@Override
public SessionData load(String id) throws Exception
{
@@ -145,19 +177,13 @@ public class MemcachedSessionDataMap extends AbstractLifeCycle implements Sessio
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataMap#store(java.lang.String, org.eclipse.jetty.server.session.SessionData)
- */
@Override
public void store(String id, SessionData data) throws Exception
{
_client.set(id, _expirySec, data);
}
-
- /**
- * @see org.eclipse.jetty.server.session.SessionDataMap#delete(java.lang.String)
- */
+
@Override
public boolean delete(String id) throws Exception
{
@@ -176,7 +202,6 @@ public class MemcachedSessionDataMap extends AbstractLifeCycle implements Sessio
_client.shutdown();
_client = null;
}
- }
-
+ }
}
diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java
index 106df261ec1..80e456f4aac 100644
--- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java
+++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java
@@ -19,15 +19,19 @@
package org.eclipse.jetty.nosql.mongodb;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.nosql.NoSqlSessionDataStore;
import org.eclipse.jetty.server.session.SessionContext;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.server.session.UnreadableSessionDataException;
+import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.log.Log;
@@ -86,9 +90,9 @@ import com.mongodb.WriteResult;
*
*
* In MongoDB, the nesting level is indicated by "." separators for the key name. Thus to
- * interact with a session attribute, the key is composed of:
- * "context".unique_context_name.attribute_name
- * Eg "context"."0_0_0_0:_testA"."A"
+ * interact with session fields, the key is composed of:
+ * "context".unique_context_name.field_name
+ * Eg "context"."0_0_0_0:_testA"."lastSaved"
*
*
*/
@@ -128,6 +132,8 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
public final static String __LAST_ACCESSED = "lastAccessed";
+ public final static String __ATTRIBUTES = "attributes";
+
/**
* Time this session will expire, based on last access time and maxIdle
*/
@@ -178,107 +184,98 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
}
-
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#load(String)
- */
@Override
- public SessionData load(String id) throws Exception
+ public SessionData doLoad(String id) throws Exception
{
- final AtomicReference reference = new AtomicReference<>();
- final AtomicReference exception = new AtomicReference<>();
- Runnable r = new Runnable()
+ DBObject sessionDocument = _dbSessions.findOne(new BasicDBObject(__ID, id));
+
+ try
{
- @Override
- public void run ()
+ if (LOG.isDebugEnabled())
+ LOG.debug("id={} loaded={}", id, sessionDocument);
+
+ if (sessionDocument == null)
+ return null;
+
+ Boolean valid = (Boolean)sessionDocument.get(__VALID);
+
+ if (LOG.isDebugEnabled())
+ LOG.debug("id={} valid={}", id, valid);
+ if (valid == null || !valid)
+ return null;
+
+ Object version = MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__VERSION));
+ Long lastSaved = (Long)MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__LASTSAVED));
+ String lastNode = (String)MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__LASTNODE));
+ byte[] attributes = (byte[])MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__ATTRIBUTES));
+
+ Long created = (Long)sessionDocument.get(__CREATED);
+ Long accessed = (Long)sessionDocument.get(__ACCESSED);
+ Long lastAccessed = (Long)sessionDocument.get(__LAST_ACCESSED);
+ Long maxInactive = (Long)sessionDocument.get(__MAX_IDLE);
+ Long expiry = (Long)sessionDocument.get(__EXPIRY);
+
+ NoSqlSessionData data = null;
+
+ // get the session for the context
+ DBObject sessionSubDocumentForContext = (DBObject)MongoUtils.getNestedValue(sessionDocument,getContextField());
+
+ if (LOG.isDebugEnabled()) LOG.debug("attrs {}", sessionSubDocumentForContext);
+
+ if (sessionSubDocumentForContext != null)
{
- try
+ if (LOG.isDebugEnabled())
+ LOG.debug("Session {} present for context {}", id, _context);
+
+ //only load a session if it exists for this context
+ data = (NoSqlSessionData)newSessionData(id, created, accessed, (lastAccessed == null? accessed:lastAccessed), maxInactive);
+ data.setVersion(version);
+ data.setExpiry(expiry);
+ data.setContextPath(_context.getCanonicalContextPath());
+ data.setVhost(_context.getVhost());
+ data.setLastSaved(lastSaved);
+ data.setLastNode(lastNode);
+
+ if (attributes == null)
{
- DBObject sessionDocument = _dbSessions.findOne(new BasicDBObject(__ID, id));
-
- if (LOG.isDebugEnabled())
- LOG.debug("id={} loaded={}", id, sessionDocument);
-
- if (sessionDocument == null)
- return;
-
- Boolean valid = (Boolean)sessionDocument.get(__VALID);
-
- if (LOG.isDebugEnabled())
- LOG.debug("id={} valid={}", id, valid);
- if (valid == null || !valid)
- return;
-
- Object version = MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__VERSION));
- Long lastSaved = (Long)MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__LASTSAVED));
- String lastNode = (String)MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__LASTNODE));
-
- Long created = (Long)sessionDocument.get(__CREATED);
- Long accessed = (Long)sessionDocument.get(__ACCESSED);
- Long lastAccessed = (Long)sessionDocument.get(__LAST_ACCESSED);
- Long maxInactive = (Long)sessionDocument.get(__MAX_IDLE);
- Long expiry = (Long)sessionDocument.get(__EXPIRY);
-
- NoSqlSessionData data = null;
-
- // get the session for the context
- DBObject sessionSubDocumentForContext = (DBObject)MongoUtils.getNestedValue(sessionDocument,getContextField());
-
- if (LOG.isDebugEnabled()) LOG.debug("attrs {}", sessionSubDocumentForContext);
-
- if (sessionSubDocumentForContext != null)
+ //legacy attribute storage format: the attributes are all fields in the document
+ Map map = new HashMap<>();
+ for (String name : sessionSubDocumentForContext.keySet())
{
- if (LOG.isDebugEnabled())
- LOG.debug("Session {} present for context {}", id, _context);
-
- //only load a session if it exists for this context
- data = (NoSqlSessionData)newSessionData(id, created, accessed, (lastAccessed == null? accessed:lastAccessed), maxInactive);
- data.setVersion(version);
- data.setExpiry(expiry);
- data.setContextPath(_context.getCanonicalContextPath());
- data.setVhost(_context.getVhost());
- data.setLastSaved(lastSaved);
- data.setLastNode(lastNode);
-
- HashMap attributes = new HashMap<>();
- for (String name : sessionSubDocumentForContext.keySet())
- {
- //skip special metadata attribute which is not one of the actual session attributes
- if ( __METADATA.equals(name) )
- continue;
- String attr = MongoUtils.decodeName(name);
- Object value = MongoUtils.decodeValue(sessionSubDocumentForContext.get(name));
- attributes.put(attr,value);
- }
-
- data.putAllAttributes(attributes);
+ //skip special metadata attribute which is not one of the actual session attributes
+ if ( __METADATA.equals(name) )
+ continue;
+ String attr = MongoUtils.decodeName(name);
+ Object value = MongoUtils.decodeValue(sessionSubDocumentForContext.get(name));
+ map.put(attr,value);
}
- else
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Session {} not present for context {}", id, _context);
- }
-
- reference.set(data);
+ data.putAllAttributes(map);
}
- catch (Exception e)
+ else
{
- exception.set(new UnreadableSessionDataException(id, _context, e));
+ //attributes have special serialized format
+ try (ByteArrayInputStream bais = new ByteArrayInputStream(attributes);
+ ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(bais);)
+ {
+ SessionData.deserializeAttributes(data, ois);
+ }
}
}
- };
-
- _context.run(r);
-
- if (exception.get() != null)
- throw exception.get();
-
- return reference.get();
+ else
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("Session {} not present for context {}", id, _context);
+ }
+
+ return data;
+ }
+ catch (Exception e)
+ {
+ throw (new UnreadableSessionDataException(id, _context, e));
+ }
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#delete(String)
- */
+
@Override
public boolean delete(String id) throws Exception
{
@@ -290,7 +287,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
* associated with this session
*/
BasicDBObject mongoKey = new BasicDBObject(__ID, id);
-
+
//DBObject sessionDocument = _dbSessions.findOne(mongoKey,_version_1);
DBObject sessionDocument = _dbSessions.findOne(new BasicDBObject(__ID, id));
@@ -336,9 +333,6 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
- */
@Override
public boolean exists(String id) throws Exception
{
@@ -371,9 +365,6 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
- */
@Override
public Set doGetExpired(Set candidates)
{
@@ -459,9 +450,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
return expiredSessions;
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#initialize(org.eclipse.jetty.server.session.SessionContext)
- */
+
public void initialize (SessionContext context) throws Exception
{
if (isStarted())
@@ -470,9 +459,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
ensureIndexes();
}
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(String, SessionData, long)
- */
+
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
{
@@ -483,7 +470,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
BasicDBObject update = new BasicDBObject();
boolean upsert = false;
BasicDBObject sets = new BasicDBObject();
- BasicDBObject unsets = new BasicDBObject();
+
Object version = ((NoSqlSessionData)data).getVersion();
@@ -532,29 +519,17 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
sets.put(__ACCESSED, data.getAccessed());
sets.put(__LAST_ACCESSED, data.getLastAccessed());
-
- Set names = ((NoSqlSessionData)data).takeDirtyAttributes();
-
- if (lastSaveTime <= 0)
- {
- names.addAll(((NoSqlSessionData)data).getAllAttributeNames()); // note dirty may include removed names
- }
-
-
- for (String name : names)
+
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);)
{
- Object value = data.getAttribute(name);
- if (value == null)
- unsets.put(getContextField() + "." + MongoUtils.encodeName(name),1);
- else
- sets.put(getContextField() + "." + MongoUtils.encodeName(name), MongoUtils.encodeName(value));
+ SessionData.serializeAttributes(data, oos);
+ sets.put(getContextSubfield(__ATTRIBUTES), baos.toByteArray());
}
// Do the upsert
if (!sets.isEmpty())
update.put("$set",sets);
- if (!unsets.isEmpty())
- update.put("$unset",unsets);
WriteResult res = _dbSessions.update(key,update,upsert,false,WriteConcern.SAFE);
if (LOG.isDebugEnabled())
@@ -584,9 +559,6 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
//TODO perhaps index on expiry time?
}
-
-
- /*------------------------------------------------------------ */
private String getContextField ()
{
return __CONTEXT + "." + getCanonicalContextId();
@@ -613,9 +585,6 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
- */
@ManagedAttribute(value="does store serialize sessions", readonly=true)
@Override
public boolean isPassivating()
@@ -624,14 +593,11 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
}
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#toString()
- */
+
@Override
public String toString()
{
return String.format("%s[collection=%s]", super.toString(),getDBCollection());
}
-
}
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java
index 016564c578f..1b1ee3dddb0 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java
@@ -59,6 +59,15 @@ public class SessionAuthentication extends AbstractUserAuthentication implements
}
+ @Override
+ public UserIdentity getUserIdentity()
+ {
+ if (_userIdentity == null)
+ throw new IllegalStateException("!UserIdentity");
+ return super.getUserIdentity();
+ }
+
+
private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException
{
@@ -66,10 +75,17 @@ public class SessionAuthentication extends AbstractUserAuthentication implements
SecurityHandler security=SecurityHandler.getCurrentSecurityHandler();
if (security==null)
- throw new IllegalStateException("!SecurityHandler");
+ {
+ if (LOG.isDebugEnabled()) LOG.debug("!SecurityHandler");
+ return;
+ }
+
LoginService login_service=security.getLoginService();
if (login_service==null)
- throw new IllegalStateException("!LoginService");
+ {
+ if (LOG.isDebugEnabled()) LOG.debug("!LoginService");
+ return;
+ }
_userIdentity=login_service.login(_name,_credentials, null);
LOG.debug("Deserialized and relogged in {}",this);
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStore.java
index 0d06bf9e626..95037c85e47 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStore.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStore.java
@@ -22,6 +22,7 @@ package org.eclipse.jetty.server.session;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
@@ -53,6 +54,16 @@ public abstract class AbstractSessionDataStore extends ContainerLifeCycle implem
* @throws Exception if unable to store data
*/
public abstract void doStore(String id, SessionData data, long lastSaveTime) throws Exception;
+
+ /**
+ * Load the session from persistent store.
+ *
+ * @param id the id of the session to load
+ * @return the re-inflated session
+ *
+ * @throws Exception if unable to load the session
+ */
+ public abstract SessionData doLoad (String id) throws Exception;
/**
@@ -64,10 +75,6 @@ public abstract class AbstractSessionDataStore extends ContainerLifeCycle implem
*/
public abstract Set doGetExpired (Set candidates);
-
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#initialize(org.eclipse.jetty.server.session.SessionContext)
- */
@Override
public void initialize (SessionContext context) throws Exception
{
@@ -76,47 +83,84 @@ public abstract class AbstractSessionDataStore extends ContainerLifeCycle implem
_context = context;
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#store(java.lang.String, org.eclipse.jetty.server.session.SessionData)
- */
+
+
+ @Override
+ public SessionData load(String id) throws Exception
+ {
+ final AtomicReference reference = new AtomicReference();
+ final AtomicReference exception = new AtomicReference();
+
+ Runnable r = new Runnable()
+ {
+ @Override
+ public void run ()
+ {
+ try
+ {
+ reference.set(doLoad(id));
+ }
+ catch (Exception e)
+ {
+ exception.set(e);
+ }
+ }
+ };
+
+ _context.run(r);
+ if (exception.get() != null)
+ throw exception.get();
+
+ return reference.get();
+ }
+
+
@Override
public void store(String id, SessionData data) throws Exception
{
if (data == null)
return;
+ final AtomicReference exception = new AtomicReference();
- long lastSave = data.getLastSaved();
- long savePeriodMs = (_savePeriodSec <=0? 0: TimeUnit.SECONDS.toMillis(_savePeriodSec));
-
- if (LOG.isDebugEnabled())
- LOG.debug("Store: id={}, dirty={}, lsave={}, period={}, elapsed={}", id,data.isDirty(), data.getLastSaved(), savePeriodMs, (System.currentTimeMillis()-lastSave));
-
- //save session if attribute changed or never been saved or time between saves exceeds threshold
- if (data.isDirty() || (lastSave <= 0) || ((System.currentTimeMillis()-lastSave) > savePeriodMs))
+ Runnable r = new Runnable()
{
- //set the last saved time to now
- data.setLastSaved(System.currentTimeMillis());
- try
+ @Override
+ public void run ()
{
- //call the specific store method, passing in previous save time
- doStore(id, data, lastSave);
- data.setDirty(false); //only undo the dirty setting if we saved it
- }
- catch (Exception e)
- {
- //reset last save time if save failed
- data.setLastSaved(lastSave);
- throw e;
- }
- }
+ long lastSave = data.getLastSaved();
+ long savePeriodMs = (_savePeriodSec <=0? 0: TimeUnit.SECONDS.toMillis(_savePeriodSec));
+
+ if (LOG.isDebugEnabled())
+ LOG.debug("Store: id={}, dirty={}, lsave={}, period={}, elapsed={}", id,data.isDirty(), data.getLastSaved(), savePeriodMs, (System.currentTimeMillis()-lastSave));
+
+ //save session if attribute changed or never been saved or time between saves exceeds threshold
+ if (data.isDirty() || (lastSave <= 0) || ((System.currentTimeMillis()-lastSave) > savePeriodMs))
+ {
+ //set the last saved time to now
+ data.setLastSaved(System.currentTimeMillis());
+ try
+ {
+ //call the specific store method, passing in previous save time
+ doStore(id, data, lastSave);
+ data.setDirty(false); //only undo the dirty setting if we saved it
+ }
+ catch (Exception e)
+ {
+ //reset last save time if save failed
+ data.setLastSaved(lastSave);
+ exception.set(e);
+ }
+ }
+ };
+ };
+
+ _context.run(r);
+ if (exception.get() != null)
+ throw exception.get();
}
-
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(java.util.Set)
- */
@Override
public Set getExpired(Set candidates)
{
@@ -131,11 +175,6 @@ public abstract class AbstractSessionDataStore extends ContainerLifeCycle implem
}
-
-
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#newSessionData(java.lang.String, long, long, long, long)
- */
@Override
public SessionData newSessionData(String id, long created, long accessed, long lastAccessed, long maxInactiveMs)
{
@@ -201,10 +240,6 @@ public abstract class AbstractSessionDataStore extends ContainerLifeCycle implem
_savePeriodSec = savePeriodSec;
}
-
- /**
- * @see java.lang.Object#toString()
- */
@Override
public String toString()
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStore.java
index 4afee55c473..82b2f7edbc4 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStore.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStore.java
@@ -31,15 +31,11 @@ import java.io.OutputStream;
import java.nio.file.FileVisitOption;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
import org.eclipse.jetty.util.MultiException;
@@ -277,80 +273,53 @@ public class FileSessionDataStore extends AbstractSessionDataStore
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#load(java.lang.String)
- */
+
@Override
- public SessionData load(String id) throws Exception
+ public SessionData doLoad(String id) throws Exception
{
- final AtomicReference reference = new AtomicReference();
- final AtomicReference exception = new AtomicReference();
- Runnable r = new Runnable()
+ //load session info from its file
+ String idWithContext = getIdWithContext(id);
+ String filename = _sessionFileMap.get(idWithContext);
+ if (filename == null)
{
- @Override
- public void run ()
+ if (LOG.isDebugEnabled())
+ LOG.debug("Unknown file {}",idWithContext);
+ return null;
+ }
+ File file = new File (_storeDir, filename);
+ if (!file.exists())
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("No such file {}",filename);
+ return null;
+ }
+
+ try (FileInputStream in = new FileInputStream(file))
+ {
+ SessionData data = load(in, id);
+ data.setLastSaved(file.lastModified());
+ return data;
+ }
+ catch (UnreadableSessionDataException e)
+ {
+ if (isDeleteUnrestorableFiles() && file.exists() && file.getParentFile().equals(_storeDir))
{
- //load session info from its file
- String idWithContext = getIdWithContext(id);
- String filename = _sessionFileMap.get(idWithContext);
- if (filename == null)
+ try
{
- if (LOG.isDebugEnabled())
- LOG.debug("Unknown file {}",idWithContext);
- return;
+ delete(id);
+ LOG.warn("Deleted unrestorable file for session {}", id);
}
- File file = new File (_storeDir, filename);
- if (!file.exists())
+ catch (Exception x)
{
- if (LOG.isDebugEnabled())
- LOG.debug("No such file {}",filename);
- return;
- }
-
- try (FileInputStream in = new FileInputStream(file))
- {
- SessionData data = load(in, id);
- data.setLastSaved(file.lastModified());
- reference.set(data);
- }
- catch (UnreadableSessionDataException e)
- {
- if (isDeleteUnrestorableFiles() && file.exists() && file.getParentFile().equals(_storeDir))
- {
- try
- {
- delete(id);
- LOG.warn("Deleted unrestorable file for session {}", id);
- }
- catch (Exception x)
- {
- LOG.warn("Unable to delete unrestorable file {} for session {}", filename, id, x);
- }
- }
-
- exception.set(e);
- }
- catch (Exception e)
- {
- exception.set(e);
- }
+ LOG.warn("Unable to delete unrestorable file {} for session {}", filename, id, x);
+ }
}
- };
-
- //ensure this runs with the context classloader set
- _context.run(r);
-
- if (exception.get() != null)
- throw exception.get();
-
- return reference.get();
+ throw e;
+ }
}
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
- */
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
{
@@ -473,10 +442,6 @@ public class FileSessionDataStore extends AbstractSessionDataStore
}
-
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
- */
@Override
@ManagedAttribute(value="are sessions serialized by this store", readonly=true)
public boolean isPassivating()
@@ -485,11 +450,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
}
-
-
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
- */
+
@Override
public boolean exists(String id) throws Exception
{
@@ -507,8 +468,10 @@ public class FileSessionDataStore extends AbstractSessionDataStore
return (expiry > System.currentTimeMillis()); //hasn't yet expired
}
- /* ------------------------------------------------------------ */
+
/**
+ * Save the session data.
+ *
* @param os the output stream to save to
* @param id identity of the session
* @param data the info of the session
@@ -528,14 +491,8 @@ public class FileSessionDataStore extends AbstractSessionDataStore
out.writeLong(data.getExpiry());
out.writeLong(data.getMaxInactiveMs());
- List keys = new ArrayList(data.getKeys());
- out.writeInt(keys.size());
ObjectOutputStream oos = new ObjectOutputStream(out);
- for (String name:keys)
- {
- oos.writeUTF(name);
- oos.writeObject(data.getAttribute(name));
- }
+ SessionData.serializeAttributes(data, oos);
}
@@ -650,7 +607,9 @@ public class FileSessionDataStore extends AbstractSessionDataStore
/**
- * @param is inputstream containing session data
+ * Load the session data from a file.
+ *
+ * @param is file input stream containing session data
* @param expectedId the id we've been told to load
* @return the session data
* @throws Exception
@@ -685,8 +644,8 @@ public class FileSessionDataStore extends AbstractSessionDataStore
data.setMaxInactiveMs(maxIdle);
// Attributes
- restoreAttributes(di, di.readInt(), data);
-
+ ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is);
+ SessionData.deserializeAttributes(data, ois);
return data;
}
catch (Exception e)
@@ -695,39 +654,10 @@ public class FileSessionDataStore extends AbstractSessionDataStore
}
}
- /**
- * @param is inputstream containing session data
- * @param size number of attributes
- * @param data the data to restore to
- * @throws Exception
- */
- protected void restoreAttributes (InputStream is, int size, SessionData data)
- throws Exception
- {
- if (size>0)
- {
- // input stream should not be closed here
- Map attributes = new HashMap();
- ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is);
- for (int i=0; i reference = new AtomicReference();
- final AtomicReference exception = new AtomicReference();
-
- Runnable r = new Runnable()
+ try (Connection connection = _dbAdaptor.getConnection();
+ PreparedStatement statement = _sessionTableSchema.getLoadStatement(connection, id, _context);
+ ResultSet result = statement.executeQuery())
{
- @Override
- public void run ()
- {
- try (Connection connection = _dbAdaptor.getConnection();
- PreparedStatement statement = _sessionTableSchema.getLoadStatement(connection, id, _context);
- ResultSet result = statement.executeQuery())
- {
- SessionData data = null;
- if (result.next())
- {
- data = newSessionData(id,
- result.getLong(_sessionTableSchema.getCreateTimeColumn()),
- result.getLong(_sessionTableSchema.getAccessTimeColumn()),
- result.getLong(_sessionTableSchema.getLastAccessTimeColumn()),
- result.getLong(_sessionTableSchema.getMaxIntervalColumn()));
- data.setCookieSet(result.getLong(_sessionTableSchema.getCookieTimeColumn()));
- data.setLastNode(result.getString(_sessionTableSchema.getLastNodeColumn()));
- data.setLastSaved(result.getLong(_sessionTableSchema.getLastSavedTimeColumn()));
- data.setExpiry(result.getLong(_sessionTableSchema.getExpiryTimeColumn()));
- data.setContextPath(_context.getCanonicalContextPath());
- data.setVhost(_context.getVhost());
+ SessionData data = null;
+ if (result.next())
+ {
+ data = newSessionData(id,
+ result.getLong(_sessionTableSchema.getCreateTimeColumn()),
+ result.getLong(_sessionTableSchema.getAccessTimeColumn()),
+ result.getLong(_sessionTableSchema.getLastAccessTimeColumn()),
+ result.getLong(_sessionTableSchema.getMaxIntervalColumn()));
+ data.setCookieSet(result.getLong(_sessionTableSchema.getCookieTimeColumn()));
+ data.setLastNode(result.getString(_sessionTableSchema.getLastNodeColumn()));
+ data.setLastSaved(result.getLong(_sessionTableSchema.getLastSavedTimeColumn()));
+ data.setExpiry(result.getLong(_sessionTableSchema.getExpiryTimeColumn()));
+ data.setContextPath(_context.getCanonicalContextPath());
+ data.setVhost(_context.getVhost());
- try (InputStream is = _dbAdaptor.getBlobInputStream(result, _sessionTableSchema.getMapColumn());
- ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is))
- {
- Object o = ois.readObject();
- data.putAllAttributes((Map)o);
- }
- catch (Exception e)
- {
- throw new UnreadableSessionDataException (id, _context, e);
- }
-
- if (LOG.isDebugEnabled())
- LOG.debug("LOADED session {}", data);
- }
- else
- if (LOG.isDebugEnabled())
- LOG.debug("No session {}", id);
-
- reference.set(data);
+ try (InputStream is = _dbAdaptor.getBlobInputStream(result, _sessionTableSchema.getMapColumn());
+ ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is))
+ {
+ SessionData.deserializeAttributes(data, ois);
}
catch (Exception e)
{
- exception.set(e);
+ throw new UnreadableSessionDataException (id, _context, e);
}
+
+ if (LOG.isDebugEnabled())
+ LOG.debug("LOADED session {}", data);
}
- };
+ else
+ if (LOG.isDebugEnabled())
+ LOG.debug("No session {}", id);
- //ensure this runs with context classloader set
- _context.run(r);
- if (exception.get() != null)
- throw exception.get();
-
- return reference.get();
+ return data;
+ }
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String)
- */
@Override
public boolean delete(String id) throws Exception
{
@@ -712,10 +679,6 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
-
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(String, SessionData, long)
- */
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
{
@@ -762,17 +725,17 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
statement.setLong(10, data.getExpiry());
statement.setLong(11, data.getMaxInactiveMs());
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(data.getAllAttributes());
- oos.flush();
- byte[] bytes = baos.toByteArray();
-
- ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
- statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob
- statement.executeUpdate();
- if (LOG.isDebugEnabled())
- LOG.debug("Inserted session "+data);
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos))
+ {
+ SessionData.serializeAttributes(data, oos);
+ byte[] bytes = baos.toByteArray();
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob
+ statement.executeUpdate();
+ if (LOG.isDebugEnabled())
+ LOG.debug("Inserted session "+data);
+ }
}
}
}
@@ -793,26 +756,25 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
statement.setLong(5, data.getExpiry());
statement.setLong(6, data.getMaxInactiveMs());
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(data.getAllAttributes());
- oos.flush();
- byte[] bytes = baos.toByteArray();
- ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
- statement.setBinaryStream(7, bais, bytes.length);//attribute map as blob
- statement.executeUpdate();
+ try(ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos))
+ {
+ SessionData.serializeAttributes(data, oos);
+ byte[] bytes = baos.toByteArray();
+ try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes))
+ {
+ statement.setBinaryStream(7, bais, bytes.length);//attribute map as blob
+ statement.executeUpdate();
- if (LOG.isDebugEnabled())
- LOG.debug("Updated session "+data);
+ if (LOG.isDebugEnabled())
+ LOG.debug("Updated session "+data);
+ }
+ }
}
}
}
-
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
- */
@Override
public Set doGetExpired(Set candidates)
{
@@ -940,10 +902,6 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
-
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
- */
@Override
@ManagedAttribute(value="does this store serialize sessions", readonly=true)
public boolean isPassivating()
@@ -954,9 +912,6 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
- */
@Override
public boolean exists(String id)
throws Exception
@@ -988,11 +943,3 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
}
}
}
-
-
-
-
-
-
-
-
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStore.java
index b27e17e6f87..f1c9914a826 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStore.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStore.java
@@ -33,28 +33,20 @@ import org.eclipse.jetty.util.annotation.ManagedObject;
public class NullSessionDataStore extends AbstractSessionDataStore
{
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#load(java.lang.String)
- */
@Override
- public SessionData load(String id) throws Exception
+ public SessionData doLoad(String id) throws Exception
{
return null;
}
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#newSessionData(java.lang.String, long, long, long, long)
- */
@Override
public SessionData newSessionData(String id, long created, long accessed, long lastAccessed, long maxInactiveMs)
{
return new SessionData(id, _context.getCanonicalContextPath(), _context.getVhost(), created, accessed, lastAccessed, maxInactiveMs);
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String)
- */
+
@Override
public boolean delete(String id) throws Exception
{
@@ -62,9 +54,7 @@ public class NullSessionDataStore extends AbstractSessionDataStore
}
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
- */
+
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
{
@@ -72,9 +62,7 @@ public class NullSessionDataStore extends AbstractSessionDataStore
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
- */
+
@Override
public Set doGetExpired(Set candidates)
{
@@ -82,9 +70,7 @@ public class NullSessionDataStore extends AbstractSessionDataStore
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
- */
+
@ManagedAttribute(value="does this store serialize sessions", readonly=true)
@Override
public boolean isPassivating()
@@ -93,9 +79,7 @@ public class NullSessionDataStore extends AbstractSessionDataStore
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
- */
+
@Override
public boolean exists(String id)
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionData.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionData.java
index 6d9e1f91a2f..6a70f16a53b 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionData.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionData.java
@@ -23,9 +23,11 @@ import java.io.IOException;
import java.io.Serializable;
import java.util.Collections;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -57,6 +59,85 @@ public class SessionData implements Serializable
protected boolean _dirty;
protected long _lastSaved; //time in msec since last save
+
+ /**
+ * Serialize the attribute map of the session.
+ *
+ * This special handling allows us to record which classloader should be used to load the value of the
+ * attribute: either the container classloader (which could be the application loader ie null, or jetty's
+ * startjar loader) or the webapp's classloader.
+ *
+ * @param data the SessionData for which to serialize the attributes
+ * @param out the stream to which to serialize
+ * @throws IOException
+ */
+ public static void serializeAttributes (SessionData data, java.io.ObjectOutputStream out)
+ throws IOException
+ {
+ int entries = data._attributes.size();
+ out.writeObject(entries);
+ for (Entry entry: data._attributes.entrySet())
+ {
+ out.writeUTF(entry.getKey());
+ ClassLoader loader = entry.getValue().getClass().getClassLoader();
+ boolean isServerLoader = false;
+
+ if (loader == Thread.currentThread().getContextClassLoader()) //is it the webapp classloader?
+ isServerLoader = false;
+ else if (loader == Thread.currentThread().getContextClassLoader().getParent() || loader == SessionData.class.getClassLoader() || loader == null) // is it the container loader?
+ isServerLoader = true;
+ else
+ throw new IOException ("Unknown loader"); // we don't know what loader to use
+
+ out.writeBoolean(isServerLoader);
+ out.writeObject(entry.getValue());
+ }
+ }
+
+ /**
+ * De-serialize the attribute map of a session.
+ *
+ * When the session was serialized, we will have recorded which classloader should be used to
+ * recover the attribute value. The classloader could be the container classloader, or the
+ * webapp classloader.
+ *
+ * @param data the SessionData for which to deserialize the attribute map
+ * @param in the serialized stream
+ * @throws IOException
+ * @throws ClassNotFoundException
+ */
+ public static void deserializeAttributes (SessionData data, java.io.ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ Object o = in.readObject();
+ if (o instanceof Integer)
+ {
+ //new serialization was used
+ if (!(ClassLoadingObjectInputStream.class.isAssignableFrom(in.getClass())))
+ throw new IOException ("Not ClassLoadingObjectInputStream");
+
+ data._attributes = new ConcurrentHashMap<>();
+ int entries = ((Integer)o).intValue();
+ for (int i=0; i < entries; i++)
+ {
+ String name = in.readUTF(); //attribute name
+ boolean isServerClassLoader = in.readBoolean(); //use server or webapp classloader to load
+
+ Object value = ((ClassLoadingObjectInputStream)in).readObject(isServerClassLoader?SessionData.class.getClassLoader():Thread.currentThread().getContextClassLoader());
+ data._attributes.put(name, value);
+ }
+ }
+ else
+ {
+ LOG.info("Legacy serialization detected for {}", data.getId());
+ //legacy serialization was used, we have just deserialized the
+ //entire attribute map
+ data._attributes = new ConcurrentHashMap();
+ data.putAllAttributes((Map)o);
+ }
+ }
+
+
public SessionData (String id, String cpath, String vhost, long created, long accessed, long lastAccessed, long maxInactiveMs)
{
this(id, cpath, vhost, created, accessed, lastAccessed, maxInactiveMs, new ConcurrentHashMap());
@@ -335,24 +416,21 @@ public class SessionData implements Serializable
out.writeUTF(_id); //session id
out.writeUTF(_contextPath); //context path
out.writeUTF(_vhost); //first vhost
-
out.writeLong(_accessed);//accessTime
out.writeLong(_lastAccessed); //lastAccessTime
out.writeLong(_created); //time created
out.writeLong(_cookieSet);//time cookie was set
out.writeUTF(_lastNode); //name of last node managing
-
out.writeLong(_expiry);
out.writeLong(_maxInactiveMs);
- out.writeObject(_attributes);
+ serializeAttributes(this, out);
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException
{
_id = in.readUTF();
_contextPath = in.readUTF();
- _vhost = in.readUTF();
-
+ _vhost = in.readUTF();
_accessed = in.readLong();//accessTime
_lastAccessed = in.readLong(); //lastAccessTime
_created = in.readLong(); //time created
@@ -360,7 +438,7 @@ public class SessionData implements Serializable
_lastNode = in.readUTF(); //last managing node
_expiry = in.readLong();
_maxInactiveMs = in.readLong();
- _attributes = (Map)in.readObject();
+ deserializeAttributes(this, in);
}
public boolean isExpiredAt (long time)
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ClassLoadingObjectInputStream.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ClassLoadingObjectInputStream.java
index d3f2e1912ea..f7107e1fc11 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/ClassLoadingObjectInputStream.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ClassLoadingObjectInputStream.java
@@ -34,6 +34,20 @@ import java.lang.reflect.Proxy;
*/
public class ClassLoadingObjectInputStream extends ObjectInputStream
{
+
+ protected static class ClassLoaderThreadLocal extends ThreadLocal
+ {
+ protected static final ClassLoader UNSET = new ClassLoader() {};
+ @Override
+ protected ClassLoader initialValue()
+ {
+ return UNSET;
+ }
+
+ }
+
+ private ThreadLocal _classloader = new ClassLoaderThreadLocal();
+
/* ------------------------------------------------------------ */
public ClassLoadingObjectInputStream(java.io.InputStream in) throws IOException
{
@@ -46,13 +60,33 @@ public class ClassLoadingObjectInputStream extends ObjectInputStream
super();
}
+
+ public Object readObject (ClassLoader loader)
+ throws IOException, ClassNotFoundException
+ {
+ try
+ {
+ _classloader.set(loader);
+ return readObject();
+ }
+ finally
+ {
+ _classloader.set(ClassLoaderThreadLocal.UNSET);
+ }
+ }
+
+
/* ------------------------------------------------------------ */
@Override
public Class> resolveClass (java.io.ObjectStreamClass cl) throws IOException, ClassNotFoundException
{
try
{
- return Class.forName(cl.getName(), false, Thread.currentThread().getContextClassLoader());
+ ClassLoader loader = _classloader.get();
+ if (ClassLoaderThreadLocal.UNSET == loader)
+ loader = Thread.currentThread().getContextClassLoader();
+
+ return Class.forName(cl.getName(), false, loader);
}
catch (ClassNotFoundException e)
{
diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileTestHelper.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileTestHelper.java
index 320cd7f7f8b..6757dd8abcb 100644
--- a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileTestHelper.java
+++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileTestHelper.java
@@ -31,9 +31,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
@@ -161,9 +158,8 @@ public class FileTestHelper
{
String filename = ""+expiry+"_"+contextPath+"_"+vhost+"_"+id;
File file = new File(_tmpDir, filename);
- try(FileOutputStream fos = new FileOutputStream(file,false))
+ try (FileOutputStream fos = new FileOutputStream(file,false); DataOutputStream out = new DataOutputStream(fos))
{
- DataOutputStream out = new DataOutputStream(fos);
out.writeUTF(id);
out.writeUTF(contextPath);
out.writeUTF(vhost);
@@ -177,14 +173,9 @@ public class FileTestHelper
if (attributes != null)
{
- List keys = new ArrayList(attributes.keySet());
- out.writeInt(keys.size());
+ SessionData tmp = new SessionData(id,contextPath, vhost, created, accessed, lastAccessed, maxIdle);
ObjectOutputStream oos = new ObjectOutputStream(out);
- for (String name:keys)
- {
- oos.writeUTF(name);
- oos.writeObject(attributes.get(name));
- }
+ SessionData.serializeAttributes(tmp, oos);
}
}
}
@@ -197,10 +188,8 @@ public class FileTestHelper
File file = new File(_tmpDir, filename);
assertTrue(file.exists());
- try (FileInputStream in = new FileInputStream(file))
+ try (FileInputStream in = new FileInputStream(file); DataInputStream di = new DataInputStream(in))
{
- DataInputStream di = new DataInputStream(in);
-
String id = di.readUTF();
String contextPath = di.readUTF();
String vhost = di.readUTF();
@@ -223,28 +212,18 @@ public class FileTestHelper
assertEquals(data.getExpiry(), expiry);
assertEquals(data.getMaxInactiveMs(), maxIdle);
- Map attributes = new HashMap<>();
-
- int size = di.readInt();
- if (size > 0)
- {
- ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(di);
- for (int i=0; imaven-surefire-plugin
true
- GCloudTestSuite
diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredOrphanedSessionTest.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredOrphanedSessionTest.java
index fb192d31b60..6aea4e330cf 100644
--- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredOrphanedSessionTest.java
+++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredOrphanedSessionTest.java
@@ -45,16 +45,10 @@ public class ClusteredOrphanedSessionTest extends AbstractClusteredOrphanedSessi
@AfterAll
public static void tearDown () throws Exception
{
+ __testSupport.deleteSessions();
__testSupport.tearDown();
}
- @AfterAll
- public static void teardown () throws Exception
- {
- __testSupport.deleteSessions();
- }
-
-
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredSessionScavengingTest.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredSessionScavengingTest.java
index 31393388e63..b4be6a648f7 100644
--- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredSessionScavengingTest.java
+++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ClusteredSessionScavengingTest.java
@@ -43,14 +43,9 @@ public class ClusteredSessionScavengingTest extends AbstractClusteredSessionScav
@AfterAll
public static void tearDown () throws Exception
- {
- __testSupport.tearDown();
- }
-
- @AfterAll
- public static void teardown () throws Exception
{
__testSupport.deleteSessions();
+ __testSupport.tearDown();
}
diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTestSupport.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTestSupport.java
index 477524ed523..9842201f77c 100644
--- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTestSupport.java
+++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTestSupport.java
@@ -130,36 +130,37 @@ public class GCloudSessionTestSupport
long lastAccessed, long maxIdle, long expiry,
long cookieset, long lastSaved,
Map attributes)
- throws Exception
+ throws Exception
{
//serialize the attribute map
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- if (attributes != null)
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream())
{
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(attributes);
- oos.flush();
- }
+ if (attributes != null)
+ {
+ SessionData tmp = new SessionData(id, contextPath, vhost, created, accessed, lastAccessed, maxIdle);
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ SessionData.serializeAttributes(tmp, oos);
+ }
- //turn a session into an entity
- Entity.Builder builder = Entity.newBuilder(_keyFactory.newKey(contextPath+"_"+vhost+"_"+id))
- .set(EntityDataModel.ID, id)
- .set(EntityDataModel.CONTEXTPATH, contextPath)
- .set(EntityDataModel.VHOST, vhost)
- .set(EntityDataModel.ACCESSED, accessed)
- .set(EntityDataModel.LASTACCESSED, lastAccessed)
- .set(EntityDataModel.CREATETIME, created)
- .set(EntityDataModel.COOKIESETTIME, cookieset)
- .set(EntityDataModel.LASTNODE, lastNode)
- .set(EntityDataModel.EXPIRY, expiry)
- .set(EntityDataModel.MAXINACTIVE, maxIdle)
- .set(EntityDataModel.LASTSAVED, lastSaved);
- if (attributes != null)
+ //turn a session into an entity
+ Entity.Builder builder = Entity.newBuilder(_keyFactory.newKey(contextPath+"_"+vhost+"_"+id))
+ .set(EntityDataModel.ID, id)
+ .set(EntityDataModel.CONTEXTPATH, contextPath)
+ .set(EntityDataModel.VHOST, vhost)
+ .set(EntityDataModel.ACCESSED, accessed)
+ .set(EntityDataModel.LASTACCESSED, lastAccessed)
+ .set(EntityDataModel.CREATETIME, created)
+ .set(EntityDataModel.COOKIESETTIME, cookieset)
+ .set(EntityDataModel.LASTNODE, lastNode)
+ .set(EntityDataModel.EXPIRY, expiry)
+ .set(EntityDataModel.MAXINACTIVE, maxIdle)
+ .set(EntityDataModel.LASTSAVED, lastSaved);
+ if (attributes != null)
builder.set(EntityDataModel.ATTRIBUTES, BlobValue.newBuilder(Blob.copyFrom(baos.toByteArray())).setExcludeFromIndexes(true).build());
+ Entity entity = builder.build();
- Entity entity = builder.build();
-
- _ds.put(entity);
+ _ds.put(entity);
+ }
}
public boolean checkSessionPersisted (SessionData data)
@@ -183,21 +184,27 @@ public class GCloudSessionTestSupport
assertEquals(data.getMaxInactiveMs(), entity.getLong(EntityDataModel.MAXINACTIVE));
Blob blob = (Blob) entity.getBlob(EntityDataModel.ATTRIBUTES);
- Map attributes = new HashMap<>();
+ SessionData tmp = new SessionData(data.getId(),entity.getString(EntityDataModel.CONTEXTPATH),
+ entity.getString(EntityDataModel.VHOST),
+ entity.getLong(EntityDataModel.CREATETIME),
+ entity.getLong(EntityDataModel.ACCESSED),
+ entity.getLong(EntityDataModel.LASTACCESSED),
+ entity.getLong(EntityDataModel.MAXINACTIVE));
+
try (ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(blob.asInputStream()))
{
- Object o = ois.readObject();
- attributes.putAll((Map)o);
+ SessionData.deserializeAttributes(tmp, ois);
}
+
//same number of attributes
- assertEquals(data.getAllAttributes().size(), attributes.size());
+ assertEquals(data.getAllAttributes().size(), tmp.getAllAttributes().size());
//same keys
- assertTrue(data.getKeys().equals(attributes.keySet()));
+ assertTrue(data.getKeys().equals(tmp.getAllAttributes().keySet()));
//same values
for (String name:data.getKeys())
{
- assertTrue(data.getAttribute(name).equals(attributes.get(name)));
+ assertTrue(data.getAttribute(name).equals(tmp.getAttribute(name)));
}
return true;
diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/InvalidationSessionTest.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/InvalidationSessionTest.java
index 3e7809aa82a..837c7749524 100644
--- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/InvalidationSessionTest.java
+++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/InvalidationSessionTest.java
@@ -45,14 +45,10 @@ public class InvalidationSessionTest extends AbstractClusteredInvalidationSessio
@AfterAll
public static void tearDown () throws Exception
{
+ __testSupport.deleteSessions();
__testSupport.tearDown();
}
- @AfterAll
- public static void teardown () throws Exception
- {
- __testSupport.deleteSessions();
- }
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastTestHelper.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastTestHelper.java
index f36df160add..c76761aad5c 100644
--- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastTestHelper.java
+++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastTestHelper.java
@@ -27,6 +27,8 @@ import java.util.concurrent.TimeUnit;
import com.hazelcast.config.JoinConfig;
import com.hazelcast.config.MulticastConfig;
import com.hazelcast.config.NetworkConfig;
+import com.hazelcast.config.SerializerConfig;
+
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
@@ -45,12 +47,21 @@ public class HazelcastTestHelper
static final String _hazelcastInstanceName = "SESSION_TEST_"+Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()));
static final String _name = Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) );
- static final HazelcastInstance _instance = Hazelcast.getOrCreateHazelcastInstance( new Config() //
- .setInstanceName(_hazelcastInstanceName ) //
- .setNetworkConfig( new NetworkConfig().setJoin( //
- new JoinConfig().setMulticastConfig( //
- new MulticastConfig().setEnabled( false ) ) ) ) //
- .addMapConfig( new MapConfig().setName(_name) ) );
+
+ static SerializerConfig _serializerConfig;
+
+ static HazelcastInstance _instance;
+
+ static
+ {
+ _serializerConfig = new SerializerConfig().setImplementation(new SessionDataSerializer()).setTypeClass(SessionData.class);
+ Config config = new Config();
+ config.setInstanceName(_hazelcastInstanceName );
+ config.setNetworkConfig( new NetworkConfig().setJoin(new JoinConfig().setMulticastConfig(new MulticastConfig().setEnabled(false))));
+ config.addMapConfig(new MapConfig().setName(_name));
+ config.getSerializationConfig().addSerializerConfig(_serializerConfig);
+ _instance = Hazelcast.getOrCreateHazelcastInstance(config);
+ }
public HazelcastTestHelper ()
{
diff --git a/tests/test-sessions/test-infinispan-sessions/pom.xml b/tests/test-sessions/test-infinispan-sessions/pom.xml
index e218d29a188..674c92d13d0 100644
--- a/tests/test-sessions/test-infinispan-sessions/pom.xml
+++ b/tests/test-sessions/test-infinispan-sessions/pom.xml
@@ -11,6 +11,7 @@
http://www.eclipse.org/jetty${project.groupId}.sessions.infinispan
+ 127.0.0.1
@@ -114,6 +115,12 @@
9.1.0.Finaltest
+
+ org.infinispan
+ infinispan-remote-query-client
+ 9.1.0.Final
+ test
+
@@ -134,6 +141,9 @@
**/*.java
+
+ ${hotrod.host}
+
diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanTestSupport.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanTestSupport.java
index a960f2774fc..02e4faedd52 100644
--- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanTestSupport.java
+++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanTestSupport.java
@@ -21,10 +21,21 @@ package org.eclipse.jetty.server.session.remote;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.util.Properties;
import org.eclipse.jetty.server.session.SessionData;
+import org.eclipse.jetty.session.infinispan.InfinispanSessionData;
+import org.eclipse.jetty.session.infinispan.SessionDataMarshaller;
+import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller;
+import org.infinispan.protostream.FileDescriptorSource;
+import org.infinispan.protostream.SerializationContext;
+
+
/**
* RemoteInfinispanTestSupport
@@ -34,7 +45,7 @@ import org.infinispan.client.hotrod.RemoteCacheManager;
public class RemoteInfinispanTestSupport
{
public static final String DEFAULT_CACHE_NAME = "session_test_cache";
- public RemoteCache _cache;
+ public RemoteCache _cache;
private String _name;
public static RemoteCacheManager _manager;
@@ -42,11 +53,24 @@ public class RemoteInfinispanTestSupport
{
try
{
- _manager = new RemoteCacheManager();
+ String host = System.getProperty("hotrod.host","127.0.0.1");
+ Properties properties = new Properties();
+
+ ConfigurationBuilder clientBuilder = new ConfigurationBuilder();
+ clientBuilder.withProperties(properties).addServer().host(host).marshaller(new ProtoStreamMarshaller());
+
+ _manager = new RemoteCacheManager(clientBuilder.build());
+
+ FileDescriptorSource fds = new FileDescriptorSource();
+ fds.addProtoFiles("/session.proto");
+
+ SerializationContext serCtx = ProtoStreamMarshaller.getSerializationContext(_manager);
+ serCtx.registerProtoFiles(fds);
+ serCtx.registerMarshaller(new SessionDataMarshaller());
}
catch (Exception e)
{
- e.printStackTrace();
+ fail(e);
}
}
@@ -65,7 +89,7 @@ public class RemoteInfinispanTestSupport
- public RemoteCache getCache ()
+ public RemoteCache getCache ()
{
return _cache;
}
@@ -82,8 +106,7 @@ public class RemoteInfinispanTestSupport
}
-
- @SuppressWarnings("unchecked")
+
public void createSession (SessionData data)
throws Exception
{
@@ -111,7 +134,8 @@ public class RemoteInfinispanTestSupport
if (obj == null)
return false;
- SessionData saved = (SessionData)obj;
+ InfinispanSessionData saved = (InfinispanSessionData)obj;
+ saved.deserializeAttributes();
assertEquals(data.getId(), saved.getId());
assertEquals(data.getContextPath(), saved.getContextPath());
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestHelper.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestHelper.java
index 36e074efce9..73f6466dab4 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestHelper.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestHelper.java
@@ -210,24 +210,26 @@ public class JdbcTestHelper
assertEquals(data.getContextPath(), result.getString(CONTEXT_COL));
assertEquals(data.getVhost(), result.getString("virtualHost"));
- Map attributes = new HashMap<>();
Blob blob = result.getBlob(MAP_COL);
+ SessionData tmp = new SessionData(data.getId(), data.getContextPath(), data.getVhost(), result.getLong(CREATE_COL),
+ result.getLong(ACCESS_COL), result.getLong(LAST_ACCESS_COL),result.getLong(MAX_IDLE_COL));
+
try (InputStream is = blob.getBinaryStream();
ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is))
{
- Object o = ois.readObject();
- attributes.putAll((Map)o);
+
+ SessionData.deserializeAttributes(tmp, ois);
}
//same number of attributes
- assertEquals(data.getAllAttributes().size(), attributes.size());
+ assertEquals(data.getAllAttributes().size(), tmp.getAllAttributes().size());
//same keys
- assertTrue(data.getKeys().equals(attributes.keySet()));
+ assertTrue(data.getKeys().equals(tmp.getAllAttributes().keySet()));
//same values
for (String name:data.getKeys())
{
- assertTrue(data.getAttribute(name).equals(attributes.get(name)));
+ assertTrue(data.getAttribute(name).equals(tmp.getAttribute(name)));
}
}
finally
@@ -303,15 +305,18 @@ public class JdbcTestHelper
if (attributes != null)
{
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- Map emptyMap = Collections.emptyMap();
- oos.writeObject(emptyMap);
- oos.flush();
- byte[] bytes = baos.toByteArray();
+ SessionData tmp = new SessionData (id, contextPath, vhost, created, accessed, lastAccessed, maxIdle);
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);)
+ {
+ SessionData.serializeAttributes(tmp, oos);
+ byte[] bytes = baos.toByteArray();
- ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
- statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob
+ try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);)
+ {
+ statement.setBinaryStream(12, bais, bytes.length);
+ }
+ }
}
else
statement.setBinaryStream(12, new ByteArrayInputStream("".getBytes()), 0);
diff --git a/tests/test-sessions/test-memcached-sessions/pom.xml b/tests/test-sessions/test-memcached-sessions/pom.xml
index 5655c1e91cc..5e1bb72f753 100644
--- a/tests/test-sessions/test-memcached-sessions/pom.xml
+++ b/tests/test-sessions/test-memcached-sessions/pom.xml
@@ -62,6 +62,12 @@
jetty-test-helpertest
+
+ org.slf4j
+ slf4j-simple
+ 1.7.9
+ test
+
diff --git a/tests/test-sessions/test-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/sessions/MemcachedTestHelper.java b/tests/test-sessions/test-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/sessions/MemcachedTestHelper.java
index ebe3590bf37..49a02bcd38f 100644
--- a/tests/test-sessions/test-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/sessions/MemcachedTestHelper.java
+++ b/tests/test-sessions/test-memcached-sessions/src/test/java/org/eclipse/jetty/memcached/sessions/MemcachedTestHelper.java
@@ -48,29 +48,22 @@ public class MemcachedTestHelper
private int _loadCount = 0;
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
- */
@Override
public boolean isPassivating()
{
return true;
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
- */
+
@Override
public boolean exists(String id) throws Exception
{
return _store.get(id) != null;
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataMap#load(java.lang.String)
- */
+
@Override
- public SessionData load(String id) throws Exception
+ public SessionData doLoad(String id) throws Exception
{
_loadCount++;
return _store.get(id);
@@ -86,18 +79,12 @@ public class MemcachedTestHelper
return _loadCount;
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataMap#delete(java.lang.String)
- */
@Override
public boolean delete(String id) throws Exception
{
return (_store.remove(id) != null);
}
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
- */
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
{
@@ -105,9 +92,6 @@ public class MemcachedTestHelper
}
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doGetExpired(java.util.Set)
- */
@Override
public Set doGetExpired(Set candidates)
{
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreTest.java
index 7c2d6e61184..1fade684ab4 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreTest.java
@@ -19,11 +19,24 @@
package org.eclipse.jetty.nosql.mongodb;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jetty.server.session.AbstractSessionDataStoreFactory;
import org.eclipse.jetty.server.session.AbstractSessionDataStoreTest;
+import org.eclipse.jetty.server.session.SessionContext;
import org.eclipse.jetty.server.session.SessionData;
+import org.eclipse.jetty.server.session.SessionDataStore;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
+import org.eclipse.jetty.servlet.ServletContextHandler;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
/**
* MongoSessionDataStoreTest
@@ -81,4 +94,55 @@ public class MongoSessionDataStoreTest extends AbstractSessionDataStoreTest
{
return MongoTestHelper.checkSessionPersisted(data);
}
+
+
+ /**
+ * Test that a session stored in the legacy attribute
+ * format can be read.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testReadLegacySession() throws Exception
+ {
+ //create the SessionDataStore
+ ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
+ context.setContextPath("/legacy");
+ SessionDataStoreFactory factory = createSessionDataStoreFactory();
+ ((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
+ SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
+ SessionContext sessionContext = new SessionContext("foo", context.getServletContext());
+ store.initialize(sessionContext);
+
+ //persist an old-style session
+
+ Map attributes = new HashMap<>();
+ attributes.put("attribute1", "attribute1value");
+ attributes.put("attribute2", new ArrayList(Arrays.asList("1", "2", "3")));
+ MongoTestHelper.createLegacySession("1234",
+ sessionContext.getCanonicalContextPath(), sessionContext.getVhost(),
+ "foo",
+ 1000L, System.currentTimeMillis()-1000L, System.currentTimeMillis()-2000L,
+ -1, -1,
+ attributes );
+
+ store.start();
+
+ //test that we can retrieve it
+ SessionData loaded = store.load("1234");
+ assertNotNull(loaded);
+ assertEquals("1234", loaded.getId());
+ assertEquals(1000L, loaded.getCreated());
+
+ assertEquals("attribute1value", loaded.getAttribute("attribute1"));
+ assertNotNull(loaded.getAttribute("attribute2"));
+
+
+ //test that we can write it
+ store.store("1234", loaded);
+
+ //and that it has now been written out with the new format
+ MongoTestHelper.checkSessionPersisted(loaded);
+
+ }
}
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoTestHelper.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoTestHelper.java
index cd5698257e3..47c536ff7cc 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoTestHelper.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoTestHelper.java
@@ -22,26 +22,23 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
-import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.UnknownHostException;
-import java.sql.Date;
-import java.util.HashMap;
import java.util.Map;
-import com.mongodb.MongoClient;
-import org.eclipse.jetty.nosql.NoSqlSessionDataStore.NoSqlSessionData;
import org.eclipse.jetty.server.session.SessionData;
+import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
-import com.mongodb.Mongo;
+import com.mongodb.MongoClient;
import com.mongodb.MongoException;
import com.mongodb.WriteConcern;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
/**
@@ -148,10 +145,9 @@ public class MongoTestHelper
MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath() +"."+MongoSessionDataStore.__LASTSAVED);
String lastNode = (String)MongoUtils.getNestedValue(sessionDocument,
MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath() +"."+MongoSessionDataStore.__LASTNODE);
-
+ byte[] attributes = (byte[])MongoUtils.getNestedValue(sessionDocument,
+ MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath() +"."+MongoSessionDataStore.__ATTRIBUTES);
- LOG.info("DA:{} MA:{}", data.getAccessed(), accessed);
- LOG.info("DLA:{} DLA:{}",data.getLastAccessed(),lastAccessed);
assertEquals(data.getCreated(), created.longValue());
assertEquals(data.getAccessed(), accessed.longValue());
assertEquals(data.getLastAccessed(), lastAccessed.longValue());
@@ -168,26 +164,24 @@ public class MongoTestHelper
assertNotNull(sessionSubDocumentForContext);
- Map attributes = new HashMap<>();
- for (String name : sessionSubDocumentForContext.keySet())
+ if (! data.getAllAttributes().isEmpty())
{
- //skip special metadata attribute which is not one of the actual session attributes
- if (MongoSessionDataStore.__METADATA.equals(name) )
- continue;
- String attr = MongoUtils.decodeName(name);
- Object value = MongoUtils.decodeValue(sessionSubDocumentForContext.get(name));
- attributes.put(attr, value);
+ assertNotNull(attributes);
+ SessionData tmp = new SessionData(data.getId(), data.getContextPath(), data.getVhost(), created.longValue(), accessed.longValue(), lastAccessed.longValue(), maxInactive.longValue());
+ try (ByteArrayInputStream bais = new ByteArrayInputStream(attributes);ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(bais))
+ {
+ SessionData.deserializeAttributes(tmp, ois);
+ }
+
+ //same keys
+ assertTrue(data.getKeys().equals(tmp.getKeys()));
+ //same values
+ for (String name:data.getKeys())
+ {
+ assertTrue(data.getAttribute(name).equals(tmp.getAttribute(name)));
+ }
}
- //same keys
- assertTrue(data.getKeys().equals(attributes.keySet()));
- //same values
- for (String name:data.getKeys())
- {
- assertTrue(data.getAttribute(name).equals(attributes.get(name)));
- }
-
-
return true;
}
@@ -226,17 +220,18 @@ public class MongoTestHelper
if (attributes != null)
{
- for (String name : attributes.keySet())
+ SessionData tmp = new SessionData (id, contextPath, vhost, created, accessed, lastAccessed, maxIdle, attributes);
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos))
{
- Object value = attributes.get(name);
- sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath+ "." + MongoUtils.encodeName(name),
- MongoUtils.encodeName(value));
+ SessionData.serializeAttributes(tmp, oos);
+ sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath +"."+MongoSessionDataStore.__ATTRIBUTES, baos.toByteArray());
}
}
+
update.put("$set",sets);
collection.update(key,update,upsert,false,WriteConcern.SAFE);
}
-
+
public static void createSession (String id, String contextPath, String vhost,
String lastNode, long created, long accessed,
@@ -269,6 +264,53 @@ public class MongoTestHelper
sets.put(MongoSessionDataStore.__ACCESSED, accessed);
sets.put(MongoSessionDataStore.__LAST_ACCESSED, lastAccessed);
+ if (attributes != null)
+ {
+ SessionData tmp = new SessionData (id, contextPath, vhost, created, accessed, lastAccessed, maxIdle, attributes);
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);)
+ {
+ SessionData.serializeAttributes(tmp, oos);
+ sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath +"."+MongoSessionDataStore.__ATTRIBUTES, baos.toByteArray());
+ }
+ }
+
+ update.put("$set",sets);
+ collection.update(key,update,upsert,false,WriteConcern.SAFE);
+ }
+
+
+ public static void createLegacySession (String id, String contextPath, String vhost,
+ String lastNode, long created, long accessed,
+ long lastAccessed, long maxIdle, long expiry,
+ Map attributes)
+ throws Exception
+ {
+ //make old-style session to test if we can retrieve it
+ DBCollection collection = _mongoClient.getDB(DB_NAME).getCollection(COLLECTION_NAME);
+
+ // Form query for upsert
+ BasicDBObject key = new BasicDBObject(MongoSessionDataStore.__ID, id);
+
+ // Form updates
+ BasicDBObject update = new BasicDBObject();
+ boolean upsert = false;
+ BasicDBObject sets = new BasicDBObject();
+
+ Object version = new Long(1);
+
+ // New session
+ upsert = true;
+ sets.put(MongoSessionDataStore.__CREATED,created);
+ sets.put(MongoSessionDataStore.__VALID,true);
+ sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath +"."+MongoSessionDataStore.__VERSION,version);
+ sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath +"."+MongoSessionDataStore.__LASTSAVED, System.currentTimeMillis());
+ sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath +"."+MongoSessionDataStore.__LASTNODE, lastNode);
+ sets.put(MongoSessionDataStore.__MAX_IDLE, maxIdle);
+ sets.put(MongoSessionDataStore.__EXPIRY, expiry);
+ sets.put(MongoSessionDataStore.__ACCESSED, accessed);
+ sets.put(MongoSessionDataStore.__LAST_ACCESSED, lastAccessed);
+
if (attributes != null)
{
for (String name : attributes.keySet())
@@ -281,9 +323,4 @@ public class MongoTestHelper
update.put("$set",sets);
collection.update(key,update,upsert,false,WriteConcern.SAFE);
}
-
-
-
-
-
}
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionDataStore.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionDataStore.java
index cdd5f468a3a..20baeb75033 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionDataStore.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestSessionDataStore.java
@@ -63,7 +63,7 @@ public class TestSessionDataStore extends AbstractSessionDataStore
@Override
- public SessionData load(String id) throws Exception
+ public SessionData doLoad(String id) throws Exception
{
SessionData sd = _map.get(id);
if (sd == null)
diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DeleteUnloadableSessionTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DeleteUnloadableSessionTest.java
index 54aa6e71546..1565fb3f96b 100644
--- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DeleteUnloadableSessionTest.java
+++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/DeleteUnloadableSessionTest.java
@@ -65,37 +65,29 @@ public class DeleteUnloadableSessionTest
String unloadableId = null;
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
- */
+
@Override
public boolean isPassivating()
{
return true;
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
- */
+
@Override
public boolean exists(String id) throws Exception
{
return o != null;
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataMap#load(java.lang.String)
- */
+
@Override
- public SessionData load(String id) throws Exception
+ public SessionData doLoad(String id) throws Exception
{
unloadableId = id;
throw new UnreadableSessionDataException(id, null, new Exception("fake"));
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataMap#delete(java.lang.String)
- */
+
@Override
public boolean delete(String id) throws Exception
{
@@ -107,18 +99,14 @@ public class DeleteUnloadableSessionTest
return false;
}
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
- */
+
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
{
//pretend it was saved
}
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doGetExpired(java.util.Set)
- */
+
@Override
public Set doGetExpired(Set candidates)
{
diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionEvictionFailureTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionEvictionFailureTest.java
index f9fde56b1bb..27687b4c82a 100644
--- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionEvictionFailureTest.java
+++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionEvictionFailureTest.java
@@ -67,45 +67,33 @@ public class SessionEvictionFailureTest
_nextStoreResult = results;
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
- */
@Override
public boolean isPassivating()
{
return false;
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
- */
+
@Override
public boolean exists(String id) throws Exception
{
return true;
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataMap#load(java.lang.String)
- */
+
@Override
- public SessionData load(String id) throws Exception
+ public SessionData doLoad(String id) throws Exception
{
return null;
}
- /**
- * @see org.eclipse.jetty.server.session.SessionDataMap#delete(java.lang.String)
- */
@Override
public boolean delete(String id) throws Exception
{
return false;
}
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
- */
+
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
{
@@ -115,9 +103,6 @@ public class SessionEvictionFailureTest
}
}
- /**
- * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doGetExpired(java.util.Set)
- */
@Override
public Set doGetExpired(Set candidates)
{
diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SessionDump.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SessionDump.java
index 3756043714d..f2ca605a78f 100644
--- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SessionDump.java
+++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SessionDump.java
@@ -31,6 +31,8 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
+import org.eclipse.jetty.util.MultiMap;
+
/**
* Test Servlet Sessions.
*/
@@ -83,6 +85,7 @@ public class SessionDump extends HttpServlet
session = request.getSession(true);
session.setAttribute("test","value");
session.setAttribute("obj", new ObjectAttributeValue(System.currentTimeMillis()));
+ session.setAttribute("WEBCL", new MultiMap());
}
else if (session!=null)
{
@@ -140,6 +143,8 @@ public class SessionDump extends HttpServlet
}
else
{
+ if (session.getAttribute("WEBCL") == null)
+ session.setAttribute("WEBCL", new MultiMap());
try
{
out.println("ID: "+session.getId()+" ");
From 557f40f41fb50bd07caaa4fa65c5f0a27a5601a2 Mon Sep 17 00:00:00 2001
From: Lachlan Roberts
Date: Tue, 6 Nov 2018 11:46:26 +0100
Subject: [PATCH 129/931] Issue #113 - CustomRequestLog
created new CustomRequestLog class
Signed-off-by: Lachlan Roberts
---
.../requestlog/jmh/RequestLogBenchmark.java | 24 +-
.../jetty/server/CustomRequestLog.java | 436 ++++++++++++++++++
.../server/handler/CustomRequestLogTest.java | 122 +++++
3 files changed, 566 insertions(+), 16 deletions(-)
create mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java
create mode 100644 jetty-server/src/test/java/org/eclipse/jetty/server/handler/CustomRequestLogTest.java
diff --git a/jetty-jmh/src/main/java/org/eclipse/jetty/requestlog/jmh/RequestLogBenchmark.java b/jetty-jmh/src/main/java/org/eclipse/jetty/requestlog/jmh/RequestLogBenchmark.java
index 9092a5fca6f..7058b0d2045 100644
--- a/jetty-jmh/src/main/java/org/eclipse/jetty/requestlog/jmh/RequestLogBenchmark.java
+++ b/jetty-jmh/src/main/java/org/eclipse/jetty/requestlog/jmh/RequestLogBenchmark.java
@@ -18,10 +18,6 @@
package org.eclipse.jetty.requestlog.jmh;
-import static java.lang.invoke.MethodHandles.dropArguments;
-import static java.lang.invoke.MethodHandles.foldArguments;
-import static java.lang.invoke.MethodType.methodType;
-
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
@@ -43,6 +39,10 @@ import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
+import static java.lang.invoke.MethodHandles.dropArguments;
+import static java.lang.invoke.MethodHandles.foldArguments;
+import static java.lang.invoke.MethodType.methodType;
+
@State(Scope.Benchmark)
@@ -79,14 +79,7 @@ public class RequestLogBenchmark
}
}
- private ThreadLocal buffers = new ThreadLocal()
- {
- @Override
- protected StringBuilder initialValue()
- {
- return new StringBuilder(256);
- }
- };
+ private ThreadLocal buffers = ThreadLocal.withInitial(() -> new StringBuilder(256));
MethodHandle logHandle;
Object[] iteratedLog;
@@ -96,8 +89,7 @@ public class RequestLogBenchmark
{
MethodType logType = methodType(Void.TYPE, StringBuilder.class, String.class);
- MethodHandle append = MethodHandles.lookup()
- .findStatic(RequestLogBenchmark.class, "append", methodType(Void.TYPE, String.class, StringBuilder.class));
+ MethodHandle append = MethodHandles.lookup().findStatic(RequestLogBenchmark.class, "append", methodType(Void.TYPE, String.class, StringBuilder.class));
MethodHandle logURI = MethodHandles.lookup().findStatic(RequestLogBenchmark.class, "logURI", logType);
MethodHandle logAddr = MethodHandles.lookup().findStatic(RequestLogBenchmark.class, "logAddr", logType);
MethodHandle logLength = MethodHandles.lookup().findStatic(RequestLogBenchmark.class, "logLength", logType);
@@ -171,7 +163,7 @@ public class RequestLogBenchmark
try
{
StringBuilder b = buffers.get();
- logHandle.invoke(buffers.get(), request);
+ logHandle.invoke(b, request);
String l = b.toString();
b.setLength(0);
return l;
@@ -202,7 +194,7 @@ public class RequestLogBenchmark
public String testHandle()
{
return logMethodHandle(Long.toString(ThreadLocalRandom.current().nextLong()));
- };
+ }
public static void main(String[] args) throws RunnerException
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java b/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java
new file mode 100644
index 00000000000..e0beb211a9d
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java
@@ -0,0 +1,436 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2018 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.server;
+
+import java.io.IOException;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.jetty.http.pathmap.PathMappings;
+import org.eclipse.jetty.util.DateCache;
+import org.eclipse.jetty.util.annotation.ManagedAttribute;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+import static java.lang.invoke.MethodHandles.dropArguments;
+import static java.lang.invoke.MethodHandles.foldArguments;
+import static java.lang.invoke.MethodType.methodType;
+
+public class CustomRequestLog extends AbstractLifeCycle implements RequestLog
+{
+ protected static final Logger LOG = Log.getLogger(CustomRequestLog.class);
+
+ private static ThreadLocal _buffers = ThreadLocal.withInitial(() -> new StringBuilder(256));
+
+ private String[] _ignorePaths;
+ private boolean _extended;
+ private transient PathMappings _ignorePathMap;
+ private boolean _preferProxiedForAddress;
+ private transient DateCache _logDateCache;
+ private String _logDateFormat = "dd/MMM/yyyy:HH:mm:ss Z";
+ private Locale _logLocale = Locale.getDefault();
+ private String _logTimeZone = "GMT";
+
+ private final MethodHandle _logHandle;
+ private final String _format;
+
+ public CustomRequestLog(String formatString)
+ {
+ try
+ {
+ _format = formatString;
+ _logHandle = getLogHandle(formatString);
+ }
+ catch (Throwable t)
+ {
+ throw new IllegalStateException();
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+
+ /**
+ * Is logging enabled
+ * @return true if logging is enabled
+ */
+ protected boolean isEnabled()
+ {
+ return true;
+ }
+
+ /* ------------------------------------------------------------ */
+
+ /**
+ * Write requestEntry out. (to disk or slf4j log)
+ * @param requestEntry the request entry
+ * @throws IOException if unable to write the entry
+ */
+ protected void write(String requestEntry) throws IOException
+ {
+ }
+
+ /* ------------------------------------------------------------ */
+
+
+ /**
+ * Writes the request and response information to the output stream.
+ *
+ * @see org.eclipse.jetty.server.RequestLog#log(Request, Response)
+ */
+ @Override
+ public void log(Request request, Response response)
+ {
+ try
+ {
+ if (_ignorePathMap != null && _ignorePathMap.getMatch(request.getRequestURI()) != null)
+ return;
+
+ if (!isEnabled())
+ return;
+
+ StringBuilder sb = _buffers.get();
+ sb.setLength(0);
+
+ _logHandle.invoke(sb, request);
+
+ String log = sb.toString();
+ write(log);
+ }
+ catch (Throwable e)
+ {
+ LOG.warn(e);
+ }
+ }
+
+ /**
+ * Extract the user authentication
+ * @param request The request to extract from
+ * @return The string to log for authenticated user.
+ */
+ protected String getAuthentication(Request request)
+ {
+ Authentication authentication = request.getAuthentication();
+
+ if (authentication instanceof Authentication.User)
+ return ((Authentication.User)authentication).getUserIdentity().getUserPrincipal().getName();
+
+ // TODO extract the user name if it is Authentication.Deferred and return as '?username'
+
+ return null;
+ }
+
+ /**
+ * Set request paths that will not be logged.
+ *
+ * @param ignorePaths array of request paths
+ */
+ public void setIgnorePaths(String[] ignorePaths)
+ {
+ _ignorePaths = ignorePaths;
+ }
+
+ /**
+ * Retrieve the request paths that will not be logged.
+ *
+ * @return array of request paths
+ */
+ public String[] getIgnorePaths()
+ {
+ return _ignorePaths;
+ }
+
+ /**
+ * Controls whether the actual IP address of the connection or the IP address from the X-Forwarded-For header will
+ * be logged.
+ *
+ * @param preferProxiedForAddress true - IP address from header will be logged, false - IP address from the
+ * connection will be logged
+ */
+ public void setPreferProxiedForAddress(boolean preferProxiedForAddress)
+ {
+ _preferProxiedForAddress = preferProxiedForAddress;
+ }
+
+ /**
+ * Retrieved log X-Forwarded-For IP address flag.
+ *
+ * @return value of the flag
+ */
+ public boolean getPreferProxiedForAddress()
+ {
+ return _preferProxiedForAddress;
+ }
+
+ /**
+ * Set the extended request log format flag.
+ *
+ * @param extended true - log the extended request information, false - do not log the extended request information
+ */
+ public void setExtended(boolean extended)
+ {
+ _extended = extended;
+ }
+
+ /**
+ * Retrieve the extended request log format flag.
+ *
+ * @return value of the flag
+ */
+ @ManagedAttribute("use extended NCSA format")
+ public boolean isExtended()
+ {
+ return _extended;
+ }
+
+ /**
+ * Set up request logging and open log file.
+ *
+ * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
+ */
+ @Override
+ protected synchronized void doStart() throws Exception
+ {
+ if (_logDateFormat != null)
+ {
+ _logDateCache = new DateCache(_logDateFormat, _logLocale ,_logTimeZone);
+ }
+
+ if (_ignorePaths != null && _ignorePaths.length > 0)
+ {
+ _ignorePathMap = new PathMappings<>();
+ for (int i = 0; i < _ignorePaths.length; i++)
+ _ignorePathMap.put(_ignorePaths[i], _ignorePaths[i]);
+ }
+ else
+ _ignorePathMap = null;
+
+ super.doStart();
+ }
+
+ @Override
+ protected void doStop() throws Exception
+ {
+ _logDateCache = null;
+ super.doStop();
+ }
+
+ /**
+ * Set the timestamp format for request log entries in the file. If this is not set, the pre-formated request
+ * timestamp is used.
+ *
+ * @param format timestamp format string
+ */
+ public void setLogDateFormat(String format)
+ {
+ _logDateFormat = format;
+ }
+
+ /**
+ * Retrieve the timestamp format string for request log entries.
+ *
+ * @return timestamp format string.
+ */
+ public String getLogDateFormat()
+ {
+ return _logDateFormat;
+ }
+
+ /**
+ * Set the locale of the request log.
+ *
+ * @param logLocale locale object
+ */
+ public void setLogLocale(Locale logLocale)
+ {
+ _logLocale = logLocale;
+ }
+
+ /**
+ * Retrieve the locale of the request log.
+ *
+ * @return locale object
+ */
+ public Locale getLogLocale()
+ {
+ return _logLocale;
+ }
+
+ /**
+ * Set the timezone of the request log.
+ *
+ * @param tz timezone string
+ */
+ public void setLogTimeZone(String tz)
+ {
+ _logTimeZone = tz;
+ }
+
+ /**
+ * Retrieve the timezone of the request log.
+ *
+ * @return timezone string
+ */
+ @ManagedAttribute("the timezone")
+ public String getLogTimeZone()
+ {
+ return _logTimeZone;
+ }
+
+
+ private static void append(StringBuilder buf, String s)
+ {
+ if (s==null || s.length()==0)
+ buf.append('-');
+ else
+ buf.append(s);
+ }
+
+ private static void append(String s, StringBuilder buf)
+ {
+ append(buf, s);
+ }
+
+ public static void logClientIP(StringBuilder b, Request request)
+ {
+ b.append(request.getRemoteAddr());
+ }
+
+ public static void main(String[] args) throws Throwable
+ {
+ Request request = new Request(null, null);
+
+
+ String formatString = "clientIP: %a | ";
+ MethodHandle logHandle = getLogHandle(formatString);
+
+
+ StringBuilder b = new StringBuilder();
+ logHandle.invoke(b, request);
+ System.err.println(b.toString());
+
+ }
+
+ private static MethodHandle getLogHandle(String formatString) throws NoSuchMethodException, IllegalAccessException
+ {
+ //TODO add response to signature
+ MethodType logType = methodType(Void.TYPE, StringBuilder.class, Request.class);
+ MethodHandle append = MethodHandles.lookup().findStatic(CustomRequestLog.class, "append", methodType(Void.TYPE, String.class, StringBuilder.class));
+ MethodHandle logHandle = dropArguments(append.bindTo("\n"), 1, Request.class);
+
+ for (Token s : tokenize(formatString))
+ {
+ if (s.isLiteralString())
+ {
+ logHandle = foldArguments(logHandle, dropArguments(append.bindTo(s.literal), 1, Request.class));
+ }
+ else
+ {
+ switch (s.code)
+ {
+
+ case "a":
+ {
+ String method = "logClientIP";
+ MethodHandle specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType);
+ logHandle = foldArguments(logHandle, specificHandle);
+ break;
+ }
+ }
+ }
+ }
+
+ return logHandle;
+ }
+
+ private static List tokenize(String value)
+ {
+ List tokens = new ArrayList<>();
+
+ final Pattern PERCENT_CODE = Pattern.compile("(?.*)%(?:\\{(?[^{}]+)})?(?[a-zA-Z%])");
+ final Pattern LITERAL = Pattern.compile("(?.*%(?:\\{[^{}]+})?[a-zA-Z%])(?.*)");
+
+ while(value.length()>0)
+ {
+ Matcher m = PERCENT_CODE.matcher(value);
+ Matcher m2 = LITERAL.matcher(value);
+ if (m.matches())
+ {
+ String code = m.group("code");
+ String arg = m.group("arg");
+
+ tokens.add(new Token(code, arg));
+ value = m.group("remaining");
+ continue;
+ }
+
+ String literal;
+ if (m2.matches())
+ {
+ literal = m2.group("literal");
+ value = m2.group("remaining");
+ }
+ else
+ {
+ literal = value;
+ value = "";
+ }
+ tokens.add(new Token(literal));
+
+ }
+ return tokens;
+ }
+
+
+
+
+ private static class Token
+ {
+ public boolean isLiteralString()
+ {
+ return(literal != null);
+ }
+
+ public boolean isPercentCode()
+ {
+ return(code != null);
+ }
+
+ public String code = null;
+ public String arg = null;
+ public String literal = null;
+
+ public Token(String code, String arg)
+ {
+ this.code = code;
+ this.arg = arg;
+ }
+
+ public Token(String literal)
+ {
+ this.literal = literal;
+ }
+ }
+}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/CustomRequestLogTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/CustomRequestLogTest.java
new file mode 100644
index 00000000000..6556508a4de
--- /dev/null
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/CustomRequestLogTest.java
@@ -0,0 +1,122 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2018 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.server.handler;
+
+import java.io.IOException;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.CustomRequestLog;
+import org.eclipse.jetty.server.LocalConnector;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.BlockingArrayQueue;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+
+public class CustomRequestLogTest
+{
+ Log _log;
+ Server _server;
+ LocalConnector _connector;
+
+
+ @BeforeEach
+ public void before() throws Exception
+ {
+ _server = new Server();
+ _connector = new LocalConnector(_server);
+ _server.addConnector(_connector);
+
+ }
+
+ void testHandlerServerStart(String formatString) throws Exception
+ {
+ _log = new Log(formatString);
+ _server.setRequestLog(_log);
+ _server.setHandler(new TestHandler());
+ _server.start();
+ }
+
+ @AfterEach
+ public void after() throws Exception
+ {
+ _server.stop();
+ }
+
+
+ @Test
+ public void testQuery() throws Exception
+ {
+ testHandlerServerStart("clientIP: %a");
+
+ _connector.getResponse("GET /foo?name=value HTTP/1.0\n\n");
+ String log = _log.entries.poll(5,TimeUnit.SECONDS);
+ assertThat(log,containsString("GET /foo?name=value"));
+ assertThat(log,containsString(" 200 "));
+ }
+
+
+
+
+ private class Log extends CustomRequestLog
+ {
+ public BlockingQueue entries = new BlockingArrayQueue<>();
+
+ public Log(String formatString)
+ {
+ super(formatString);
+ }
+
+ @Override
+ protected boolean isEnabled()
+ {
+ return true;
+ }
+
+ @Override
+ public void write(String requestEntry) throws IOException
+ {
+ try
+ {
+ entries.add(requestEntry);
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private class TestHandler extends AbstractHandler
+ {
+ @Override
+ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ {
+ baseRequest.setHandled(true);
+ }
+ }
+}
From 012d412ccb40c4545f0c54bdd0bdd2a63aa74bbb Mon Sep 17 00:00:00 2001
From: Lachlan Roberts
Date: Tue, 6 Nov 2018 11:48:08 +0100
Subject: [PATCH 130/931] Issue #113 - CustomRequestLog
javadoc detailing the custom log formats
Signed-off-by: Lachlan Roberts
---
.../jetty/server/CustomRequestLog.java | 231 ++++++++++++++++++
1 file changed, 231 insertions(+)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java b/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java
index e0beb211a9d..16f1f2c7fa1 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java
@@ -39,6 +39,237 @@ import static java.lang.invoke.MethodHandles.dropArguments;
import static java.lang.invoke.MethodHandles.foldArguments;
import static java.lang.invoke.MethodType.methodType;
+/**
+
+
+
Format String
+
Description
+
+
+
+
%%
+
The percent sign.
+
+
+
+
%a
+
Client IP address of the request.
+
+
+
+
%{c}a
+
Underlying peer IP address of the connection.
+
+
+
+
%A
+
Local IP-address.
+
+
+
+
%B
+
Size of response in bytes, excluding HTTP headers.
+
+
+
+
%b
+
Size of response in bytes, excluding HTTP headers. In CLF format, i.e. a '-' rather than a 0 when no bytes are sent.
+
+
+
+
%{VARNAME}C
+
The contents of cookie VARNAME in the request sent to the server. Only version 0 cookies are fully supported.
+
+
+
+
%D
+
The time taken to serve the request, in microseconds.
+
+
+
+
%{VARNAME}e
+
The contents of the environment variable VARNAME.
+
+
+
+
%f
+
Filename.
+
+
+
+
%h
+
Remote hostname. Will log the IP address if HostnameLookups is set to Off, which is the default. If it logs the hostname for only a few hosts, you probably have access control directives mentioning them by name. See the Require host documentation.
+
+
+
+
%H
+
The request protocol.
+
+
+
+
%{VARNAME}i
+
The contents of VARNAME: header line(s) in the request sent to the server. Changes made by other modules (e.g. mod_headers) affect this. If you're interested in what the request header was prior to when most modules would have modified it, use mod_setenvif to copy the header into an internal environment variable and log that value with the %{VARNAME}e described above.
+
+
+
+
%k
+
Number of keepalive requests handled on this connection. Interesting if KeepAlive is being used, so that, for example, a '1' means the first keepalive request after the initial one, '2' the second, etc...; otherwise this is always 0 (indicating the initial request).
+
+
+
+
%l
+
Remote logname (from identd, if supplied). This will return a dash unless mod_ident is present and IdentityCheck is set On.
+
+
+
+
%L
+
The request log ID from the error log (or '-' if nothing has been logged to the error log for this request). Look for the matching error log line to see what request caused what error.
+
+
+
+
%m
+
The request method.
+
+
+
+
%{VARNAME}n
+
The contents of note VARNAME from another module.
+
+
+
+
%{VARNAME}o
+
The contents of VARNAME: header line(s) in the reply.
+
+
+
+
%p
+
The canonical port of the server serving the request.
+
+
+
+
%{format}p
+
The canonical port of the server serving the request, or the server's actual port, or the client's actual port. Valid formats are canonical, local, or remote.
+
+
+
+
%P
+
The process ID of the child that serviced the request.
+
+
+
+
%{format}P
+
The process ID or thread ID of the child that serviced the request. Valid formats are pid, tid, and hextid. hextid requires APR 1.2.0 or higher.
+
+
+
+
%q
+
The query string (prepended with a ? if a query string exists, otherwise an empty string).
+
+
+
+
%r
+
First line of request.
+
+
+
+
%R
+
The handler generating the response (if any).
+
+
+
+
%s
+
Status. For requests that have been internally redirected, this is the status of the original request. Use %>s for the final status.
+
+
+
+
%t
+
Time the request was received, in the format [18/Sep/2011:19:18:28 -0400]. The last number indicates the timezone offset from GMT
+
+
+
+
%{format}t
+
+ The time, in the form given by format, which should be in an extended strftime(3) format (potentially localized). If the format starts with begin: (default) the time is taken at the beginning of the request processing. If it starts with end: it is the time when the log entry gets written, close to the end of the request processing.
+
+
In addition to the formats supported by strftime(3), the following format tokens are supported:
+
+
+ sec number of seconds since the Epoch
+ msec number of milliseconds since the Epoch
+ usec number of microseconds since the Epoch
+ msec_frac millisecond fraction
+ usec_frac microsecond fraction
+
+
+ These tokens can not be combined with each other or strftime(3) formatting in the same format string. You can use multiple %{format}t tokens instead.
+
+
+
+
+
%T
+
The time taken to serve the request, in seconds.
+
+
+
+
%{UNIT}T
+
The time taken to serve the request, in a time unit given by UNIT. Valid units are ms for milliseconds, us for microseconds, and s for seconds. Using s gives the same result as %T without any format; using us gives the same result as %D. Combining %T with a unit is available in 2.4.13 and later.
+
+
+
+
%u
+
Remote user if the request was authenticated. May be bogus if return status (%s) is 401 (unauthorized).
+
+
+
+
%U
+
The URL path requested, not including any query string.
+
+
+
+
%v
+
The canonical ServerName of the server serving the request.
+
+
+
+
%V
+
The server name according to the UseCanonicalName setting.
+
+
+
+
%X
+
Connection status when response is completed:
+ X = Connection aborted before the response completed.
+ + = Connection may be kept alive after the response is sent.
+ - = Connection will be closed after the response is sent.
+
+
+
+
%I
+
Bytes received, including request and headers. Cannot be zero. You need to enable mod_logio to use this.
+
+
+
+
%O
+
Bytes sent, including headers. May be zero in rare cases such as when a request is aborted before a response is sent. You need to enable mod_logio to use this.
+
+
+
+
%S
+
Bytes transferred (received and sent), including request and headers, cannot be zero. This is the combination of %I and %O. You need to enable mod_logio to use this.
+
+
+
+
%{VARNAME}^ti
+
The contents of VARNAME: trailer line(s) in the request sent to the server.
+
+
+
+
%{VARNAME}^to
+
The contents of VARNAME: trailer line(s) in the response sent from the server.
+
+
+
+ */
public class CustomRequestLog extends AbstractLifeCycle implements RequestLog
{
protected static final Logger LOG = Log.getLogger(CustomRequestLog.class);
From 4be4b4e7b48b986f1fc934abe561cef81144e41b Mon Sep 17 00:00:00 2001
From: Lachlan Roberts
Date: Tue, 6 Nov 2018 12:16:22 +0100
Subject: [PATCH 131/931] Issue #113 - CustomRequestLog
update logHandle directly rather than creating list of tokens
Signed-off-by: Lachlan Roberts
---
.../jetty/server/CustomRequestLog.java | 118 +++++-------------
1 file changed, 33 insertions(+), 85 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java b/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java
index 16f1f2c7fa1..f0cb7d45556 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java
@@ -22,8 +22,6 @@ import java.io.IOException;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -286,18 +284,16 @@ public class CustomRequestLog extends AbstractLifeCycle implements RequestLog
private String _logTimeZone = "GMT";
private final MethodHandle _logHandle;
- private final String _format;
public CustomRequestLog(String formatString)
{
try
{
- _format = formatString;
_logHandle = getLogHandle(formatString);
}
catch (Throwable t)
{
- throw new IllegalStateException();
+ throw new IllegalStateException(t);
}
}
@@ -549,119 +545,71 @@ public class CustomRequestLog extends AbstractLifeCycle implements RequestLog
b.append(request.getRemoteAddr());
}
- public static void main(String[] args) throws Throwable
+
+ //TODO add response to signature
+ private static final MethodType LOG_TYPE = methodType(Void.TYPE, StringBuilder.class, Request.class);
+
+ private MethodHandle getLogHandle(String formatString) throws Throwable
{
- Request request = new Request(null, null);
-
-
- String formatString = "clientIP: %a | ";
- MethodHandle logHandle = getLogHandle(formatString);
-
-
- StringBuilder b = new StringBuilder();
- logHandle.invoke(b, request);
- System.err.println(b.toString());
-
- }
-
- private static MethodHandle getLogHandle(String formatString) throws NoSuchMethodException, IllegalAccessException
- {
- //TODO add response to signature
- MethodType logType = methodType(Void.TYPE, StringBuilder.class, Request.class);
MethodHandle append = MethodHandles.lookup().findStatic(CustomRequestLog.class, "append", methodType(Void.TYPE, String.class, StringBuilder.class));
MethodHandle logHandle = dropArguments(append.bindTo("\n"), 1, Request.class);
- for (Token s : tokenize(formatString))
- {
- if (s.isLiteralString())
- {
- logHandle = foldArguments(logHandle, dropArguments(append.bindTo(s.literal), 1, Request.class));
- }
- else
- {
- switch (s.code)
- {
-
- case "a":
- {
- String method = "logClientIP";
- MethodHandle specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType);
- logHandle = foldArguments(logHandle, specificHandle);
- break;
- }
- }
- }
- }
-
- return logHandle;
- }
-
- private static List tokenize(String value)
- {
- List tokens = new ArrayList<>();
-
final Pattern PERCENT_CODE = Pattern.compile("(?.*)%(?:\\{(?[^{}]+)})?(?[a-zA-Z%])");
final Pattern LITERAL = Pattern.compile("(?.*%(?:\\{[^{}]+})?[a-zA-Z%])(?.*)");
- while(value.length()>0)
+ String remaining = formatString;
+ while(remaining.length()>0)
{
- Matcher m = PERCENT_CODE.matcher(value);
- Matcher m2 = LITERAL.matcher(value);
+ Matcher m = PERCENT_CODE.matcher(remaining);
if (m.matches())
{
String code = m.group("code");
String arg = m.group("arg");
- tokens.add(new Token(code, arg));
- value = m.group("remaining");
+ logHandle = updateLogHandle(logHandle, code, arg);
+ remaining = m.group("remaining");
continue;
}
+ Matcher m2 = LITERAL.matcher(remaining);
String literal;
if (m2.matches())
{
literal = m2.group("literal");
- value = m2.group("remaining");
+ remaining = m2.group("remaining");
}
else
{
- literal = value;
- value = "";
+ literal = remaining;
+ remaining = "";
}
- tokens.add(new Token(literal));
-
+ logHandle = updateLogHandle(logHandle, append, literal);
}
- return tokens;
+
+ return logHandle;
}
-
-
- private static class Token
+ private MethodHandle updateLogHandle(MethodHandle logHandle, MethodHandle append, String literal)
{
- public boolean isLiteralString()
- {
- return(literal != null);
- }
+ return foldArguments(logHandle, dropArguments(append.bindTo(literal), 1, Request.class));
+ }
- public boolean isPercentCode()
- {
- return(code != null);
- }
- public String code = null;
- public String arg = null;
- public String literal = null;
-
- public Token(String code, String arg)
+ private MethodHandle updateLogHandle(MethodHandle logHandle, String code, String arg) throws Throwable
+ {
+ switch (code)
{
- this.code = code;
- this.arg = arg;
- }
+ case "a":
+ {
+ String method = "logClientIP";
+ MethodHandle specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, LOG_TYPE);
+ return foldArguments(logHandle, specificHandle);
+ }
- public Token(String literal)
- {
- this.literal = literal;
+ default:
+ LOG.warn("Unsupported code %{}", code);
+ return logHandle;
}
}
}
From 22e7679dd681f7f16dc5e795317e15a95403b597 Mon Sep 17 00:00:00 2001
From: Lachlan Roberts
Date: Tue, 6 Nov 2018 12:21:30 +0100
Subject: [PATCH 132/931] Issue 113 - CustomRequestLog
changed the log type to include the response
Signed-off-by: Lachlan Roberts
---
.../org/eclipse/jetty/server/CustomRequestLog.java | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java b/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java
index f0cb7d45556..c13fcdba1c0 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java
@@ -341,7 +341,7 @@ public class CustomRequestLog extends AbstractLifeCycle implements RequestLog
StringBuilder sb = _buffers.get();
sb.setLength(0);
- _logHandle.invoke(sb, request);
+ _logHandle.invoke(sb, request, response);
String log = sb.toString();
write(log);
@@ -540,19 +540,17 @@ public class CustomRequestLog extends AbstractLifeCycle implements RequestLog
append(buf, s);
}
- public static void logClientIP(StringBuilder b, Request request)
+ public static void logClientIP(StringBuilder b, Request request, Response response)
{
b.append(request.getRemoteAddr());
}
-
- //TODO add response to signature
- private static final MethodType LOG_TYPE = methodType(Void.TYPE, StringBuilder.class, Request.class);
+ private static final MethodType LOG_TYPE = methodType(Void.TYPE, StringBuilder.class, Request.class, Response.class);
private MethodHandle getLogHandle(String formatString) throws Throwable
{
MethodHandle append = MethodHandles.lookup().findStatic(CustomRequestLog.class, "append", methodType(Void.TYPE, String.class, StringBuilder.class));
- MethodHandle logHandle = dropArguments(append.bindTo("\n"), 1, Request.class);
+ MethodHandle logHandle = dropArguments(dropArguments(append.bindTo("\n"), 1, Request.class), 2, Response.class);
final Pattern PERCENT_CODE = Pattern.compile("(?.*)%(?:\\{(?[^{}]+)})?(?[a-zA-Z%])");
final Pattern LITERAL = Pattern.compile("(?.*%(?:\\{[^{}]+})?[a-zA-Z%])(?.*)");
@@ -592,7 +590,8 @@ public class CustomRequestLog extends AbstractLifeCycle implements RequestLog
private MethodHandle updateLogHandle(MethodHandle logHandle, MethodHandle append, String literal)
{
- return foldArguments(logHandle, dropArguments(append.bindTo(literal), 1, Request.class));
+ return foldArguments(logHandle, dropArguments(dropArguments(append.bindTo(literal), 1, Request.class), 2, Response.class));
+
}
From ef261a39ae09b775aae27b042f69bfb83f3a287b Mon Sep 17 00:00:00 2001
From: Jan Bartel
Date: Tue, 6 Nov 2018 16:40:21 +0100
Subject: [PATCH 133/931] Issue #2925 Update troubleshooting doc for files
locking on windows (#3061)
* Issue #2925 Update troubleshooting doc for files locking on windows
Signed-off-by: Jan Bartel
* General formatting fixes.
Signed-off-by: WalkerWatch
---
.../troubleshooting-locked-files.adoc | 110 +++++++-----------
1 file changed, 42 insertions(+), 68 deletions(-)
diff --git a/jetty-documentation/src/main/asciidoc/reference/troubleshooting/troubleshooting-locked-files.adoc b/jetty-documentation/src/main/asciidoc/reference/troubleshooting/troubleshooting-locked-files.adoc
index f23b78d8d22..584241d2cfb 100644
--- a/jetty-documentation/src/main/asciidoc/reference/troubleshooting/troubleshooting-locked-files.adoc
+++ b/jetty-documentation/src/main/asciidoc/reference/troubleshooting/troubleshooting-locked-files.adoc
@@ -26,84 +26,58 @@ Effectively this means that you have to stop Jetty to update a file.
==== Remedy
-Jetty provides a configuration switch in the `webdefault.xml` file for the DefaultServlet that enables or disables the use of memory-mapped files.
+Jetty provides a configuration switch for the `DefaultServlet` that enables or disables the use of memory-mapped files.
If you are running on Windows and are having file-locking problems, you should set this switch to disable memory-mapped file buffers.
+Use one of the following options to configure the switch.
-The default `webdefault.xml` file is found in the jetty distribution under the `etc/` directory or in the `jetty-webapp-${VERSION}.jar` artifact at `org/eclipse/jetty/webapp/webdefault.xml`.
-Edit the file in the distribution or extract it to a convenient disk location and edit it to change `useFileMappedBuffer` to false.
-The easiest option is to simply edit the default file contained in the jetty distribution itself.
+===== Using override-web.xml
+
+An <> file can be placed in your webapp's `WEB-INF` directory to change the default setting of the `DefaultServlet` for memory-mapped file buffers.
+Create an `override-web.xml` file with appropriate headers for your version of the servlet specification, and place the following inside the `` element:
[source, xml, subs="{sub-order}"]
----
-
- useFileMappedBuffer
- true
-
-
-
-----
-
-Make sure to apply your custom `webdefault.xml` file to all of your webapps.
-You can do that by changing the configuration of the Deployment Manager in `etc/jetty-deploy.xml`.
-
-[source, xml, subs="{sub-order}"]
-----
-
-
-
- .
- .
-
- /etc/webdefault.xml
- 1
- true
- .
- .
-
-
-
-
-
-----
-
-Alternatively, if you have individually configured your webapps with context xml files, you need to call the `WebAppContext.setDefaultsDescriptor(String path)` method:
-
-[source, xml, subs="{sub-order}"]
-----
-
- /
- ./webapps/fredapp
- /home/fred/jetty/mywebdefaults.xml
- .
- .
-
-
-
-----
-
-Instead, you could redefine the DefaultServlet in your web.xml file, making sure to set useFileMappedBuffer to false:
-
-[source, xml, subs="{sub-order}"]
-----
-
- ...
- default
- org.eclipse.jetty.servlet.DefaultServlet
-
- useFileMappedBuffer
- false
-
- 0
-
- ...
-
+ default
+
+ useFileMappedBuffer
+ false
+
+
----
+===== Using a Context XML File
+
+You can create or update a context xml file that configures your webapp to apply the setting to disable memory-mapped file buffers.
+Add the following to your context xml file:
+
+[source, xml, subs="{sub-order}"]
+----
+
+ org.eclipse.jetty.servlet.Default.useFileMappedBuffer
+ false
+
+----
+
+
+===== Using the Jetty Maven Plugin
+
+If you don't want to use either of the other two solutions, you can configure the plugin directly to disable memory-mapped file buffers.
+Add the following to the plugin's configuration under the `` element:
+
+[source, xml, subs="{sub-order}"]
+----
+ <_initParams>
+ false
+
+----
+
+
+
==== Alternate Remedy
You can force a `WebAppContext` to always copy a web app directory on deployment.
-The base directory of your web app (ie the root directory where your static content exists) will be copied to the link:#ref-temporary-directories[temp directory].
+The base directory of your web app (i.e. the root directory where your static content exists) will be copied to the link:#ref-temporary-directories[temp directory].
Configure this in an xml file like so:
[source, xml, subs="{sub-order}"]
@@ -120,4 +94,4 @@ Configure this in an xml file like so:
____
[NOTE]
Be careful with this option when using an explicitly setlink:#ref-temp-directories[temp directory] name - as the name of the temp directory will not unique across redeployments, copying the static content into the same directory name each time may not avoid the locking problem.
-____
\ No newline at end of file
+____
From 872eafef0652f67af51a5926a374c84176f24c4b Mon Sep 17 00:00:00 2001
From: Olivier Lamy
Date: Wed, 7 Nov 2018 17:28:44 +1000
Subject: [PATCH 134/931] Issue #2858 upgrade jnr-unixsocket to 0.19 (#2859)
* upgrade jnr-unixsocket to 0.19 #2858
Signed-off-by: olivier lamy
* remove hack as issue has been fixed on jnr project
Signed-off-by: olivier lamy
* upgrade jnr-unixsocket to 0.20
Signed-off-by: olivier lamy
---
.../jetty/unixsocket/UnixSocketEndPoint.java | 46 -------------------
pom.xml | 2 +-
2 files changed, 1 insertion(+), 47 deletions(-)
diff --git a/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/UnixSocketEndPoint.java b/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/UnixSocketEndPoint.java
index 3fac0fbe26d..8f798e22e3b 100644
--- a/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/UnixSocketEndPoint.java
+++ b/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/UnixSocketEndPoint.java
@@ -75,50 +75,4 @@ public class UnixSocketEndPoint extends ChannelEndPoint
LOG.debug(e);
}
}
-
-
- @Override
- public boolean flush(ByteBuffer... buffers) throws IOException
- {
- // TODO this is a work around for https://github.com/jnr/jnr-unixsocket/issues/50
- long flushed=0;
- try
- {
- for (ByteBuffer b : buffers)
- {
- if (b.hasRemaining())
- {
- int r=b.remaining();
- int p=b.position();
- int l=_channel.write(b);
- if (l>=0)
- {
- b.position(p+l);
- flushed+=l;
- }
-
- if (CEPLOG.isDebugEnabled())
- CEPLOG.debug("flushed {}/{} r={} {}", l,r,b.remaining(), this);
-
- if (b.hasRemaining())
- break;
- }
- }
-
- }
- catch (IOException e)
- {
- throw new EofException(e);
- }
-
- if (flushed>0)
- notIdle();
-
- for (ByteBuffer b : buffers)
- if (!BufferUtil.isEmpty(b))
- return false;
-
- return true;
- }
-
}
diff --git a/pom.xml b/pom.xml
index 4fd3fe4cd53..45e08653987 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1022,7 +1022,7 @@
com.github.jnrjnr-unixsocket
- 0.18
+ 0.20junit
From cf2de4411c3465f93cfa3a6e0e685e836ca768a4 Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Wed, 7 Nov 2018 10:03:18 +0100
Subject: [PATCH 135/931] Issue #3041 separate CookieCompliance for parsing and
generation (#3048)
* Issue #3041 separate CookieCompliance for parsing and generation
Signed-off-by: Greg Wilkins
* improved documentation
Signed-off-by: Greg Wilkins
* use only getters
Signed-off-by: Greg Wilkins
* Rename setters to avoid setSetXxxx
Signed-off-by: Greg Wilkins
---
jetty-server/src/main/config/etc/jetty.xml | 3 +-
.../src/main/config/modules/server.mod | 7 +-
.../jetty/server/HttpConfiguration.java | 113 +++++++++++++++---
.../org/eclipse/jetty/server/Request.java | 4 +-
.../org/eclipse/jetty/server/Response.java | 4 +-
.../eclipse/jetty/server/ResponseTest.java | 2 +-
6 files changed, 108 insertions(+), 25 deletions(-)
diff --git a/jetty-server/src/main/config/etc/jetty.xml b/jetty-server/src/main/config/etc/jetty.xml
index 525b1d08f9f..961f95435e5 100644
--- a/jetty-server/src/main/config/etc/jetty.xml
+++ b/jetty-server/src/main/config/etc/jetty.xml
@@ -64,7 +64,8 @@
-
+
+
diff --git a/jetty-server/src/main/config/modules/server.mod b/jetty-server/src/main/config/modules/server.mod
index 2bd4718fd0d..038f1836b65 100644
--- a/jetty-server/src/main/config/modules/server.mod
+++ b/jetty-server/src/main/config/modules/server.mod
@@ -62,8 +62,11 @@ patch-module: servlet.api=lib/jetty-schemas-3.1.jar
## Maximum number of error dispatches to prevent looping
# jetty.httpConfig.maxErrorDispatches=10
-## Cookie compliance mode of: RFC2965, RFC6265
-# jetty.httpConfig.cookieCompliance=RFC6265
+## Cookie compliance mode for parsing request Cookie headers: RFC2965, RFC6265
+# jetty.httpConfig.requestCookieCompliance=RFC6265
+
+## Cookie compliance mode for generating response Set-Cookie: RFC2965, RFC6265
+# jetty.httpConfig.responseCookieCompliance=RFC6265
## multipart/form-data compliance mode of: LEGACY(slow), RFC7578(fast)
# jetty.httpConfig.multiPartFormDataCompliance=LEGACY
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java
index 623a97b8ffd..4d9537ad024 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java
@@ -31,6 +31,8 @@ import org.eclipse.jetty.util.TreeTrie;
import org.eclipse.jetty.util.Trie;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
+import org.eclipse.jetty.util.component.Dumpable;
+import org.eclipse.jetty.util.component.DumpableCollection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -46,7 +48,7 @@ import org.eclipse.jetty.util.log.Logger;
*
*/
@ManagedObject("HTTP Configuration")
-public class HttpConfiguration
+public class HttpConfiguration implements Dumpable
{
private static final Logger LOG = Log.getLogger(HttpConfiguration.class);
@@ -70,7 +72,8 @@ public class HttpConfiguration
private int _maxErrorDispatches = 10;
private long _minRequestDataRate;
private long _minResponseDataRate;
- private CookieCompliance _cookieCompliance = CookieCompliance.RFC6265;
+ private CookieCompliance _requestCookieCompliance = CookieCompliance.RFC6265;
+ private CookieCompliance _responseCookieCompliance = CookieCompliance.RFC6265;
private MultiPartFormDataCompliance _multiPartCompliance = MultiPartFormDataCompliance.LEGACY; // TODO change default in jetty-10
private boolean _notifyRemoteAsyncErrors = true;
@@ -133,7 +136,8 @@ public class HttpConfiguration
_maxErrorDispatches=config._maxErrorDispatches;
_minRequestDataRate=config._minRequestDataRate;
_minResponseDataRate=config._minResponseDataRate;
- _cookieCompliance=config._cookieCompliance;
+ _requestCookieCompliance =config._requestCookieCompliance;
+ _responseCookieCompliance =config._responseCookieCompliance;
_notifyRemoteAsyncErrors=config._notifyRemoteAsyncErrors;
}
@@ -531,19 +535,58 @@ public class HttpConfiguration
_minResponseDataRate = bytesPerSecond;
}
- public CookieCompliance getCookieCompliance()
+ /**
+ * @see #getResponseCookieCompliance()
+ * @return The CookieCompliance used for parsing request Cookie headers.
+ */
+ public CookieCompliance getRequestCookieCompliance()
{
- return _cookieCompliance;
- }
-
- public void setCookieCompliance(CookieCompliance cookieCompliance)
- {
- _cookieCompliance = cookieCompliance==null?CookieCompliance.RFC6265:cookieCompliance;
+ return _requestCookieCompliance;
}
+ /**
+ * @see #getRequestCookieCompliance()
+ * @return The CookieCompliance used for generating response Set-Cookie headers
+ */
+ public CookieCompliance getResponseCookieCompliance()
+ {
+ return _responseCookieCompliance;
+ }
+
+ /**
+ * @see #setRequestCookieCompliance(CookieCompliance)
+ * @param cookieCompliance The CookieCompliance to use for parsing request Cookie headers.
+ */
+ public void setRequestCookieCompliance(CookieCompliance cookieCompliance)
+ {
+ _requestCookieCompliance = cookieCompliance==null?CookieCompliance.RFC6265:cookieCompliance;
+ }
+
+ /**
+ * @see #setResponseCookieCompliance(CookieCompliance)
+ * @param cookieCompliance The CookieCompliance to use for generating response Set-Cookie headers
+ */
+ public void setResponseCookieCompliance(CookieCompliance cookieCompliance)
+ {
+ _responseCookieCompliance = cookieCompliance==null?CookieCompliance.RFC6265:cookieCompliance;
+ }
+
+ @Deprecated
+ public void setCookieCompliance(CookieCompliance compliance)
+ {
+ setRequestCookieCompliance(compliance);
+ }
+
+ @Deprecated
+ public CookieCompliance getCookieCompliance()
+ {
+ return getRequestCookieCompliance();
+ }
+
+ @Deprecated
public boolean isCookieCompliance(CookieCompliance compliance)
{
- return _cookieCompliance.equals(compliance);
+ return _requestCookieCompliance.equals(compliance);
}
/**
@@ -579,15 +622,51 @@ public class HttpConfiguration
return _notifyRemoteAsyncErrors;
}
+ @Override public String dump()
+ {
+ return Dumpable.dump(this);
+ }
+
+ @Override public void dump(Appendable out, String indent) throws IOException
+ {
+ Dumpable.dumpObjects(out,indent,this,
+ new DumpableCollection("customizers",_customizers),
+ new DumpableCollection("formEncodedMethods",_formEncodedMethods.keySet()),
+ "outputBufferSize=" + _outputBufferSize,
+ "outputAggregationSize=" + _outputAggregationSize,
+ "requestHeaderSize=" + _requestHeaderSize,
+ "responseHeaderSize=" + _responseHeaderSize,
+ "headerCacheSize=" + _headerCacheSize,
+ "secureScheme=" + _secureScheme,
+ "securePort=" + _securePort,
+ "idleTimeout=" + _idleTimeout,
+ "blockingTimeout=" + _blockingTimeout,
+ "sendDateHeader=" + _sendDateHeader,
+ "sendServerVersion=" + _sendServerVersion,
+ "sendXPoweredBy=" + _sendXPoweredBy,
+ "delayDispatchUntilContent=" + _delayDispatchUntilContent,
+ "persistentConnectionsEnabled=" + _persistentConnectionsEnabled,
+ "maxErrorDispatches=" + _maxErrorDispatches,
+ "minRequestDataRate=" + _minRequestDataRate,
+ "minResponseDataRate=" + _minResponseDataRate,
+ "cookieCompliance=" + _requestCookieCompliance,
+ "setRequestCookieCompliance=" + _responseCookieCompliance,
+ "notifyRemoteAsyncErrors=" + _notifyRemoteAsyncErrors
+ );
+ }
+
@Override
public String toString()
{
return String.format("%s@%x{%d/%d,%d/%d,%s://:%d,%s}",
- this.getClass().getSimpleName(),
- hashCode(),
- _outputBufferSize, _outputAggregationSize,
- _requestHeaderSize,_responseHeaderSize,
- _secureScheme,_securePort,
- _customizers);
+ this.getClass().getSimpleName(),
+ hashCode(),
+ _outputBufferSize,
+ _outputAggregationSize,
+ _requestHeaderSize,
+ _responseHeaderSize,
+ _secureScheme,
+ _securePort,
+ _customizers);
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
index b13d1cc0c16..d29d0431d54 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
@@ -770,7 +770,7 @@ public class Request implements HttpServletRequest
if (field.getHeader()==HttpHeader.COOKIE)
{
if (_cookies==null)
- _cookies = new CookieCutter(getHttpChannel().getHttpConfiguration().getCookieCompliance());
+ _cookies = new CookieCutter(getHttpChannel().getHttpConfiguration().getRequestCookieCompliance());
_cookies.addCookieField(field.getValue());
}
}
@@ -2057,7 +2057,7 @@ public class Request implements HttpServletRequest
public void setCookies(Cookie[] cookies)
{
if (_cookies == null)
- _cookies = new CookieCutter(getHttpChannel().getHttpConfiguration().getCookieCompliance());
+ _cookies = new CookieCutter(getHttpChannel().getHttpConfiguration().getRequestCookieCompliance());
_cookies.setCookies(cookies);
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
index 43876ea13e7..3741ee1b256 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
@@ -172,7 +172,7 @@ public class Response implements HttpServletResponse
throw new IllegalArgumentException("Cookie.name cannot be blank/null");
}
- if (getHttpChannel().getHttpConfiguration().isCookieCompliance(CookieCompliance.RFC2965))
+ if (getHttpChannel().getHttpConfiguration().getResponseCookieCompliance()==CookieCompliance.RFC2965)
addSetRFC2965Cookie(
cookie.getName(),
cookie.getValue(),
@@ -217,7 +217,7 @@ public class Response implements HttpServletResponse
throw new IllegalArgumentException("Cookie.name cannot be blank/null");
}
- if (getHttpChannel().getHttpConfiguration().isCookieCompliance(CookieCompliance.RFC2965))
+ if (getHttpChannel().getHttpConfiguration().getResponseCookieCompliance()==CookieCompliance.RFC2965)
addSetRFC2965Cookie(cookie.getName(),
cookie.getValue(),
cookie.getDomain(),
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
index fd2396c5aef..6ef9136c453 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
@@ -944,7 +944,7 @@ public class ResponseTest
public void testAddCookieComplianceRFC2965() throws Exception
{
Response response = getResponse();
- response.getHttpChannel().getHttpConfiguration().setCookieCompliance(CookieCompliance.RFC2965);
+ response.getHttpChannel().getHttpConfiguration().setResponseCookieCompliance(CookieCompliance.RFC2965);
Cookie cookie = new Cookie("name", "value");
cookie.setDomain("domain");
From 6bec0e8357207824774eb47ebd17ce68ef6a31fc Mon Sep 17 00:00:00 2001
From: Greg Wilkins
Date: Wed, 7 Nov 2018 12:05:55 +0100
Subject: [PATCH 136/931] Cleanup webapp context
Signed-off-by: Greg Wilkins
---
.../jetty/embedded/OneWebAppWithJsp.java | 4 +-
.../annotations/AnnotationConfiguration.java | 42 ++++++++-----------
.../jetty/servlet/ServletContextHandler.java | 1 +
3 files changed, 20 insertions(+), 27 deletions(-)
diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneWebAppWithJsp.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneWebAppWithJsp.java
index 99054e58b39..ace3450fa5a 100644
--- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneWebAppWithJsp.java
+++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneWebAppWithJsp.java
@@ -55,7 +55,7 @@ public class OneWebAppWithJsp
WebAppContext webapp = new WebAppContext();
webapp.setContextPath( "/" );
File warFile = new File(
- "../../jetty-distribution/target/distribution/demo-base/webapps/test.war" );
+ "jetty-distribution/target/distribution/demo-base/webapps/test.war" );
if (!warFile.exists())
{
throw new RuntimeException( "Unable to find WAR File: "
@@ -96,7 +96,7 @@ public class OneWebAppWithJsp
// itself.
HashLoginService loginService = new HashLoginService();
loginService.setName( "Test Realm" );
- loginService.setConfig( "src/test/resources/realm.properties" );
+ loginService.setConfig( "examples/embedded/src/test/resources/realm.properties" );
server.addBean( loginService );
// Start things up!
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java
index bc2da221fe6..9d1cc3661bc 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java
@@ -79,9 +79,9 @@ public class AnnotationConfiguration extends AbstractConfiguration
public static final int DEFAULT_MAX_SCAN_WAIT = 60; /* time in sec */
public static final boolean DEFAULT_MULTI_THREADED = true;
- protected List _discoverableAnnotationHandlers = new ArrayList();
+ protected final List _discoverableAnnotationHandlers = new ArrayList<>();
protected ClassInheritanceHandler _classInheritanceHandler;
- protected List _containerInitializerAnnotationHandlers = new ArrayList();
+ protected final List _containerInitializerAnnotationHandlers = new ArrayList<>();
protected List _parserTasks;
@@ -318,29 +318,12 @@ public class AnnotationConfiguration extends AbstractConfiguration
String tmp = (String)context.getAttribute(SERVLET_CONTAINER_INITIALIZER_EXCLUSION_PATTERN);
_sciExcludePattern = (tmp==null?null:Pattern.compile(tmp));
}
-
public void addDiscoverableAnnotationHandler(AbstractDiscoverableAnnotationHandler handler)
{
_discoverableAnnotationHandlers.add(handler);
}
- @Override
- public void deconfigure(WebAppContext context) throws Exception
- {
- context.removeAttribute(CLASS_INHERITANCE_MAP);
- context.removeAttribute(CONTAINER_INITIALIZERS);
- ServletContainerInitializersStarter starter = (ServletContainerInitializersStarter)context.getAttribute(CONTAINER_INITIALIZER_STARTER);
- if (starter != null)
- {
- context.removeBean(starter);
- context.removeAttribute(CONTAINER_INITIALIZER_STARTER);
- }
-
- if (_loadedInitializers != null)
- _loadedInitializers.reload();
- }
-
/**
* @see org.eclipse.jetty.webapp.AbstractConfiguration#configure(org.eclipse.jetty.webapp.WebAppContext)
*/
@@ -386,15 +369,14 @@ public class AnnotationConfiguration extends AbstractConfiguration
public void postConfigure(WebAppContext context) throws Exception
{
Map> classMap = (ClassInheritanceMap)context.getAttribute(CLASS_INHERITANCE_MAP);
- List initializers = (List)context.getAttribute(CONTAINER_INITIALIZERS);
-
- context.removeAttribute(CLASS_INHERITANCE_MAP);
if (classMap != null)
classMap.clear();
-
- context.removeAttribute(CONTAINER_INITIALIZERS);
+ context.removeAttribute(CLASS_INHERITANCE_MAP);
+
+ List initializers = (List)context.getAttribute(CONTAINER_INITIALIZERS);
if (initializers != null)
initializers.clear();
+ context.removeAttribute(CONTAINER_INITIALIZERS);
if (_discoverableAnnotationHandlers != null)
_discoverableAnnotationHandlers.clear();
@@ -408,7 +390,17 @@ public class AnnotationConfiguration extends AbstractConfiguration
_parserTasks.clear();
_parserTasks = null;
}
-
+
+ ServletContainerInitializersStarter starter = (ServletContainerInitializersStarter)context.getAttribute(CONTAINER_INITIALIZER_STARTER);
+ if (starter != null)
+ {
+ context.removeBean(starter);
+ context.removeAttribute(CONTAINER_INITIALIZER_STARTER);
+ }
+
+ if (_loadedInitializers != null)
+ _loadedInitializers.reload();
+
super.postConfigure(context);
}
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java
index 21f51b86ad7..48fb06391de 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java
@@ -287,6 +287,7 @@ public class ServletContextHandler extends ContextHandler
{
super.doStop();
_objFactory.clear();
+ getServletContext().removeAttribute(DecoratedObjectFactory.ATTR);
}
/* ------------------------------------------------------------ */
From 3ef33764cb71207637cfcb97701eaa33bb9bff81 Mon Sep 17 00:00:00 2001
From: Olivier Lamy
Date: Thu, 8 Nov 2018 07:24:42 +1000
Subject: [PATCH 137/931] Issue #3054 Jetty 9.4.x spifly upgrade (#3079)
* spifly 1.0.15-SNAPSHOT
Signed-off-by: olivier lamy
* upgrade org.apache.aries.spifly.dynamic.bundle to 1.1
Signed-off-by: olivier lamy
* Make osgi work with spifly 1.1
Signed-off-by: Jan Bartel
---
.../jetty-osgi-boot/jettyhome/etc/jetty.xml | 31 ++++++++++++----
.../osgi/annotations/AnnotationParser.java | 2 +-
jetty-osgi/pom.xml | 1 -
jetty-osgi/test-jetty-osgi-server/pom.xml | 2 +-
.../main/java/com/acme/osgi/Activator.java | 11 ++++++
jetty-osgi/test-jetty-osgi/pom.xml | 28 +++++++++++++--
.../src/test/config/etc/jetty.xml | 35 ++++++++++++-------
.../TestJettyOSGiBootWebAppAsService.java | 2 +-
.../TestJettyOSGiBootWithAnnotations.java | 4 +--
9 files changed, 87 insertions(+), 29 deletions(-)
diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml
index f47a40a2bc4..fe4fc1d1ab3 100644
--- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml
+++ b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml
@@ -40,7 +40,7 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- true
- 1000
- false
- false
-
+
+
+
+
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/annotations/AnnotationParser.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/annotations/AnnotationParser.java
index ef85bd9e23a..00f0919a023 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/annotations/AnnotationParser.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/annotations/AnnotationParser.java
@@ -49,7 +49,7 @@ public class AnnotationParser extends org.eclipse.jetty.annotations.AnnotationPa
public AnnotationParser(int javaPlatform)
{
- super(javaPlatform, Opcodes.ASM5);
+ super(javaPlatform, Opcodes.ASM7);
}
/**
diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml
index 503b4cba7e3..090cc250a42 100644
--- a/jetty-osgi/pom.xml
+++ b/jetty-osgi/pom.xml
@@ -15,7 +15,6 @@
pom
- 6.23.6.0.v201005173.2.100.v201005031.0.0-v20070606
diff --git a/jetty-osgi/test-jetty-osgi-server/pom.xml b/jetty-osgi/test-jetty-osgi-server/pom.xml
index 57f376a32a1..195f3b6fbfe 100644
--- a/jetty-osgi/test-jetty-osgi-server/pom.xml
+++ b/jetty-osgi/test-jetty-osgi-server/pom.xml
@@ -15,7 +15,7 @@
org.eclipse.jetty
- jetty-server
+ jetty-webapp${project.version}
diff --git a/jetty-osgi/test-jetty-osgi-server/src/main/java/com/acme/osgi/Activator.java b/jetty-osgi/test-jetty-osgi-server/src/main/java/com/acme/osgi/Activator.java
index a45f567d57d..89288615b63 100644
--- a/jetty-osgi/test-jetty-osgi-server/src/main/java/com/acme/osgi/Activator.java
+++ b/jetty-osgi/test-jetty-osgi-server/src/main/java/com/acme/osgi/Activator.java
@@ -23,6 +23,7 @@ import java.util.Hashtable;
import org.eclipse.jetty.util.component.AbstractLifeCycle.AbstractLifeCycleListener;
import org.eclipse.jetty.util.component.LifeCycle;
+import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
@@ -67,6 +68,16 @@ public class Activator implements BundleActivator
});
ContextHandlerCollection contexts = new ContextHandlerCollection();
server.setHandler(contexts);
+ //server.setDumpAfterStart(true);
+
+ Configuration.ClassList list = new Configuration.ClassList(new String[] {"org.eclipse.jetty.osgi.boot.OSGiWebInfConfiguration",
+ "org.eclipse.jetty.webapp.WebXmlConfiguration",
+ "org.eclipse.jetty.webapp.MetaInfConfiguration",
+ "org.eclipse.jetty.webapp.FragmentConfiguration",
+ "org.eclipse.jetty.webapp.JettyWebXmlConfiguration"});
+ server.addBean(list);
+ server.setAttribute("org.eclipse.jetty.webapp.configuration", list);
+ list.setServerDefault(server);
Dictionary serverProps = new Hashtable();
//define the unique name of the server instance
diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml
index 40340aa2fbb..50faee17777 100644
--- a/jetty-osgi/test-jetty-osgi/pom.xml
+++ b/jetty-osgi/test-jetty-osgi/pom.xml
@@ -78,13 +78,13 @@
org.eclipse.platformorg.eclipse.osgi
- 3.12.50
+ 3.13.100testorg.eclipse.platformorg.eclipse.osgi.services
- 3.6.0
+ 3.7.100test
@@ -148,7 +148,29 @@
org.apache.aries.spiflyorg.apache.aries.spifly.dynamic.bundle
- 1.0.10
+ 1.1
+ test
+
+
+ org.apache.felix
+ org.apache.felix.framework
+
+
+ org.ow2.asm
+ asm-util
+
+
+
+
+ org.apache.aries
+ org.apache.aries.util
+ 1.1.1
+ test
+
+
+ com.sun.activation
+ javax.activation
+ 1.2.0test
diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml
index f47a40a2bc4..43e978db7f0 100644
--- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml
+++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml
@@ -41,25 +41,34 @@
-
- https
-
- 32768
- 8192
- 8192
- true
- false
- 4096
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- true
- 1000
- false
- false
+
+
+
+
diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWebAppAsService.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWebAppAsService.java
index ba2b2b2326d..56083be7bb6 100644
--- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWebAppAsService.java
+++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWebAppAsService.java
@@ -101,8 +101,8 @@ public class TestJettyOSGiBootWebAppAsService
@Test
public void assertAllBundlesActiveOrResolved()
{
- //TestOSGiUtil.assertAllBundlesActiveOrResolved(bundleContext);
TestOSGiUtil.debugBundles(bundleContext);
+ TestOSGiUtil.assertAllBundlesActiveOrResolved(bundleContext);
}
diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithAnnotations.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithAnnotations.java
index 358baeab33f..c8e5a57f1a1 100644
--- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithAnnotations.java
+++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithAnnotations.java
@@ -85,6 +85,7 @@ public class TestJettyOSGiBootWithAnnotations
public static List
-
- org.apache.aries
- org.apache.aries.util
- 1.1.1
- test
- com.sun.activationjavax.activation
diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java
index e30a2e81950..eb3c086e0ec 100644
--- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java
+++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java
@@ -110,7 +110,6 @@ public class TestOSGiUtil
res.add(mavenBundle().groupId( "org.ow2.asm" ).artifactId( "asm" ).versionAsInProject().start());
res.add(mavenBundle().groupId( "org.ow2.asm" ).artifactId( "asm-commons" ).versionAsInProject().start());
res.add(mavenBundle().groupId( "org.ow2.asm" ).artifactId( "asm-tree" ).versionAsInProject().start());
- res.add(mavenBundle().groupId( "org.apache.aries" ).artifactId( "org.apache.aries.util" ).versionAsInProject().start());
res.add(mavenBundle().groupId( "org.apache.aries.spifly" ).artifactId( "org.apache.aries.spifly.dynamic.bundle" ).versionAsInProject().start());
res.add(mavenBundle().groupId( "org.eclipse.jetty.toolchain" ).artifactId( "jetty-osgi-servlet-api" ).versionAsInProject().noStart());
res.add(mavenBundle().groupId( "javax.annotation" ).artifactId( "javax.annotation-api" ).versionAsInProject().start());
@@ -157,7 +156,6 @@ public class TestOSGiUtil
List