diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/ResourceLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/ResourceLoader.java index ec7ccd1e47..61c5087b23 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/ResourceLoader.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/ResourceLoader.java @@ -10,7 +10,9 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; +import java.net.JarURLConnection; import java.net.URL; +import java.net.URLConnection; import net.sourceforge.pmd.RuleSetNotFoundException; @@ -41,6 +43,8 @@ public final class ResourceLoader { * Method to find a file, first by finding it as a file (either by the * absolute or relative path), then as a URL, and then finally seeing if it * is on the classpath. + *
+ * Caller is responsible for closing the {@link InputStream}. * * @param name * String @@ -59,6 +63,8 @@ public final class ResourceLoader { /** * Uses the ClassLoader passed in to attempt to load the resource if it's * not a File or a URL + *
+ * Caller is responsible for closing the {@link InputStream}.
*
* @param name
* String
@@ -91,8 +97,30 @@ public final class ResourceLoader {
if (resource == null) {
// Don't throw RuleSetNotFoundException, keep API compatibility
return null;
+ } else {
+ final URLConnection connection = resource.openConnection();
+ final InputStream inputStream = connection.getInputStream();
+ if (connection instanceof JarURLConnection) {
+ // Wrap the InputStream to also close the underlying JarFile if from a JarURLConnection.
+ // See https://github.com/pmd/pmd/issues/337
+ return new InputStream() {
+ @Override
+ public int read() throws IOException {
+ return inputStream.read();
+ }
+
+ @Override
+ public void close() throws IOException {
+ inputStream.close();
+ if (connection instanceof JarURLConnection) {
+ ((JarURLConnection) connection).getJarFile().close();
+ }
+ }
+ };
+ } else {
+ return inputStream;
+ }
}
- return resource.openStream();
} catch (IOException e1) {
// Ignored
}
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetFactoryTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetFactoryTest.java
index cb9f003dd0..252c346450 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetFactoryTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetFactoryTest.java
@@ -55,6 +55,7 @@ public class RuleSetFactoryTest {
InputStream in = ResourceLoader.loadResourceAsStream("net/sourceforge/pmd/rulesets/reference-ruleset.xml",
this.getClass().getClassLoader());
Assert.assertNotNull("Test ruleset not found - can't continue with test!", in);
+ in.close();
RuleSetFactory rsf = new RuleSetFactory();
RuleSets rs = rsf.createRuleSets("net/sourceforge/pmd/rulesets/reference-ruleset.xml");
diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java b/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java
index e6f4d81647..38c7c12b59 100644
--- a/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java
+++ b/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java
@@ -229,7 +229,9 @@ public abstract class AbstractRuleSetFactoryTest {
List