diff options
author | Raymond Auge | 2018-12-10 18:36:44 +0000 |
---|---|---|
committer | Raymond Auge | 2018-12-11 21:55:29 +0000 |
commit | 7cfd24099844b8c1b0f691831f2012c53af40a6f (patch) | |
tree | 2b3fe184e328f0cc7ab838e992ee67e62e157828 /bundles | |
parent | 63aac5d11ae9c04a10ffddd64b7b8b3182f6f0b2 (diff) | |
download | rt.equinox.bundles-7cfd24099844b8c1b0f691831f2012c53af40a6f.tar.gz rt.equinox.bundles-7cfd24099844b8c1b0f691831f2012c53af40a6f.tar.xz rt.equinox.bundles-7cfd24099844b8c1b0f691831f2012c53af40a6f.zip |
Bug 541607 - fixes Eclipse Info center massive memory leak since PhotonI20181211-1800
Signed-off-by: Raymond Auge <raymond.auge@liferay.com>
Change-Id: I376dbb41fcd8973144aeb18f547ff049ba724ef5
Diffstat (limited to 'bundles')
14 files changed, 138 insertions, 20 deletions
diff --git a/bundles/org.eclipse.equinox.http.jetty/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.http.jetty/META-INF/MANIFEST.MF index 8969336dc..71d2dfdda 100644 --- a/bundles/org.eclipse.equinox.http.jetty/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.http.jetty/META-INF/MANIFEST.MF @@ -4,7 +4,7 @@ Bundle-Name: %bundleName Bundle-Vendor: %providerName Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.equinox.http.jetty -Bundle-Version: 3.6.200.qualifier +Bundle-Version: 3.7.0.qualifier Bundle-Activator: org.eclipse.equinox.http.jetty.internal.Activator Import-Package: javax.servlet;version="[2.6.0,4.0.0)", javax.servlet.http;version="[2.6.0,4.0.0)", diff --git a/bundles/org.eclipse.equinox.http.jetty/pom.xml b/bundles/org.eclipse.equinox.http.jetty/pom.xml index 55107c4ef..f240ce7cd 100644 --- a/bundles/org.eclipse.equinox.http.jetty/pom.xml +++ b/bundles/org.eclipse.equinox.http.jetty/pom.xml @@ -21,6 +21,6 @@ </parent> <groupId>org.eclipse.equinox</groupId> <artifactId>org.eclipse.equinox.http.jetty</artifactId> - <version>3.6.200-SNAPSHOT</version> + <version>3.7.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/bundles/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/JettyConstants.java b/bundles/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/JettyConstants.java index 2044bcadd..e8664d59b 100644 --- a/bundles/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/JettyConstants.java +++ b/bundles/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/JettyConstants.java @@ -151,6 +151,11 @@ public interface JettyConstants { public static final String CONTEXT_SESSIONINACTIVEINTERVAL = "context.sessioninactiveinterval"; //$NON-NLS-1$ /** + * name="housekeeper.interval" type="Integer" + */ + public static final String HOUSEKEEPER_INTERVAL = "housekeeper.interval"; //$NON-NLS-1$ + + /** * name="customizer.class" type="String" <br /> * (full qualified name of the class that implements * <code>org.eclipse.equinox.http.jetty.JettyCustomizer</code> and has a public no-arg constructor; diff --git a/bundles/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/internal/Activator.java b/bundles/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/internal/Activator.java index 10a0f3d3c..f00174c8a 100644 --- a/bundles/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/internal/Activator.java +++ b/bundles/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/internal/Activator.java @@ -197,6 +197,16 @@ public class Activator implements BundleActivator { } } + // House Keeper Interval + String houseKeeperInterval = Details.getStringProp(context, JettyConstants.HOUSEKEEPER_INTERVAL, null); + if (houseKeeperInterval != null) { + try { + defaultSettings.put(JettyConstants.HOUSEKEEPER_INTERVAL, Long.valueOf(houseKeeperInterval)); + } catch (NumberFormatException e) { + //(log this) ignore + } + } + // Other Info String otherInfo = Details.getStringProp(context, JettyConstants.OTHER_INFO, null); if (otherInfo != null) diff --git a/bundles/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java b/bundles/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java index b4d65a4f1..ea16184f4 100644 --- a/bundles/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java +++ b/bundles/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java @@ -22,12 +22,12 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.*; import javax.servlet.*; -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionIdListener; +import javax.servlet.http.*; import org.eclipse.equinox.http.jetty.JettyConstants; import org.eclipse.equinox.http.jetty.JettyCustomizer; import org.eclipse.equinox.http.servlet.HttpServiceServlet; import org.eclipse.jetty.server.*; +import org.eclipse.jetty.server.session.HouseKeeper; import org.eclipse.jetty.server.session.SessionHandler; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; @@ -159,6 +159,9 @@ public class HttpServerManager implements ManagedServiceFactory { try { server.start(); + + HouseKeeper houseKeeper = server.getSessionIdManager().getSessionHouseKeeper(); + houseKeeper.setIntervalSec(Details.getLong(dictionary, JettyConstants.HOUSEKEEPER_INTERVAL, houseKeeper.getIntervalSec())); } catch (Exception e) { throw new ConfigurationException(pid, e.getMessage(), e); } @@ -250,23 +253,32 @@ public class HttpServerManager implements ManagedServiceFactory { } } - public static class InternalHttpServiceServlet implements HttpSessionIdListener, Servlet { + public static class InternalHttpServiceServlet implements HttpSessionListener, HttpSessionIdListener, Servlet { // private static final long serialVersionUID = 7477982882399972088L; - private Servlet httpServiceServlet = new HttpServiceServlet(); + private final Servlet httpServiceServlet = new HttpServiceServlet(); private ClassLoader contextLoader; - private Method method; - - @Override - public void init(ServletConfig config) throws ServletException { - ServletContext context = config.getServletContext(); - contextLoader = (ClassLoader) context.getAttribute(INTERNAL_CONTEXT_CLASSLOADER); + private final Method sessionDestroyed; + private final Method sessionIdChanged; + public InternalHttpServiceServlet() { Class<?> clazz = httpServiceServlet.getClass(); + + try { + sessionDestroyed = clazz.getMethod("sessionDestroyed", new Class<?>[] {String.class}); //$NON-NLS-1$ + } catch (Exception e) { + throw new IllegalStateException(e); + } try { - method = clazz.getMethod("sessionIdChanged", new Class<?>[] {String.class}); //$NON-NLS-1$ + sessionIdChanged = clazz.getMethod("sessionIdChanged", new Class<?>[] {String.class}); //$NON-NLS-1$ } catch (Exception e) { - throw new ServletException(e); + throw new IllegalStateException(e); } + } + + @Override + public void init(ServletConfig config) throws ServletException { + ServletContext context = config.getServletContext(); + contextLoader = (ClassLoader) context.getAttribute(INTERNAL_CONTEXT_CLASSLOADER); Thread thread = Thread.currentThread(); ClassLoader current = thread.getContextClassLoader(); @@ -314,12 +326,35 @@ public class HttpServerManager implements ManagedServiceFactory { } @Override + public void sessionCreated(HttpSessionEvent event) { + // Nothing to do. + } + + @Override + public void sessionDestroyed(HttpSessionEvent event) { + Thread thread = Thread.currentThread(); + ClassLoader current = thread.getContextClassLoader(); + thread.setContextClassLoader(contextLoader); + try { + sessionDestroyed.invoke(httpServiceServlet, event.getSession().getId()); + } catch (IllegalAccessException e) { + // not likely + } catch (IllegalArgumentException e) { + // not likely + } catch (InvocationTargetException e) { + throw new RuntimeException(e.getCause()); + } finally { + thread.setContextClassLoader(current); + } + } + + @Override public void sessionIdChanged(HttpSessionEvent event, String oldSessionId) { Thread thread = Thread.currentThread(); ClassLoader current = thread.getContextClassLoader(); thread.setContextClassLoader(contextLoader); try { - method.invoke(httpServiceServlet, oldSessionId); + sessionIdChanged.invoke(httpServiceServlet, oldSessionId); } catch (IllegalAccessException e) { // not likely } catch (IllegalArgumentException e) { diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.http.servlet.tests/META-INF/MANIFEST.MF index 981c2c0f5..6304f11c6 100644 --- a/bundles/org.eclipse.equinox.http.servlet.tests/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.http.servlet.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: org.eclipse.equinox.http.servlet.tests Bundle-SymbolicName: org.eclipse.equinox.http.servlet.tests -Bundle-Version: 1.5.200.qualifier +Bundle-Version: 1.5.300.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Eclipse-BundleShape: dir Bundle-Activator: org.eclipse.equinox.http.servlet.tests.bundle.Activator diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/pom.xml b/bundles/org.eclipse.equinox.http.servlet.tests/pom.xml index 5d1437d51..a9b7e11a7 100644 --- a/bundles/org.eclipse.equinox.http.servlet.tests/pom.xml +++ b/bundles/org.eclipse.equinox.http.servlet.tests/pom.xml @@ -19,7 +19,7 @@ </parent> <groupId>org.eclipse.equinox</groupId> <artifactId>org.eclipse.equinox.http.servlet.tests</artifactId> - <version>1.5.200-SNAPSHOT</version> + <version>1.5.300-SNAPSHOT</version> <packaging>eclipse-test-plugin</packaging> <build> diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/testbase/BaseTest.java b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/testbase/BaseTest.java index 527492cae..59dee0567 100644 --- a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/testbase/BaseTest.java +++ b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/testbase/BaseTest.java @@ -69,6 +69,8 @@ public class BaseTest { System.setProperty("org.eclipse.jetty.servlet.LEVEL", "OFF"); System.setProperty("org.osgi.service.http.port", "0"); + System.setProperty("org.eclipse.equinox.http.jetty.context.sessioninactiveinterval", "1"); + System.setProperty("org.eclipse.equinox.http.jetty.housekeeper.interval", "10"); BundleContext bundleContext = getBundleContext(); installer = new BundleInstaller(TEST_BUNDLES_BINARY_DIRECTORY, bundleContext); advisor = new BundleAdvisor(bundleContext); diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java index 74a898559..daac63089 100644 --- a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java +++ b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java @@ -45,6 +45,7 @@ import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; @@ -1819,6 +1820,63 @@ public class ServletTest extends BaseTest { } @Test + public void test_Sessions05_Bug541607_MemoryLeak() throws Exception { + final List<String> sessionIds = new CopyOnWriteArrayList<>(); + HttpSessionListener sessionListener = new HttpSessionListener() { + + @Override + public void sessionDestroyed(HttpSessionEvent se) { + sessionIds.remove(se.getSession().getId()); + } + + @Override + public void sessionCreated(HttpSessionEvent se) { + sessionIds.add(se.getSession().getId()); + } + }; + HttpServlet sessionServlet = new HttpServlet() { + private static final long serialVersionUID = 1L; + + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, + IOException { + HttpSession session = request.getSession(); + response.getWriter().print("created " + session.getId()); + } + + }; + ServiceRegistration<Servlet> servletReg = null; + ServiceRegistration<HttpSessionListener> sessionListenerReg = null; + Dictionary<String, Object> servletProps = new Hashtable<String, Object>(); + servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/sessions"); + + try { + servletReg = getBundleContext().registerService(Servlet.class, sessionServlet, servletProps); + Dictionary<String, String> listenerProps = new Hashtable<String, String>(); + listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true"); + sessionListenerReg = getBundleContext().registerService(HttpSessionListener.class, sessionListener, listenerProps); + + // call the servet 10 times, we should get 10 sessions + for (int i = 0; i < 10; i++) { + requestAdvisor.request("sessions"); + } + + assertEquals("Wrong result", 10, sessionIds.size()); + Thread.sleep(12000); // 12 seconds + assertEquals("Wrong result", 0, sessionIds.size()); + } catch (Exception e) { + fail("Unexpected exception: " + e); + } finally { + if (servletReg != null) { + servletReg.unregister(); + } + if (sessionListenerReg != null) { + sessionListenerReg.unregister(); + } + } + } + + @Test public void test_Resource1() throws Exception { String expected = "a"; String actual; diff --git a/bundles/org.eclipse.equinox.http.servlet/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.http.servlet/META-INF/MANIFEST.MF index 92348f3cc..d6285ac27 100644 --- a/bundles/org.eclipse.equinox.http.servlet/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.http.servlet/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %bundleName Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.equinox.http.servlet -Bundle-Version: 1.5.200.qualifier +Bundle-Version: 1.5.300.qualifier Bundle-Activator: org.eclipse.equinox.http.servlet.internal.Activator Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.6 diff --git a/bundles/org.eclipse.equinox.http.servlet/pom.xml b/bundles/org.eclipse.equinox.http.servlet/pom.xml index 9faae4fdf..a50ce572c 100644 --- a/bundles/org.eclipse.equinox.http.servlet/pom.xml +++ b/bundles/org.eclipse.equinox.http.servlet/pom.xml @@ -20,6 +20,6 @@ </parent> <groupId>org.eclipse.equinox</groupId> <artifactId>org.eclipse.equinox.http.servlet</artifactId> - <version>1.5.200-SNAPSHOT</version> + <version>1.5.300-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java index 44b55ee97..1ad919b95 100644 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java @@ -1075,6 +1075,10 @@ public class HttpServiceRuntimeImpl } } + public void sessionDestroyed(String sessionId) { + httpSessionTracker.invalidate(sessionId, false); + } + private Map<String, Object> attributes; private final String targetFilter; private final ServiceRegistration<ServletContextHelper> defaultContextReg; diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpSessionTracker.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpSessionTracker.java index c4e7c8a83..e783b52df 100644 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpSessionTracker.java +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpSessionTracker.java @@ -69,7 +69,7 @@ public class HttpSessionTracker implements HttpSessionInvalidator { List<HttpSessionAttributeListener> httpSessionAttributeListeners = eventListeners.get(HttpSessionAttributeListener.class); - if (!httpSessionListeners.isEmpty()) { + if (!httpSessionAttributeListeners.isEmpty()) { Enumeration<String> enumeration = httpSessionAdaptor.getAttributeNames(); diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java index a4d64bb2b..7f5b3c8f6 100644 --- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java +++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java @@ -53,6 +53,10 @@ public class ProxyServlet extends HttpServlet { this.httpServiceRuntimeImpl = httpServiceRuntimeImpl; } + public void sessionDestroyed(String sessionId) { + httpServiceRuntimeImpl.sessionDestroyed(sessionId); + } + public void sessionIdChanged(String oldSessionId) { httpServiceRuntimeImpl.fireSessionIdChanged(oldSessionId); } |