142

Assume standard maven setup.

Say in your resources folder you have a file abc.

In Java, how can I get absolute path to the file please?

bbenno
  • 377
  • 4
  • 11
James Raitsev
  • 92,517
  • 154
  • 335
  • 470
  • Do you want to write a Maven plugin? Or do you want to access the file when your program executes? – Gyro Gearless Jun 27 '13 at 19:28
  • Related: http://stackoverflow.com/questions/8136891/getting-absolute-path-of-a-file-loaded-via-classpath – Vadzim May 13 '17 at 09:39
  • There are three variants of solution, depending on the situation: https://stackoverflow.com/a/56327069/715269 – Gangnus May 27 '19 at 13:36

6 Answers6

197

The proper way that actually works:

URL resource = YourClass.class.getResource("abc");
Paths.get(resource.toURI()).toFile();

It doesn't matter now where the file in the classpath physically is, it will be found as long as the resource is actually a file and not a JAR entry.

(The seemingly obvious new File(resource.getPath()) doesn't work for all paths! The path is still URL-encoded!)

Karol S
  • 9,028
  • 2
  • 32
  • 45
  • 5
    Or presumably you could just do: `new File(resource.toURI()).getAbsolutePath();` (i.e. I don't think you need the Path object?) – Dan King Mar 12 '14 at 10:56
  • 2
    Good tip about the toURI(), this avoids spaces in your path coming out as %20's! – Matthew Wise Sep 23 '14 at 16:50
  • 38
    Thanks! This almost worked for me. But I had to make one change: YourClass.class.getClassLoader().getResource("abc"); – yngwietiger Sep 18 '15 at 23:01
  • You could alternativly do `new File(YourClass.class.getResource("abc").toURI().getPath())` if you wanted to. – Rylander Oct 09 '17 at 18:58
  • 8
    I don't understand how this have worked for so many people without the starting slash: `.getResource("/abc")` – cahen Feb 27 '19 at 11:09
  • Kotlin: `YourClass::class.java.classLoader.getResource("resource.txt")` – ExactaBox Jan 21 '20 at 03:29
117

You can use ClassLoader.getResource method to get the correct resource.

URL res = getClass().getClassLoader().getResource("abc.txt");
File file = Paths.get(res.toURI()).toFile();
String absolutePath = file.getAbsolutePath();

OR

Although this may not work all the time, a simpler solution -

You can create a File object and use getAbsolutePath method:

File file = new File("resources/abc.txt");
String absolutePath = file.getAbsolutePath();
Rahul Bobhate
  • 4,892
  • 3
  • 25
  • 48
  • 10
    An advice of limited use, as it relies on the working directory to be the maven root. And even then, you should rather use `target/classes/abc.txt` to reference the file, as this is the canonical place where Maven puts resource files after processing (for example, the maven-resources plugin might have done property substitution on abc.txt). It's much better to use the abc.txt via getResource() from the classpath. – Gyro Gearless Jun 27 '13 at 19:44
  • 4
    What if an end-user is running your application as an executable JAR? Then there won't be a physical File at all. This is another reason why you should use getResource(), and e.g. open input stream to it depending on what you want to do with it. – Matthew Wise Sep 23 '14 at 16:49
  • 7
    Can this be removed as the correct answer? @Karol S answered below - that should be the correct answer (hence the upvote discrepancy) – DanGordon Mar 14 '17 at 14:22
  • 3
    Wrong answer. Please refer below answer by @Karol – bhathiya-perera Jan 16 '18 at 05:47
  • Technically it works, I guess. Got the root path correct but it did not point to where my actual resource folder is for the module. – David S Aug 31 '21 at 16:59
38

You need to specifie path started from /

URL resource = YourClass.class.getResource("/abc");
Paths.get(resource.toURI()).toFile();
Hett
  • 3,484
  • 2
  • 34
  • 51
  • In my case it is a .png file, and when I add the above, I get resources as null. Please can you tell what to do for a .png or .pdf file present in the resources folder? – abc123 Feb 18 '22 at 05:51
14

Create the classLoader instance of the class you need, then you can access the files or resources easily. now you access path using getPath() method of that class.

 ClassLoader classLoader = getClass().getClassLoader();
 String path  = classLoader.getResource("chromedriver.exe").getPath();
 System.out.println(path);
Kasun Siyambalapitiya
  • 3,956
  • 8
  • 38
  • 58
Kirit Thakrar
  • 141
  • 1
  • 2
5

There are two problems on our way to the absolute path:

  1. The placement found will be not where the source files lie, but where the class is saved. And the resource folder almost surely will lie somewhere in the source folder of the project.
  2. The same functions for retrieving the resource work differently if the class runs in a plugin or in a package directly in the workspace.

The following code will give us all useful paths:

    URL localPackage = this.getClass().getResource("");
    URL urlLoader = YourClassName.class.getProtectionDomain().getCodeSource().getLocation();
    String localDir = localPackage.getPath();
    String loaderDir = urlLoader.getPath();
    System.out.printf("loaderDir = %s\n localDir = %s\n", loaderDir, localDir);

Here both functions that can be used for localization of the resource folder are researched. As for class, it can be got in either way, statically or dynamically.


If the project is not in the plugin, the code if run in JUnit, will print:

loaderDir = /C:.../ws/source.dir/target/test-classes/
 localDir = /C:.../ws/source.dir/target/test-classes/package/

So, to get to src/rest/resources we should go up and down the file tree. Both methods can be used. Notice, we can't use getResource(resourceFolderName), for that folder is not in the target folder. Nobody puts resources in the created folders, I hope.


If the class is in the package that is in the plugin, the output of the same test will be:

loaderDir = /C:.../ws/plugin/bin/
 localDir = /C:.../ws/plugin/bin/package/

So, again we should go up and down the folder tree.


The most interesting is the case when the package is launched in the plugin. As JUnit plugin test, for our example. The output is:

loaderDir = /C:.../ws/plugin/
 localDir = /package/

Here we can get the absolute path only combining the results of both functions. And it is not enough. Between them we should put the local path of the place where the classes packages are, relatively to the plugin folder. Probably, you will have to insert something as src or src/test/resource here.

You can insert the code into yours and see the paths that you have.

Gangnus
  • 24,044
  • 16
  • 90
  • 149
2

To return a file or filepath

URL resource = YourClass.class.getResource("abc");
File file = Paths.get(resource.toURI()).toFile(); // return a file
String filepath = Paths.get(resource.toURI()).toFile().getAbsolutePath();  // return file path
Emmanuel Osimosu
  • 5,625
  • 2
  • 38
  • 39