13

I have a spring boot web application which I run using java -jar application.jar. I need to get the jar parent folder path dynamically from the code. How can I accomplish that?

I have already tried this, but without success.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Carlos Nantes
  • 1,197
  • 1
  • 12
  • 23
  • Welcome to Stack Overflow, please read about [How to Ask a Question](https://stackoverflow.com/help/how-to-ask) and [How to create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) in this site. Always be specific and make your best effort before asking. In this case, you mention that you tried a solution but what is your error or what is your basic implementation. – Teocci Oct 10 '17 at 01:22
  • If I from the terminal with **java -jar application.jar** the code presented on that questtion will return null. I'll put the code here: `MyCustomClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath();` If I run the application using Spring Tools Suit IDE play button, the result of this code will be: `/D:/arquivos/repositorio/myapp/trunk/target/classes/` – Carlos Nantes Oct 10 '17 at 01:41

3 Answers3

32

Well, what have worked for me was an adaptation of this answer. The code is:

if you run using java -jar myapp.jar dirtyPath will be something close to this: jar:file:/D:/arquivos/repositorio/myapp/trunk/target/myapp-1.0.3-RELEASE.jar!/BOOT-INF/classes!/br/com/cancastilho/service. Or if you run from Spring Tools Suit, something like this: file:/D:/arquivos/repositorio/myapp/trunk/target/classes/br/com/cancastilho/service

public String getParentDirectoryFromJar() {
    String dirtyPath = getClass().getResource("").toString();
    String jarPath = dirtyPath.replaceAll("^.*file:/", ""); //removes file:/ and everything before it
    jarPath = jarPath.replaceAll("jar!.*", "jar"); //removes everything after .jar, if .jar exists in dirtyPath
    jarPath = jarPath.replaceAll("%20", " "); //necessary if path has spaces within
    if (!jarPath.endsWith(".jar")) { // this is needed if you plan to run the app using Spring Tools Suit play button. 
        jarPath = jarPath.replaceAll("/classes/.*", "/classes/");
    }
    String directoryPath = Paths.get(jarPath).getParent().toString(); //Paths - from java 8
    return directoryPath;
}

EDIT:

Actually, if your using spring boot, you could just use the ApplicationHome class like this:

ApplicationHome home = new ApplicationHome(MyMainSpringBootApplication.class);
home.getDir();    // returns the folder where the jar is. This is what I wanted.
home.getSource(); // returns the jar absolute path.
Carlos Nantes
  • 1,197
  • 1
  • 12
  • 23
1
    File file = new File(".");
    logger.debug(file.getAbsolutePath());

This worked for me to get the path where my jar is running, I hope this is what you are expecting.

  • This code will return the folder path where I issued the java -jar command. If I run it from my target folder: cd D:\arquivos\repositorio\myapp\trunk\target java -jar application.jar I'll get this result: `D:\arquivos\repositorio\myapp\trunk\target\.` If I run it from an outside folder, let's say: cd D:\arquivos\repositorio\myapp\trunk\ java -jar target\application.jar I'll get: `D:\arquivos\repositorio\myapp\trunk\.` It partially solves my problem. Is there a way to find the path even if I issue the command from another external folder? – Carlos Nantes Oct 10 '17 at 02:16
  • Will this not keep on creating new files of . everytime the script is run? – mohdnaveed Jul 22 '19 at 17:31
0

Try this code

public static String getParentRealPath(URI uri) throws URISyntaxException {
    if (!"jar".equals(uri.getScheme()))
        return new File(uri).getParent();
    do {
        uri = new URI(uri.getSchemeSpecificPart());
    } while ("jar".equals(uri.getScheme()));
    File file = new File(uri);
    do {
        while (!file.getName().endsWith(".jar!"))
            file = file.getParentFile();
        String path = file.toURI().toString();
        uri = new URI(path.substring(0, path.length() - 1));
        file = new File(uri);
    } while (!file.exists());
    return file.getParent();
}

URI uri = clazz.getProtectionDomain().getCodeSource().getLocation().toURI();
System.out.println(getParentRealPath(uri));
Anton Shchyrov
  • 285
  • 3
  • 15