javagroovyproperties-file

Groovy - how to read properties from a property file in a jar on the classpath


Thought this would be easy and straightforward, especially in Groovy, but I could use come help with accessing properties from property files that are in jar files on the classpath. I thought Java and therefore Groovy supported that as a foundational part of the language and runtime environment.

I thought I was getting close with this -

String propPath = this.class.getClassLoader().getResource("conf/Config.properties").getPath()

println "propPath = '$propPath'"

Properties appProps = new Properties()

appProps.load(new FileInputStream(propPath))
  
String appVersion = appProps.getProperty("version")

println "appVersion = $appVersion"

but propPath is getting set to the full pathname of the jar file (so far so good) but is is prepended with "file:" and it has an exclamation point followed by the resource name - /app/lib/util.jar!conf/Config.properties and so FileInputStream throws a FileNotFoundException (as expected).

Execution output:

propPath = 'file:/app/lib/util.jar!/conf/Config.properties'
Exception thrown

java.io.FileNotFoundException: file:/app/lib/util.jar!/conf/Config.properties (No such file or directory)

Any help is appreciated.


Solution

  • Take a close look at the URL, which is the result from getResource (URL is already the first warning sign). It starts like a regular file:// URL but then has a !... in it - this the JVM telling you, that the file you want is inside this archive.

    FileInputStream only really can load files from the file-system, hence the error. At best FileInputStream could read the .jar-file for you.

    So you need a way read the content of your file from "the class-path" and the shortest route is to request an InputStream from the class-loader and pass that to load your properties:

    Properties appProps = new Properties().tap{
        load(
                Thread.currentThread().contextClassLoader.getResourceAsStream("conf/Config.properties")
        )
    }