Read a *.properties file from a *.jar file

jarwell this is an embrassing thing to share but this is the fact, that I found difficulties when i tried to read *.properties file when it's already in *.jar file first, I tried to load the properties file with this way :

   1: URL url = InOut.class.getClassLoader().getResource("appSetting/test.properties");
   2: File f = new File(url.toURI());
   3: FileInputStream fis =  new FileInputStream(f);
   4: Properties prop  = new Properties();
   5: prop.load(fis);
   6: System.out.println(prop.getProperty("test"));

there's no problem when I try to run it from Eclipse, but when I already have exported it into a .jar file and try to run it, this error hit my screen... –____–

java.lang.IllegalArgumentException: URI is not hierarchical
at java.io.File.<init>(File.java:380)
at inOutTask.InOut.main(InOut.java:49)

well, I tried to load a Properties file from File object initiated with URI. And the URI comes from URL object that I have created in the first line : jar:file:/home/123/abc/test.jar!/appSetting/test.properties. as you can see it tried to load a properties file in a jar file. in my opinion we can't access file in a file.. so that's the problem. Actually method load() in line 5 accept an InputStream object, so why it could accept FileInputStreamObject? It's because FileInputStream is an extended class from InputStream. so to get around this problem I just need to pass an InputStream object to method load() with this way :


   1: InputStream is = ClassName.class.getClassLoader().getResourceAsStream("appSetting/test.properties");
   2: Properties prop  = new Properties();
   3: prop.load(is);
   4: System.out.println(prop.getProperty("test"));

or


   1: InputStream is = ClassName.class.getResourceAsStream("/appSetting/test.properties");
   2: Properties prop  = new Properties();
   3: prop.load(is);
   4: System.out.println(prop.getProperty("test"));

I use ClassName.class because I called this line of code from a main method, so if want to call this getResourceAsStream() method from a POJO class just change it into this.getClass(). the difference between those two are :

  • the first way ClassLoader.getResourceAsStream(path) will consider all paths to be absolute paths. So calling String.getClassLoader.getResourceAsString("myfile.txt") and String.getClassLoader.getResourceAsString("/myfile.txt") will both look for a file in your classpath at the following location: "./myfile.txt"
  • the second way in Class.getResourceAsStream(path), the path is interpreted as a path local to the package of the class you are calling it from. For example calling, String.getResourceAsStream("myfile.txt") will look for a file in your classpath at the following location: "java/lang/myfile.txt". If your path starts with a '/', the it will be considered an absolute path, and will start searching from the root of the classpath. So calling String.getResourceAsStream("/myfile.txt") will look at the following location in your in your class path "./myfile.txt

0 comments:

Post a Comment