DevEx
DevEx

Reputation: 4561

scala issue with reading file from resources directory

I wrote something like this to read file from resource directory:

val filePath = MyClass.getClass.getResource("/myFile.csv")
val file = filePath.getFile
println(file)
CSVReader.open(file)

and the result I got was something like this:

file:/path/to/project/my_module/src/main/resources/my_module-assembly-0.1.jar!/myFile.csv

Exception in thread "main" java.io.FileNotFoundException: file:/path/to/project/my_module/src/main/resources/my_module-assembly-0.1.jar!/myFile.csv (No such file or directory)

Whereas, if I run the same code in IDE(Intellij), no issues and the path printed to console is:

/path/to/project/my_module/target/scala-2.11/classes/myFile.csv

FYI, its a multi build project with a couple of modules and I build the jars using sbt assembly

Upvotes: 4

Views: 3819

Answers (1)

Alonso Dominguez
Alonso Dominguez

Reputation: 7858

This is more related to Java or the JVM itself than to Scala or SBT.

There is a difference when running your application from the IDE vs the command line (or outside the IDE). The method getClass.getResource(...) attempts to find the resource URL in the current classpath, and that's the key difference.

If you look at the URL itself, you will find that in the first case you have a my_module-assembly-0.1.jar! bit in it, meaning that URL is actually pointing towards the contents of the JAR, not to a file accessible from the file system.

From inside your IDE your class path will include the actual files on disk, from the source folders, because the IDE assumes that there is not any JAR file itself. So when obtaining the URL given by getClass.getResource(...) you have an URL that does not have the my_module-assembly-0.1.jar! bit in it.


Since you want to read the contents of the file, you may want to do a getClass.getResourceAsStream(...). That will give you an InputStream that you can use to read the contents regardless you are in the IDE or anywhere else.

Your CSVReader class may have a method that allows it read the data from an InputStream or a Reader or something similar.

EDIT: As pointed out by Luis Miguel Mejia Suarez, a more Scala idiomatic way of reading files from your class path is using the Source.fromResource method. This will return a BufferedSource that then can be used to read the file contents.

Upvotes: 8

Related Questions