I recently learned how to register custom grails artifacts (I need it for dynamic controllers in my application) using grailsApplication.addArtefact(java.lang.String artefactType, GrailsClass artefactGrailsClass) and it works fine, but now I realized that I also want to be able to unregister them.
Unfortunately, interface GrailsApplication provides no clear way to do so and it seems that unregistering unwanted dynamically registered grails artifacts can only be done by restarting the whole application.
Maybe I'm missing something and an artifact can be removed from an application without having to restart the app?
Thank you
You can always rebuild the GrailsApplication. That throws away all artefacts and loads the default ones. That obviously means you'd have to addArtefact the artefacts you want to keep again.
Other option is access the loadedClasses set (which is protected) and make the changes manually and then call populateAllClasses to make available (this method is protected too).
Related
I know I can do it manually but is there any grails create-service counterpart for removing a service?
No, there is not. As others have said, removal is more dangerous than creation. Either use an IDE, or remove the service manually after checking for any usages.
I have a Grails 2.4.4 project configured with the default ':cache:1.1.8' plugin. It also uses the default ":asset-pipeline:1.9.9" plugin.
When running the application, I'm seeing this DEBUG message in the logs:
DEBUG simple.MemoryPageFragmentCachingFilter - No cacheable annotation found for GET:/PROJECTNAME/grails/assets/index.dispatch [controller=assets, action=index]
How do I make this message go away? I don't mean by filtering the log file, I mean by putting a cacheable annotation for the asset pipeline controller, or something like that.
UPDATE: It turns out that I was getting dozens of those DEBUG log messages instead of just one, because of a flaw in sass-asset-pipeline:1.9.0.
I updated to sass-asset-pipeline:1.9.1, because they said they fixed some caching issues in 1.9.1 here:
https://github.com/bertramdev/sass-grails-asset-pipeline/issues/11
You don't want to. Caching responses and method calls should use very different logic from caching static resources.
Typically static resources change rarely and are cached forever, but use a unique name or some other mechanism so if you do change the CSS/JS/etc. file, you can get clients to use the new version.
But caching service method calls and controller responses is typically much more short-lived, since database updates often trigger cache invalidation and flushing to ensure that the correct data is used.
The asset-pipeline plugin and its addon plugins have great support for smart caching and you should manage that there, but not by misusing the cache plugin(s).
I am working with Grails 2.4.2 and Tomcat 7 in Debian server.
Suppose I need to change a label of a field. If I change the label in server's view directory it is not working.
All I have to do is creating war again and deploy. But so far as I know, if any changes made in views no need to create war and deploy again.
In my opinion, the best way to deal with any dynamic content is to externalize it. Save the dynamic content into an external file where you can modify it. Grails' reloadable configuration could be of a great help. See http://www.tothenew.com/blog/externalize-and-reload-grails-configuration-dynamically/ to get an idea how this could be done.
Is there a way to override at runtime the value of a property defined in a message bundle?
My grails application contains a property in the messages.properties file:
page1.para1.text=Some text to display to the user
My Config.groovy defines the following config location:
grails.config.locations = [ "file:${userHome}/.myApp/myApp-config.properties" ]
I currently use this approach to override Config.groovy properties (like db connections, etc), but it doesn't seen to apply to message bundle properties.
I was hoping/expecting to just make sure that the myApp-config.properties file contains my new property value, restart the Tomcat server where my app is deployed and it would get picked up and displayed on my page:
page1.para1.text=Some DIFFERENT text to display to the user
Grails docs on Internalization/Message bundles grails i18n doesn't suggest if this is possible or not.
Obviously, I'm trying to achieve this change without the need to recompile and redeliver my Grails application.
Any ideas?
Thanks in advance.
When you are already live and don't want to create a new .war file:
I'm not sure, but the .war file can be found unzipped on the server. You might try to replace the message files directly on the server, but a restart of the app might be necessary. But I wouldn't advice doing so.
If you need to often change the message bundles at runtime, I guess it would make sense to store them in the database. But that means that you have to change your code a little bit and redeploy it once. There is a blog entry which describes how to do it: http://graemerocher.blogspot.de/2010/04/reading-i18n-messages-from-database.html
Another SO question handles the case that you want to store changes to the messages in a DB but fall back to the files:
Grails i18n From Database but Default Back To File
hth
In theory you should be able to replace the messageSource bean with a ReloadableResourceBundleMessageSource inside Resources.groovy. This way you can not only point it to a new location but also declare how often they should be invalidated as cached values.
I'm wondering where utility code can be placed, that doesn't cause a restart of container. Updating controllers doesn't cause a container restart & the updated code is available to run (great), but I wanted a more general library/utility place for my utility code.
Putting the code in /utils or in src/groovy does cause a restart on save, at least using Intellij, but I imagine this is the same regardless of where Grails is developed.
Perhaps you have some general info/insights on how Grails does this -- includes new code but doesn't need to restart the container, if that's only special to controllers?
(v. 1.3.7)
You're out of luck out of the box unless you want to use 2.0. The alternative is to turn off auto-reloading and add in something like jrebel. See this blog for details.