title: Java class loader bug: Caused by: java.io.IOException: Stream closed
body: <p>I'm getting a strange bug regarding I believe class loader issues when I deploy my webapp to Tomcat. The bug doesn't appear when I run my webapp locally using Jetty. It seems like my input streams for my .yml resource files are being closed for some reason when they shouldn't be. This bug first appeared when I tried to convert my single module project into a multi module project. Before that, it was working fine on Tomcat using the exact same code:</p>
  
  <pre><code>Caused by: org.yaml.snakeyaml.error.YAMLException: java.io.IOException: Stream closed
      at org.yaml.snakeyaml.reader.StreamReader.update(StreamReader.java:200)
      at org.yaml.snakeyaml.reader.StreamReader.&lt;init&gt;(StreamReader.java:60)
      at org.yaml.snakeyaml.Yaml.load(Yaml.java:412)
      at com.config.ConfigProvider.&lt;init&gt;(ConfigProvider.java:20)
      ... 49 more
  Caused by: java.io.IOException: Stream closed
      at java.io.PushbackInputStream.ensureOpen(PushbackInputStream.java:57)
      at java.io.PushbackInputStream.read(PushbackInputStream.java:149)
      at org.yaml.snakeyaml.reader.UnicodeReader.init(UnicodeReader.java:90)
      at org.yaml.snakeyaml.reader.UnicodeReader.read(UnicodeReader.java:122)
      at java.io.Reader.read(Reader.java:123)
      at org.yaml.snakeyaml.reader.StreamReader.update(StreamReader.java:184)
      ... 55 more
  </code></pre>
  
  <p>Here's the line that causes the bug:</p>
  
  <pre><code>String s = ConfigProvider.getConfig().getString("test");
  </code></pre>
  
  <p>Here's the <code>ConfigProvider</code> class. It basically scans for all resource files of regex <code>^.*\\.config\\.yml$</code>, converts it into a <code>Map&lt;String, Object&gt;</code>, and combines all the obtained <code>Map&lt;String, Object&gt;</code> into a single <code>Map&lt;String, Object&gt;</code>:</p>
  
  <pre><code>1 public class ConfigProvider {
  2     protected static final String CONFIG_PACKAGE = ConfigProvider.class.getPackage().getName();
  3     protected static final Pattern CONFIG_PATH_REGEX = Pattern.compile("^.*\\.config\\.yml$");
  4 
  5     private static final ConfigProvider INSTANCE = new ConfigProvider();
  6     private Map&lt;String, Object&gt; configMap;
  7 
  8     protected ConfigProvider() {
  9         configMap = new HashMap&lt;String, Object&gt;();
  10 
  11        Set&lt;String&gt; configPaths = new Reflections(CONFIG_PACKAGE,
  12            new ResourcesScanner()).getResources(CONFIG_PATH_REGEX);
  13
  14        if (configPaths.isEmpty()) {
  15            throw new RuntimeException("no config paths found");
  16        }
  17
  18        for (String path : configPaths) {
  19            InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
  20            Map&lt;String, Object&gt; fullConfig = new Map&lt;String, Object&gt;((Map) new Yaml().load(inputStream));
  21        
  22            try {
  23                inputStream.close();
  24            } catch (IOException e) {
  25                throw new RuntimeException("error closing stream");
  26            }
  27
  28            MapUtils.merge(configMap, fullConfig);
  29        }
  30    }
  31
  32    public static ConfigMap getConfig() {
  33        return INSTANCE.configMap;
  34    }
  35 }
  </code></pre>
  
  <p>Here's my project structure, titled Foo:</p>
  
  <pre><code>- Foo (this is a module)
      - .idea
      - application (this is a module)
          - src
              - main
                  - java
                  - resources
                      - application.config.yml
                  - webapp
              - test
          - pom.xml
      - client (this is a module)
          - src
              - main
                  - java
                  - resources
                      - client.config.yml
                  - webapp
              - test
          - pom.xml
      - pom.xml
  </code></pre>
  
  <p><code>ConfigProvider</code> is a class I get from my parent pom file (<code>Foo/pom.xml</code>). I package a <code>WAR</code> file from the <code>application</code> module (<code>Foo/application/target/application.war</code>), and deploy it with Tomcat. Previously, my project was a single module project with just a <code>Foo</code> module being identical to <code>application</code> module. Then I added a <code>client</code> module and converted the project into a multi module project, and the problem has showed up. I think it's because my class loader is getting messed up due to the multiple modules. I've spent a lot of time trying to debug this and still haven't gotten anywhere. Anyone know what could be the cause, or can think of possible things to try?</p>
  
  <p>Please let me know if you need more info.</p>