Home » Java » java – How to refer to a file inside spring boot application jar as a -D property value while starting the app from command line?-Exceptionshub

java – How to refer to a file inside spring boot application jar as a -D property value while starting the app from command line?-Exceptionshub

Posted by: admin February 25, 2020 Leave a comment

Questions:

I have a simple spring boot application that needs java.security.krb5.conf property value set to a custom krb5.conf file. I have added the file inside the src/main/resources folder and maven make it packaged into the jar.

to start the app , I run
java -jar -Djava.security.krb5.conf=<localPath>/krb5.conf my-jar.jar

currently I have to give the <localPath> as the path to the file on my machine. Is there a way to refer to the file inside the jar so that I can run in any machine without creating the file file first on the machine?

things I tried so far:

  • give -Djava.security.krb5.conf=classpath:krb5.conf (also ./krb5.conf). Didn’t work
  • I see most of the examples for ‘how to read files from class path’ refer to getClass.getResource (filename). So I tried do getClass.getResource (filename).getPath() so that I can set it as java.security.krb5.conf system property while starting the app in main class instead of passing from command line. But the string that getPath shows is something like /<diskPath>/my-jar.jar!/BOOT-INF/classes!/krb5.conf and this path is not working when I try to read the file for testing.
  • Create a copy of the file to the running dir on-the-fly, in main method before calling SprinApplication.run. This is what I am doing now.
    try(
       InputStream in = new ClassPathResource("krb5.conf").getInputStream();
       OutputStream out = new FileOutputStream( new File("krb5copy.conf"));) {
       IOUtils.copy(in, out);
    }
    System.setProperty("java.security.krb5.conf","krb5copy.conf");

If there is a solution for this question , I can see other use cases such as providing the trustore file included in jar as javax.net.ssl.trustStore etc.

How to&Answers:

give -Djava.security.krb5.conf=classpth:krb5.conf (also ./krb5.conf).
Didn’t work

It’s not ‘classpth’ it’s ‘classpath’, actually. AND with a slash after it.

-Djava.security.krb5.conf=classpath/:krb5.conf should work.

Answer:

The code that reads the krb5.conf configuration file uses FileInputStream, which requires the path to the file and doesn’t “understand” classpath: prefix.

The idea below is to locate the file on the classpath and from that to get the path to the file:

ClassPathResource resource = new ClassPathResource("krb5.conf");
try
{
   String fileSpec = resource.getURL().getFile();
   System.setProperty("java.security.krb5.conf", fileSpec);
}
catch (IOException e)
{
   // TODO handle the exception
   e.printStackTrace();
}

EDIT: When packaged as SpringBoot fat JAR, trying to read the file with FileInputStream results in java.io.FileNotFoundException: file:/<path-to-jar/<jar-name>.jar!/BOOT-INF/classes!/krb5.conf (No such file or directory) 🙁