This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch camel-3.x in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-3.x by this push: new 8711f64d9c7 Bean leak (#11818) 8711f64d9c7 is described below commit 8711f64d9c7887c333b4461c0cec14628dc44db5 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Tue Oct 24 13:00:50 2023 +0200 Bean leak (#11818) * CAMEL-20035: Added javadoc * CAMEL-20035: camel-bean - Fix bean info cache gets populated per instance instead of per class. Only in special use-case use per instance. --- .../apache/camel/component/bean/BeanComponent.java | 4 +++- .../org/apache/camel/component/bean/BeanInfo.java | 16 ++++++++++++++-- .../component/bean/DefaultBeanProcessorFactory.java | 3 +++ .../java/org/apache/camel/support/LRUCache.java | 21 +++++++++++++++++++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanComponent.java b/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanComponent.java index 1c588e26e91..e33981c0b57 100644 --- a/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanComponent.java +++ b/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanComponent.java @@ -81,7 +81,9 @@ public class BeanComponent extends DefaultComponent { } void addBeanInfoToCache(BeanInfoCacheKey key, BeanInfo beanInfo) { - beanInfoCache.put(key, beanInfo); + if (beanInfo != null) { + beanInfoCache.put(key, beanInfo); + } } @Override diff --git a/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanInfo.java b/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanInfo.java index f53439b6b75..b5392d37632 100644 --- a/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanInfo.java +++ b/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanInfo.java @@ -111,9 +111,13 @@ public class BeanInfo { this.component = beanComponent; final BeanInfoCacheKey key = new BeanInfoCacheKey(type, instance, explicitMethod); + final BeanInfoCacheKey key2 = instance != null ? new BeanInfoCacheKey(type, null, explicitMethod) : null; // lookup if we have a bean info cache BeanInfo beanInfo = component.getBeanInfoFromCache(key); + if (key2 != null && beanInfo == null) { + beanInfo = component.getBeanInfoFromCache(key2); + } if (beanInfo != null) { // copy the values from the cache we need defaultMethod = beanInfo.defaultMethod; @@ -158,8 +162,16 @@ public class BeanInfo { operationsWithHandlerAnnotation = Collections.unmodifiableList(operationsWithHandlerAnnotation); methodMap = Collections.unmodifiableMap(methodMap); - // add new bean info to cache - component.addBeanInfoToCache(key, this); + // key must be instance based for custom/handler annotations + boolean instanceBased = !operationsWithCustomAnnotation.isEmpty() || !operationsWithHandlerAnnotation.isEmpty(); + if (instanceBased) { + // add new bean info to cache (instance based) + component.addBeanInfoToCache(key, this); + } else { + // add new bean info to cache (not instance based, favour key2 if possible) + BeanInfoCacheKey k = key2 != null ? key2 : key; + component.addBeanInfoToCache(k, this); + } } public Class<?> getType() { diff --git a/components/camel-bean/src/main/java/org/apache/camel/component/bean/DefaultBeanProcessorFactory.java b/components/camel-bean/src/main/java/org/apache/camel/component/bean/DefaultBeanProcessorFactory.java index 9ff2ee574b6..7931d9a66d7 100644 --- a/components/camel-bean/src/main/java/org/apache/camel/component/bean/DefaultBeanProcessorFactory.java +++ b/components/camel-bean/src/main/java/org/apache/camel/component/bean/DefaultBeanProcessorFactory.java @@ -28,6 +28,7 @@ import org.apache.camel.StaticService; import org.apache.camel.spi.BeanProcessorFactory; import org.apache.camel.spi.annotations.JdkService; import org.apache.camel.support.CamelContextHelper; +import org.apache.camel.support.service.ServiceHelper; import org.apache.camel.support.service.ServiceSupport; import org.apache.camel.util.ObjectHelper; import org.slf4j.Logger; @@ -205,6 +206,8 @@ public final class DefaultBeanProcessorFactory extends ServiceSupport @Override protected void doInit() throws Exception { parameterMappingStrategy = ParameterMappingStrategyHelper.createParameterMappingStrategy(getCamelContext()); + beanComponent = getCamelContext().getComponent("bean", BeanComponent.class); + ServiceHelper.initService(beanComponent); } } diff --git a/core/camel-support/src/main/java/org/apache/camel/support/LRUCache.java b/core/camel-support/src/main/java/org/apache/camel/support/LRUCache.java index bc474a98793..e4bd04f6395 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/LRUCache.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/LRUCache.java @@ -18,18 +18,39 @@ package org.apache.camel.support; import java.util.Map; +/** + * A least-recently-used cache. + */ public interface LRUCache<K, V> extends Map<K, V> { + /** + * Clears the cache + */ void cleanUp(); + /** + * Reset usage statistics + */ void resetStatistics(); + /** + * Gets the number of evicted elements + */ long getEvicted(); + /** + * Gets the number of cache misses. + */ long getMisses(); + /** + * Gets the number of cache hits. + */ long getHits(); + /** + * Maximum cache capacity. + */ int getMaxCacheSize(); }