This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-karaf.git
commit b08e6fcef735f89c97dd4e6762a0a659ff9188f7 Author: Claus Ibsen <[email protected]> AuthorDate: Mon Dec 21 14:01:51 2020 +0100 CAMEL-13443: camel-test-blueprint - Close file handles for PojoSRBundle bundles that are loaded from Jar via JarFile revision. Felix does not close the JarFile handle when the bundle is stopped and therefore leak file handles. --- .../test/blueprint/CamelBlueprintTestSupport.java | 40 +++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintTestSupport.java b/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintTestSupport.java index 7c35a87..213774d 100644 --- a/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintTestSupport.java +++ b/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintTestSupport.java @@ -18,10 +18,12 @@ package org.apache.camel.test.blueprint; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import java.io.Closeable; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.Field; import java.net.URL; import java.nio.file.Files; import java.util.Arrays; @@ -35,7 +37,9 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.jar.JarFile; +import org.osgi.framework.Bundle; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -404,7 +408,15 @@ public abstract class CamelBlueprintTestSupport extends CamelTestSupport { } } - CamelBlueprintHelper.disposeBundleContext(bundleContext); + // close bundle context + if (bundleContext != null) { + // remember bundles before closing + Bundle[] bundles = bundleContext.getBundles(); + // close bundle context + CamelBlueprintHelper.disposeBundleContext(bundleContext); + // now close jar files from the bundles + closeBundleJArFile(bundles); + } } @Override @@ -417,6 +429,32 @@ public abstract class CamelBlueprintTestSupport extends CamelTestSupport { } /** + * Felix Connect leaks "open files" as a JarFile on Bundle Revision is not closed when stopping the bundle + * which can cause the JVM to open up too many file handles. + */ + private void closeBundleJArFile(Bundle[] bundles) { + for (Bundle bundle : bundles) { + try { + // not all bundles is from PojoSRBundle that has a revision + Field field = bundle.getClass().getDeclaredField("m_revision"); + field.setAccessible(true); + Object val = field.get(bundle); + field = val.getClass().getDeclaredField("m_jar"); + field.setAccessible(true); + Object mJar = field.get(val); + if (mJar instanceof JarFile) { + JarFile jf = (JarFile) mJar; + log.debug("Closing bundle[{}] JarFile: {}", bundle.getBundleId(), jf.getName()); + jf.close(); + log.trace("Closed bundle[{}] JarFile: {}", bundle.getBundleId(), jf.getName()); + } + } catch (Throwable e) { + // ignore + } + } + } + + /** * Return the system bundle context */ protected BundleContext getBundleContext() {
