From ad3be199e8ba29433ce5a2d40cd279f1222c1281 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 31 May 2019 10:43:56 -0500 Subject: [PATCH 1/2] Disabling broken slack notifications --- Jenkinsfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 4a9352e4c99..4875134e04b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -80,6 +80,7 @@ pipeline { } } } + /* post { failure { slackNotif() @@ -91,8 +92,10 @@ pipeline { slackNotif() } } + */ } +/* def slackNotif() { script { if (env.BRANCH_NAME=='jetty-10.0.x' || @@ -106,6 +109,7 @@ def slackNotif() { } } } +*/ /** * To other developers, if you are using this method above, please use the following syntax. From dec10044e0f0bdbeaeafd4401b695a7db35d0b93 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Mon, 3 Jun 2019 10:27:38 +0200 Subject: [PATCH 2/2] Jetty 9.4.x 3722 session destroy listeners (#3723) * Issue #3722 Use webapp classloader for HttpSessionListener.sessionDestroyed calls --- .../jetty/server/session/SessionHandler.java | 19 ++++-- ...tHttpSessionListenerWithWebappClasses.java | 61 +++++++++++++++++++ .../server/session/SessionListenerTest.java | 26 +++++++- 3 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpSessionListenerWithWebappClasses.java diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java index 0165eda509c..c8397ee7570 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java @@ -370,11 +370,22 @@ public class SessionHandler extends ScopedHandler if (_sessionListeners!=null) { - HttpSessionEvent event=new HttpSessionEvent(session); - for (int i = _sessionListeners.size()-1; i>=0; i--) + //We annoint the calling thread with + //the webapp's classloader because the calling thread may + //come from the scavenger, rather than a request thread + Runnable r = new Runnable() { - _sessionListeners.get(i).sessionDestroyed(event); - } + @Override + public void run () + { + HttpSessionEvent event=new HttpSessionEvent(session); + for (int i = _sessionListeners.size()-1; i>=0; i--) + { + _sessionListeners.get(i).sessionDestroyed(event); + } + } + }; + _sessionContext.run(r); } } diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpSessionListenerWithWebappClasses.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpSessionListenerWithWebappClasses.java new file mode 100644 index 00000000000..9884a214161 --- /dev/null +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/TestHttpSessionListenerWithWebappClasses.java @@ -0,0 +1,61 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 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.session; + +import javax.servlet.http.HttpSessionEvent; + +/** + * TestHttpSessionListenerWithWebappClasses + * + * A session listener class that checks that sessionDestroyed + * events can reference classes known only to the webapp, ie + * that the calling thread has been correctly annointed with + * the webapp loader. + * + */ +public class TestHttpSessionListenerWithWebappClasses extends TestHttpSessionListener +{ + public TestHttpSessionListenerWithWebappClasses() + { + super(); + } + + public TestHttpSessionListenerWithWebappClasses(boolean access) + { + super(access); + } + + @Override + public void sessionDestroyed(HttpSessionEvent se) + { + //try loading a class that is known only to the webapp + //to test that the calling thread has been properly + //annointed with the webapp's classloader + try + { + Class clazz = Thread.currentThread().getContextClassLoader().loadClass("Foo"); + } + catch (Exception cnfe) + { + ex=cnfe; + } + super.sessionDestroyed(se); + } + +} diff --git a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionListenerTest.java b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionListenerTest.java index 7769ff0b3d6..11f8155bdda 100644 --- a/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionListenerTest.java +++ b/tests/test-sessions/test-sessions-common/src/test/java/org/eclipse/jetty/server/session/SessionListenerTest.java @@ -18,9 +18,14 @@ package org.eclipse.jetty.server.session; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.Serializable; import java.net.HttpCookie; +import java.net.URL; +import java.net.URLClassLoader; import java.util.concurrent.TimeUnit; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -35,6 +40,8 @@ import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.toolchain.test.IO; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -121,13 +128,27 @@ public class SessionListenerTest /** - * Test that listeners are called when a session expires. + * Test that listeners are called when a session expires + * and that the listener is able to access webapp classes. * * @throws Exception */ @Test public void testSessionExpiresWithListener() throws Exception { + //Use a class that would only be known to the webapp classloader + InputStream foostream = Thread.currentThread().getContextClassLoader().getResourceAsStream("Foo.clazz"); + File foodir = new File (MavenTestingUtils.getTargetDir(), "foo"); + foodir.mkdirs(); + File fooclass = new File (foodir, "Foo.class"); + IO.copy(foostream, new FileOutputStream(fooclass)); + + assertTrue(fooclass.exists()); + assertTrue(fooclass.length() != 0); + + URL[] foodirUrls = new URL[]{foodir.toURI().toURL()}; + URLClassLoader contextClassLoader = new URLClassLoader(foodirUrls, Thread.currentThread().getContextClassLoader()); + String contextPath = "/"; String servletMapping = "/server"; int inactivePeriod = 3; @@ -143,8 +164,9 @@ public class SessionListenerTest TestServlet servlet = new TestServlet(); ServletHolder holder = new ServletHolder(servlet); ServletContextHandler context = server1.addContext(contextPath); + context.setClassLoader(contextClassLoader); context.addServlet(holder, servletMapping); - TestHttpSessionListener listener = new TestHttpSessionListener(true); + TestHttpSessionListener listener = new TestHttpSessionListenerWithWebappClasses(true); context.getSessionHandler().addEventListener(listener); server1.start();