2

I have this code

    InputStream stream1 = ResponseCreator.class.getResourceAsStream("version.properties");
    InputStream stream2 = ResponseCreator.class.getResourceAsStream("/version.properties");
    InputStream stream3 = ResponseCreator.class.getClassLoader().getResourceAsStream("version.properties");
    InputStream stream4 = ResponseCreator.class.getClassLoader().getResourceAsStream("/version.properties");

    System.out.println("result1="+stream1);
    System.out.println("result2="+stream2);
    System.out.println("result3="+stream3);
    System.out.println("result4="+stream4);

and the results are...

result1=null
result2=java.io.BufferedInputStream@75412c2f
result3=java.io.BufferedInputStream@282ba1e
result4=null

That seems very odd and inconsistent and I even see posts saying stream1 is the way to go and that doesn't even work for me (eclipse IDE run, Intellij IDE run on MAC both yield the same)

I was running jdk8 and now I tried with 11 which is what we run now. Here is the results..

INFO: Starting Development Server under java version=11.0.5
result1=null 
result2=sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@3b220bcb
result3=sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@2b95e48b
result4=null
Dean Hiller
  • 19,235
  • 25
  • 129
  • 212
  • Which version of java are you using? – cse Mar 18 '20 at 02:09
  • @cse updated post. we were using jdk8 and now 11. It's odd the Stream changed...lol. – Dean Hiller Mar 24 '20 at 21:20
  • Does [this answer](https://stackoverflow.com/a/6608848/1031296) help with your question? – vicpermir Mar 24 '20 at 21:27
  • Did you **read the documentation**, i.e. the javadoc of [`Class.getResourceAsStream(String)`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getResourceAsStream-java.lang.String-) and [`ClassLoader.getResourceAsStream(String)`](https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html#getResourceAsStream-java.lang.String-). It very clearly explains how they work, and why e.g. `stream1` is null. – Andreas Mar 24 '20 at 21:28

1 Answers1

2

The javadoc of Class.getResourceAsStream(String name) says:

  • If the name begins with a '/' ('\u002f'), then the absolute name of the resource is the portion of the name following the '/'.

  • Otherwise, the absolute name is of the following form:

     modified_package_name/name 
    

    Where the modified_package_name is the package name of this object with '/' substituted for '.' ('\u002e').

So, if we assume that class ResponseCreator is in package com.example then:

// The following are the same, and returns resource "com/example/version.properties"
ResponseCreator.class.getResourceAsStream("version.properties")
ResponseCreator.class.getClassLoader().getResourceAsStream("com/example/version.properties")

// The following are the same, and returns resource "version.properties"
ResponseCreator.class.getResourceAsStream("/version.properties")
ResponseCreator.class.getClassLoader().getResourceAsStream("version.properties")

// The following returns null because resource names don't start with /
ResponseCreator.class.getClassLoader().getResourceAsStream("/version.properties")

Since you only have resource "version.properties", you get:

  • stream1 returns null (not found)

  • stream2 and stream3 returns a stream for the resource

  • stream4 returns null (not found, aka invalid name)

There is nothing inconsistent about this. The methods do exactly what they are documented to do. It is entirely up to you to read the documentation, so you understand what the methods do, rather than attempting to guess how they work.

Community
  • 1
  • 1
Andreas
  • 154,647
  • 11
  • 152
  • 247