1 /*
2 * Licensed under the GPL License. You may not use this file except in compliance with the License.
3 * You may obtain a copy of the License at
4 *
5 * https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
6 *
7 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
8 * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
9 * PURPOSE.
10 */
11 package psiprobe;
12
13 import jakarta.servlet.ServletContextEvent;
14 import jakarta.servlet.ServletContextListener;
15 import jakarta.servlet.annotation.WebListener;
16
17 import javax.imageio.ImageIO;
18
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 /**
23 * Prevents a classloader leak.
24 *
25 * <p>
26 * As suggested by: <a href="https://cdivilly.wordpress.com/2012/04/23/permgen-memory-leak/">Colm
27 * Divilly</a>
28 */
29 @WebListener
30 public class AwtAppContextClassloaderListener implements ServletContextListener {
31
32 /** The Constant logger. */
33 private static final Logger logger =
34 LoggerFactory.getLogger(AwtAppContextClassloaderListener.class);
35
36 /**
37 * Forces the {@code sun.awt.AppContext} singleton to be created and initialized when the context
38 * is initialized.
39 *
40 * @param sce the event containing the context being initialized
41 */
42 @Override
43 public void contextInitialized(ServletContextEvent sce) {
44 try {
45 final ClassLoader active = Thread.currentThread().getContextClassLoader();
46 try {
47 // Find the root classloader
48 ClassLoader root = active;
49 while (root.getParent() != null) {
50 root = root.getParent();
51 }
52 // Temporarily make the root class loader the active class loader
53 Thread.currentThread().setContextClassLoader(root);
54 /*
55 * Forces the sun.awt.AppContext singleton to be created and initialized. Call
56 * ImageIO.getCacheDirectory() to avoid direct call to Oracle JVM internal class
57 * sun.awt.AppContext. Same solution as in
58 * org.apache.catalina.core.JreMemoryLeakPreventionListener which is optional on Tomcat.
59 */
60 ImageIO.getCacheDirectory();
61 } finally {
62 // restore the class loader
63 Thread.currentThread().setContextClassLoader(active);
64 }
65 logger.info("AwtAppContextClassloaderListener Initialized");
66 } catch (Exception e) {
67 logger.error("Failed to address PermGen leak.", e);
68 }
69 }
70
71 @Override
72 public void contextDestroyed(ServletContextEvent sce) {
73 // Not Implemented
74 }
75
76 }