This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-vfs.git

commit fdb039900ceb9898555afc1522d8d348e9961ff9
Author: Gary Gregory <garydgreg...@gmail.com>
AuthorDate: Thu Feb 25 11:33:53 2021 -0500

    Fix file resource leak in CombinedResources (properties file) which
    keeps the jar file open.
    
    - The Messages class' singleton loads a CombinedResources which loads a
    property file.
    - This means the jar file remains open while the JVM is up which
    prevents the jar file from being deleted when a webapp is undeplyed from
    Tomcat for example.
    - Simplify initialization.
---
 .../commons/vfs2/util/CombinedResources.java       | 68 ++++++++++------------
 src/changes/changes.xml                            |  5 +-
 2 files changed, 36 insertions(+), 37 deletions(-)

diff --git 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/util/CombinedResources.java
 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/util/CombinedResources.java
index fa54bb6..642b4a0 100644
--- 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/util/CombinedResources.java
+++ 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/util/CombinedResources.java
@@ -17,6 +17,7 @@
 package org.apache.commons.vfs2.util;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.URL;
 import java.util.Enumeration;
 import java.util.Locale;
@@ -33,11 +34,38 @@ public class CombinedResources extends ResourceBundle {
     // locale.getVariant()
 
     private final String resourceName;
-    private boolean inited;
+    private volatile boolean inited;
     private final Properties properties = new Properties();
 
     public CombinedResources(final String resourceName) {
         this.resourceName = resourceName;
+        init();
+    }
+
+    @Override
+    public Enumeration<String> getKeys() {
+        return new Enumeration<String>() {
+            @Override
+            public boolean hasMoreElements() {
+                return properties.keys().hasMoreElements();
+            }
+
+            @Override
+            public String nextElement() {
+                // We know that our properties will only ever contain Strings
+                return (String) properties.keys().nextElement();
+            }
+
+        };
+    }
+
+    public String getResourceName() {
+        return resourceName;
+    }
+
+    @Override
+    protected Object handleGetObject(final String key) {
+        return properties.get(key);
     }
 
     protected void init() {
@@ -55,7 +83,7 @@ public class CombinedResources extends ResourceBundle {
         if (locale == null) {
             return;
         }
-        final String[] parts = new String[] { locale.getLanguage(), 
locale.getCountry(), locale.getVariant() };
+        final String[] parts = new String[] {locale.getLanguage(), 
locale.getCountry(), locale.getVariant()};
         final StringBuilder sb = new StringBuilder();
         for (int i = 0; i < 3; i++) {
             sb.append(getResourceName());
@@ -81,8 +109,8 @@ public class CombinedResources extends ResourceBundle {
                 final Enumeration<URL> resources = 
loader.getResources(resourceName);
                 while (resources.hasMoreElements()) {
                     final URL resource = resources.nextElement();
-                    try {
-                        
properties.load(resource.openConnection().getInputStream());
+                    try (final InputStream inputStream = 
resource.openConnection().getInputStream()) {
+                        properties.load(inputStream);
                     } catch (final IOException ignored) {
                         // Ignore
                     }
@@ -92,36 +120,4 @@ public class CombinedResources extends ResourceBundle {
             }
         }
     }
-
-    public String getResourceName() {
-        return resourceName;
-    }
-
-    @Override
-    public Enumeration<String> getKeys() {
-        if (!inited) {
-            init();
-        }
-        return new Enumeration<String>() {
-            @Override
-            public boolean hasMoreElements() {
-                return properties.keys().hasMoreElements();
-            }
-
-            @Override
-            public String nextElement() {
-                // We know that our properties will only ever contain Strings
-                return (String) properties.keys().nextElement();
-            }
-
-        };
-    }
-
-    @Override
-    protected Object handleGetObject(final String key) {
-        if (!inited) {
-            init();
-        }
-        return properties.get(key);
-    }
 }
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 0cca8d7..e3887e5 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -69,6 +69,9 @@ The <action> type attribute can be add,update,fix,remove.
       <action issue="VFS-748" dev="ggregory" due-to="PeterAlfredLee, Gary 
Gregory" type="fix">
         TarProvider Incorrectly marks file IMAGINARY after garbage collection 
with WeakRefFilesCache, #97.
       </action>
+      <action dev="ggregory" due-to="Gary Gregory" type="fix">
+        Fix file resource leak in CombinedResources (properties file).
+      </action>
       <!-- ADDS -->
       <action dev="ggregory" due-to="Boris Petrov, Gary Gregory" type="add">
         Add ability to remove a provider from DefaultFileSystemManager #149.
@@ -230,7 +233,7 @@ The <action> type attribute can be add,update,fix,remove.
         SftpFileSystem returns null channel and produce NPE - fix get… #110.
       </action>
       <action dev="ggregory" due-to="PeterAlfredLee" type="add">
-        Fix some test error when JVM's default language is not US en #107. 
+        Fix some test error when JVM's default language is not US en #107.
       </action>
       <action issue="VFS-788" dev="ggregory" due-to="satish bhor" type="fix">
         [webdav/webdav4] Jackrabbit1 and jackrabbit2 modules getting same OSGi 
symbolic name.

Reply via email to