Unable to read file from resources nested directory - scala

I am currently including a submodule to my project (a scala project, using Maven for dependency management):
[submodule "src/main/resources/secrets"]
path = src/main/resources/secrets
url = <my repository url>.git
Having this submodule, my resources path (src/main/resources) looks like:
src/main/resources/secrets/anotherdirectory/secret.conf
If I try in my local to read the file using com.typesafe.config.ConfigFactory, it works well:
ConfigFactory.load("secret").getConfig("config")
However, when I run the application (using the .jar), I am unable to do the same, having the following error (and the file is the same):
com.typesafe.config.ConfigException$Missing: no configuration setting found for key
I've also tried to read as a file, which also works in my local, but gives me a null when .jar:
getClass.getClassLoader.getResource("secrets/cloud/anotherdirectory/secret.conf").getFile
Anyone had any similar issue?
Thank you.

Related

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
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.

Resolving NED Path issue Veins/Omnet++

I am working with veins. I needed to change the default behavior of BaseWaveApplLayer. Rather doing in file changes, I created a second application file with the name MyApp. I added MyApp.cc, MyApp.h, MyApp.ned files. Then I duplicated TraCIDemoRSU11p, and added files for TraCIDemoRSU11pEnhanced. Now in .ini file when I changed *.rsu[*].applType to point to "TraCIDemoRSU11pEnhanced". It compiles fine, but when I try to run it, generates the following error:
Submodule appl: no module type named `TraCIDemo11pEnhanced' found that implements module interface org.car2x.veins.base.modules.IBaseApplLayer (not in the loaded NED files?).
In MyApp.ned file it is declared to be of type IBaseApplLayer. I tried setting ned-path parameter in ini file, didn't resolve the problem. In veins project properties, NED source folder is checked. Do I have to add the ned path for the newly created application file, somewhere?
Try using the cookiecutter package (https://veins.car2x.org/tutorial/#newprojects) to create new applications that use veins instead of copying and pasting files:
Use pip to install the package (https://github.com/cookiecutter/cookiecutter)
Then follow the steps in (https://github.com/veins/cookiecutter-veins-project/blob/master/README.md) to create the new project; following the prompts that appear.
This will create a new project that uses Veins and has the application layer-related files for you to update according to your application with no errors.

sbt run - how to specify working directory? [duplicate]

I would like to be able to run the java program in a specific directory. I think, that it is quite convenient to parametrize working directory, because it allows to easily manage configurations.
For example in one folder you could have configuration for test, in other you could have resources needed for production. You probably think, that there is option to manipulate classpath for including/exluding resources but such solution works only if you are interested in resources stored in classpath and referencing them using Classloader.getResource(r). But what if you have some external configuration and you want to access it using simple instructions like File file = new File("app.properties");?
Let's see ordinary example.
Your application uses app.properties file, where you store credentials for external service. Application looks for this file in working directory, because you uses mentioned File file = new File("app.properties"); instruction to access it. In your tests you want to use app.properties specific to your tests. In you integration tests you want to use app.properties specific to another environment. And finally when you build and release application you want to provide other app.properties file. All these resources you want to access always in the same way just by typing File file = new File("app.properties"); instead of (pseudo code):
if(configTest)
file = File("testWorkDir/app.properties");
else if(config2)
file = File("config2WorkDir/app.properties");
else
file = File("app.properties");
or instead of using resources in classpath
this.getClass.getClassLoader.getResource("app.properties");
Of course you are clever programmer and you use build tool such maven, gradle or sbt :)
Enought at the outset. At least The Question:
Is there a way to set working directory in java and if yes how to configure it in build tools (especially in sbt)?
Additional info:
changing 'user.dir' system property is not working (I've tried to change it programaticly).
In sbt changing 'working directory' via baseDirectory setting for test changes baseDirectory which is not base dir in my understangind and it is not equal new java.io.File(".").getAbsolutePath.
Providing environment variable like YOUR_APP_HOME and referencing resources from this path is feasible but require to remember about this in your code.
In sbt changing 'working directory' via baseDirectory setting for test changes baseDirectory which is not base dir in my understangind and it is not equal new java.io.File(".").getAbsolutePath.
I'm not sure what the above statement means, but with sbt you need to fork to change your working directory during the run or test. This is documented in Enable forking and Change working directory.
If you fork, you can control everything, including the working directory.
http://www.scala-sbt.org/0.13.5/docs/Detailed-Topics/Forking.html
Example code:
fork in run := true
baseDirectory in run := file("/path/to/working/directory/")

playframework2 jquery error (jquery.min.map)

When I launch my minimal play2 application I can see an exception in the js console like:
GET http://localhost:9000/assets/javascripts/jquery.min.map 404 (Not Found)
Why it happens? Is it known issue. I've seen some play-tool-projects on github that has this file there. By default I do not have this file in my "javascripts" folder. Should I?
The source map file maps the minified version of the code against the un-minified version so that you can access the real code while debugging.
The 404 error only appears when using the developer tools. To fix this, just download the correct version of your source map file. Mine for example was:
jquery-1.9.0.min.map
Then rename it to:
jquery.min.map
and move it in the javascripts directory.
Try to map of the Assets controller in your conf/routes file.
GET /assets/javascripts/jquery.min.map
For more information read this documentation
Working with public assets

How to access test resources in Play 2.1?

I'm trying to access a .jpg file that is inside my src folders with this line of code:
getClass().getResource("/teste.jpg")
That leads to NullPointerException.
I tried to put the file in the app/ root directory. I also tried to put it in test/ directory and also test/resources as well.
When I run the test from Eclipse it works fine, but it does not from command line using play test.
How to solve this?
I believe that you can achieve it by using
Play.application().getFile("file-relative-to-root")
It is dependent on the running application but for the unit test you can create your own application. Take a look into API docs.
http://www.playframework.com/documentation/api/2.1.0/scala/index.html#play.api.Application
Place the file under public or app/assets as described in Anatomy of a Play application. You can also have the test resources under test/resources.
[root]> help resourceDirectory
Default unmanaged resource directory, used for user-defined resources.
[root]> show test:resourceDirectory
[info] root/test:resourceDirectory
[info] /Users/jacek/dev/sandbox/play-new-app/test/resources
With the resource file(s) in one of the directories, you can get at them as follows:
io.Source.fromInputStream(getClass.getResourceAsStream("/teste.jpg"))