I have a Grails 2.1 application in development, and I have a service that is calling Thread.currentThread().contextClassLoader.getResource(fileName) to load a configuration file in grails-app/conf (I’m hoping the location doesn’t matter, though).
It works just fine, except that I have to restart the grails application to load changes to the config file. I’d really like to be able to read the file contents every single time I ask for the resource, at least during development.
Also, I’d like to avoid writing my own caching system if I can avoid it. The simpler the solution, the better.
My problem seems to be similar to this one with velocity but using getClass().getClassLoader().getResource(path).openStream() does not seem to work.
EDIT: I think I may have left out an important detail. The resource that I am retrieving is non-static. I am using the grails template engine to inject values into the resource like so:
Map bindings = [keys: 'values']
new SimpleTemplateEngine().createTemplate(resource).make(bindings).toString()
Using my debugger, I have found that the resource text isn’t changing, but knowing the above may change potential answers.
EDIT #2: I tried using URLConnection.setUseCaches(false) like so with no luck:
URLConnection connection = Thread.currentThread().contextClassLoader.getResource(path).openConnection()
connection.setUseCaches(false)
connection.connect()
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))
String content = reader.readLines().join('\n')
reader.close()
If you’re using a resource in this manner, you might consider moving it out of grails-app/conf and into /web-app.
When running
grails run-app, a cached version of an exploded war is actually running in a container with some outside magic monitoring various paths for changes and re-compiling and re-copying updated files similar to how one might manually hot-swap .class files and other resources.This monitoring happens out of the box for all files in /web-app. Once the files are there, you can use the ServletContext to get a handle to the file in question. For example, you might do something like:
and pass that to your templating engine. For environments that lock down the file system (e.g. Heroku), the
getRealPathmethod will likely not work. You can, alternatively, use something like:The downsides to this approach:
Hope this helps!