javamavenjava-8filenotfoundexceptionnosuchfileexception

Not able to load file from Maven resources with Paths.get()


I apologize for this seemingly easy and almost a stupid question, but I have spent a lot of time to fix it without much success.

I created a very simple maven project and then a simple text file inside the src/resources folder like this.

enter image description here

enter image description here

pom.xml is simple. The App class looks like this:

public class App {
    public static void main(String[] args) throws IOException {
        Files.lines(Paths.get("test.txt")).forEach(System.out::println);
    }
}

And the exception that I get:

Exception in thread "main" java.nio.file.NoSuchFileException: test.txt
    at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79)
    at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
    at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
    at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230)
    at java.nio.file.Files.newByteChannel(Files.java:361)
    at java.nio.file.Files.newByteChannel(Files.java:407)
    at java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:384)
    at java.nio.file.Files.newInputStream(Files.java:152)
    at java.nio.file.Files.newBufferedReader(Files.java:2784)
    at java.nio.file.Files.lines(Files.java:3744)
    at java.nio.file.Files.lines(Files.java:3785)
    at com.rahul.App.main(App.java:12)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Process finished with exit code 1

This seems to be a very stupid problem but I just can't get my head around it. Any help is sincerely appreciated.


Solution

  • You are using Maven and the text file that you want to load is correctly placed to be in the classpath : src/main/resources. The problem is that Paths.get("test.txt") doesn't search the file in the classpath but in the filesystem.

    So what you need is getting the resource from the classpath as a URI and to pass it to Paths.get(URI):

    Path textFile = Paths.get(App.class.getResource("/test.txt").toURI());
    Files.lines(textFile).forEach(System.out::println);
    

    Note that the way to get the Path is really convoluted.
    Unfortunately the Class class was not updated to take advantage of the java nio API that was introduced in Java 7.
    It would be really simpler if we could write something like :

    Files.lines(App.class.getResourcePath("/test.txt"))
         .forEach(System.out::println);