5

I'm struggling to resolve a problem which seems very strange to me. I've looked trough at least five similar topics here on StackOverflow and neither of them provided an answer. But to the problem itself: I want to read in a file on app's startup. When I run the app in the IDE (IntelliJ Idea) everything is OK. Although when I build it with Gradle Java throws FileNotFoundException:

java.io.FileNotFoundException: file:/home/user/IdeaProjects/time-keeper/build/libs/time-keeper-0.7-beta.jar!/data.csv (No such file or directory)

The path to the file is correct, the file exists, the jar has proper permissions. The declaration:

File dataFile = new File(ClassLoader.getSystemResource("data.csv").getFile());
Handle<TimeTask> dataHandle = new FileHandle(dataFile);
cнŝdk
  • 31,391
  • 7
  • 56
  • 78
ttarczynski
  • 949
  • 1
  • 10
  • 19

1 Answers1

12

As long as data.csv is a file itself, everything works. This is probably true as long as you run the application from within your IDE. In that case,

ClassLoader.getSystemResource("data.csv").getFile()

returns the path of a file on your file system. However, once gradle generates a JAR which contains the file data.csv, the above call produces

/home/user/IdeaProjects/time-keeper/build/libs/time-keeper-0.7-beta.jar!/data.csv

While this is technically the correct path (data.csv within the JAR), it is no longer a valid file system path. The java.io.File utilities cannot handle arbitrary URLs or files within archives. data.csv simply is no File, but an entry within an archive.

If you want to read the "file", you can use getSystemResourceAsStream which opens a resource (no matter whether it is a "real" file or not) as an InputStream.

Tobias
  • 7,723
  • 1
  • 27
  • 44