1

I have a maven project with these standard directory structures:

src/main/java

src/main/java/pdf/Pdf.java

src/test/resources

src/test/resources/files/x.pdf

In my Pdf.java,

File file = new File("../../../test/resources/files/x.pdf");

Why does it report "No such file or dirctory"? The relative path should work. Right?

user697911
  • 10,043
  • 25
  • 95
  • 169

3 Answers3

0

Relative paths work relative to the current working directory. Maven does not set it, so it is inherited from whatever value it had in the Java process your code is executing in.

The only reliable way is to figure it out in your own code. Depending on how you do things, there are several ways to do so. See How to get the real path of Java application at runtime? for suggestions. You are most likely looking at this.getClass().getProtectionDomain().getCodeSource().getLocation() and then you know where the class file is and can navigate relative to that.

Community
  • 1
  • 1
Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
0

Why does it report "No such file or dirctory"? The relative path should work. Right?

wrong.

Your classes are compiled to $PROJECT_ROOT/target/classes and your resources are copied to the same folder keeping their relative paths below src/main/resources.

The file will be located relative to the classpath of which the root is $PROJECT_ROOT/target/classes. Therefore you have to write in your Pdf.java:

File file = new File("/files/x.pdf");

Your relative path will be evaluated from the projects current working directory which is $PROJECT_ROOT (AFAIR).

But it does not matter because you want that to work in your final application and not only in your build environment. Therefore you should access the file with getClass().getResource("/path/to/file/within/classpath") which searches the file in the class path of which the root is $PROJECT_ROOT/target/classes.

Timothy Truckle
  • 15,071
  • 2
  • 27
  • 51
0

No the way you are referencing the files is according to your file system. Java knows about the classpath not the file system if you want to reference something like that you have to use the fully qualified name of the file. Also I do not know if File constructor works with the classpath since it's an abstraction to manage the file system it will depend where the application is run from. Say it is run from the target directory at the same level as source in that case you have to go one directory up and then on src then test the resources the files and finally in x.pdf.

Since you are using a resources folder I think you want the file to be on the classpath and then you can load a resource with:

InputStream in = this.getClass().getClassLoader()
                            .getResourceAsStream("<path in classpath>");

Then you can create a FileInputStream or something to wrap around the file. Otherwise use the fully qualiefied name and put it somewere like /home/{user}/files/x.pdf.

Nord
  • 253
  • 2
  • 6