FISH-5723 Fixes WebappClassloader memory-leak issue by removing JAXRSResources classes from cache on shutdown event (#5102)
* FISH-5723 Fixes WebappClassloader memory-leak issue by removing JAXRS Resources classes from cache on shutdown event
Signed-off-by: Gaurav Gupta <gaurav.gupta@payara.fish>
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/Cache.java b/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/Cache.java
index 923552c..40d94ab 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/Cache.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/Cache.java
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022 Payara Foundation and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,6 +17,7 @@
package org.glassfish.jersey.internal.util.collection;
+import java.util.Enumeration;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
@@ -108,6 +110,15 @@
}
/**
+ * Get the cache keys
+ *
+ * @return
+ */
+ public Enumeration<K> keys() {
+ return cache.keys();
+ }
+
+ /**
* Returns true if the key has already been cached.
*
* @param key item key.
diff --git a/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java b/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java
index 4d0eed3..498f041 100644
--- a/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java
+++ b/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2018 Payara Foundation and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2022 Payara Foundation and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -66,6 +66,7 @@
import jakarta.enterprise.inject.spi.Bean;
import jakarta.enterprise.inject.spi.BeanManager;
import jakarta.enterprise.inject.spi.BeforeBeanDiscovery;
+import jakarta.enterprise.inject.spi.BeforeShutdown;
import jakarta.enterprise.inject.spi.Extension;
import jakarta.enterprise.inject.spi.InjectionPoint;
import jakarta.enterprise.inject.spi.InjectionTarget;
@@ -960,6 +961,11 @@
);
}
+ @SuppressWarnings("unused")
+ private void beforeShutDown(@Observes final BeforeShutdown beforeShutdown, final BeanManager beanManager) {
+ runtimeSpecifics.clearJaxRsResource(Thread.currentThread().getContextClassLoader());
+ }
+
/**
* Add a predicate to test HK2 dependency to create a CDI bridge bean to HK2 for it.
* @param predicate to test whether given class is a HK2 dependency.
diff --git a/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProviderClientRuntimeSpecifics.java b/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProviderClientRuntimeSpecifics.java
index bad8dca..a6eee5c 100644
--- a/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProviderClientRuntimeSpecifics.java
+++ b/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProviderClientRuntimeSpecifics.java
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022 Payara Foundation and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -20,6 +21,7 @@
import jakarta.enterprise.inject.spi.AnnotatedType;
import jakarta.ws.rs.core.Context;
import java.lang.annotation.Annotation;
+import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
@@ -59,4 +61,9 @@
public boolean isJaxRsResource(Class<?> resource) {
return false;
}
+
+ @Override
+ public void clearJaxRsResource(ClassLoader loader) {
+ }
+
}
diff --git a/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProviderRuntimeSpecifics.java b/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProviderRuntimeSpecifics.java
index 9ca5ce4..359309f 100644
--- a/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProviderRuntimeSpecifics.java
+++ b/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProviderRuntimeSpecifics.java
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022 Payara Foundation and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -34,4 +35,6 @@
boolean isAcceptableResource(Class<?> resource);
boolean isJaxRsResource(Class<?> resource);
+
+ void clearJaxRsResource(ClassLoader loader);
}
diff --git a/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProviderServerRuntimeSpecifics.java b/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProviderServerRuntimeSpecifics.java
index a677436..826fdc2 100644
--- a/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProviderServerRuntimeSpecifics.java
+++ b/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProviderServerRuntimeSpecifics.java
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022 Payara Foundation and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -48,6 +49,7 @@
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.util.Enumeration;
/**
* Server side runtime CDI ComponentProvider specific implementation.
@@ -226,6 +228,17 @@
}
@Override
+ public void clearJaxRsResource(ClassLoader loader) {
+ Enumeration<Class<?>> keys = jaxRsResourceCache.keys();
+ while (keys.hasMoreElements()) {
+ Class<?> key = keys.nextElement();
+ if (key.getClassLoader() == loader) {
+ jaxRsResourceCache.remove(key);
+ }
+ }
+ }
+
+ @Override
public boolean containsJaxRsParameterizedCtor(final AnnotatedType annotatedType) {
return CdiComponentProvider
.containAnnotatedParameters(annotatedType.getConstructors(), JaxRsParamProducer.JAX_RS_STRING_PARAM_ANNOTATIONS);