custom codec not found in plugin - grails

I have a grails application with multiple internally developed plugins. Since upgrading from 4.x to 5.2.3, codecs are not found in one plugin, but are found in others. Specifically, I can place the same file (UsernameListCodec.groovy, package name changed from one plugin to the next but otherwise no changes) in grails-app/utils in one plugin and it works; when placed in grails-app/utils in another plugin it fails with MissingMethodException.
What could cause this? The plugins are fairly different in terms of what they provide, but very similar in terms of how they're built, published, etc. Clearly this is something I'm doing wrong (since the codec works in another plugin) but I don't even know where to begin looking. Does a plugin need to do something in particular to be able to provide custom codecs as of grails 5?

Related

grails 3 project plugin source code?

In grails 2 and earlier, plugins installed their source to .grails/<version>/projects/<projectName>/plugins/etc, this made it easy to debug plugins that were installed without having to check out and load the full source... find where problems were that could be hot-deployed. No need to install run the plugin locally.
In grails 3, this seems to be missing... or maybe I'm just missing something? Is there somewhere in my project I can directly modify the plugin source without checking out the plugin, compiling it and then installing it locally?
Yes, you're missing something rather important :)
Grails 2 plugins are distributed as ZIP files including source code, but Grails 3+ plugins are distributed as JAR files with the code compiled into classes. This has multiple benefits over the earlier approach, the biggest one being that you can no longer edit the source directly (which is the worst way to make changes to how a plugin works).
What you should do instead (in all versions of Grails) is to take advantage of the compilation/load/resolution order between the app and the installed plugins - plugins load first, then the app. This allows you to override nearly anything in a plugin just by creating a file (Groovy/Java/GSP/etc.) with the same name and same relative location in your app code, and it will automagically override the plugin's file or class. E.g. to override a plugin's com.foo.BarController controller, create grails-app/controllers/com/foo/BarController.groovy in your app (manually or by copying the original source and modifying it).

Check active grails plugins

Is there a way to check which Grails plugins are active and used durring application runtime?
I want to remove a plugin but I want to be absolutely sure that it is not used anymore...
Well, a brute force way would be to copy your Grails project (preferably using a source control tool like git's branching feature), remove the plugin, and make sure that:
No exceptions on a grails clean, grails compile, and grails refresh-dependencies.
All unit and integration tests pass (your team is writing those, right? ;) )
You can run the application and use it fairly normally; warning, this is the worst test, and by itself isn't sufficient, as you could end up with a BOMM.
If you're familiar with the classes in the plugin, but there are way too many Grails files to look through manually, you could use code search tools like those found in GGTS whatever IDE/text editor you're using. Even grep could be handy for finding references to those classes or some distinctly named methods.
Conversely, if the plugin is basically a black box, and your Grails app is small enough to get around, check the import statements at the top of your Controllers, Domains, and Services. If the plugin provides more client-side technology (like the jQuery plugin) check your GSPs and various items in the web-app directory (like Javascript files) for references to it.

Exclude dependencies from a local Grails plugin

I'm not seeing anything resembling an answer to this on the googlytubes so here goes...
We make use of several local plugins in our grails project. One of our plugins recently has a dependency on SLF4J. Our main webapp (that uses the plugin) also has a dependency on SLF4J. This results in the entirely harmless but nevertheless irritating warning at runtime:
Error SLF4J: Class path contains multiple SLF4J bindings.
Typically I'd just define an "excludes" on the plugins SLF4J dependency, but since this is a local plugin I don't see any way to do so. I tried...
grails.plugin.location.'localpluginname' = '../localplugindir'
grails.project.dependency.resolution = {
plugins {
runtime("com.ourcompany:localpluginname:1.0") {
excludes('slf4j-api')
}
}
}
...but then it tries to actually resolve said plugin on the remote repositories, and fails. We also don't want to exclude the dependency directly in the plugin because the plugin may be used in other projects which do not provide the dependency already.
Before anyone suggests we deploy our local plugin to a local maven repo in order to do this, let me get it out of the way that we don't want to do that. We have them local for a reason...so we can rapidly make changes and see said changes. We'd rather live with the annoying warning messages than add in the increased pain of deploying on every change.
The warning you are getting is not related to having multiple versions of the slf4j-api present in the classpath. SLF4J API is designed to bind with one and only one underlying logging framework at a time. If more than one binding is present on the class path, SLF4J will emit a warning, listing the location of those bindings. You can read more about it in the SLF4J warning or error messages and their meanings document.
The solution proposed by Slf4J is: When multiple bindings are available on the class path, select one and only one binding you wish to use, and remove the other bindings.
In your case the best way would be to exclude the Slf4J binding directly from the plugin. The plugin should not rely on having its own binding but rather assume that the Grails application will provide the binding (which is what it will do)

Command to change package name in Grails

I have created my application under package music. Now I want to change my package to com.mp3.songs.music.
One way is I can manually create the package for grails-app. Is there anything else that I need to take care while changing the package name.
Alternatively, is there a command in grails which can be used to change the package.
I found a way out in the below link. But this works only when you create new files. What if you want to change the package of the older files.
http://www.goto20.nl/tech/groovy/configuring-the-default-package-name-for-a-grails-project/
Thanks!
IntelliJ IDEA has very good support for rename refactoring. I believe it is currently the best (9.0.3 stable) chance you'll have of any major refactoring jobs in Grails. They have a 30 day trial, so it is worth a try.
Why not use Spring Source Tool Suite. Its a great IDE with solid support for Groovy n Grails.

Grails startup is slow

Help! I'm porting a large ruby app to Grails - but the Grails startup of my application takes more than 2 minutes.
I've already set dbCreate to "read" I've ensured my high end dual processor desktop windows box gives Grails needed RAM (1 Gig). I have no plugins installed. I have 170 domain classes that used to be ruby classes.
When it starts up it prints out the line "Running Grails App.." and then hangs for a long time before it then prints out the "Server running" line.
I just did something where I migrated all my ids to bigints. That seems to have worsened the problem. Now it takes about 10 minutes to startup.
I am new to grails would you please give me a few more details on what and where to log the events at startup? As to profiling the vm, its been a few years since I did a lot of Java. What do you recommend as the best profiling tool to use now?
What else can I do to speed up Grails startup?
Unfortunately, I am not sure too much can be done beyond what you already did. As you know, there is a lot going on when it starts up, with all the plugin resolution / loading, adding dynamic methods to your domain objects, and overall dynamic nature of Groovy.
I am not sure which version you are using, but I've asked for ability to turn off dependency checking when you start up in 1.2, since that adds a bunch of time to startup time as well.
I realize above isn't too helpful, so perhaps this will be: I split up my application into several plugins. One for domain objects, one for graphing capability, one for excel import, another for some UI constructs I needed. I didn't do it just because of slow startup times, but the advantage is that I can test parts of the system separately from each other before integrating everything together.
I am about to add a piece of new functionality that involves at least 10 new domain objects, and I am first developing them in a separate plugin by having stubs for the few objects they have to interact with from the core app. That allows me to both reduce startup times, and also have my code better isolated.
So if it's an option for you, try to separate out things so you can work on them separately, which will alleviate your issue somewhat. There may also be other benefits in terms of having your team work on smaller components separately, better modularization, etc.
Hope this is helpful.
170 domain classes is fairly large, but 2 minutes still seems really long to me. Do you have a ton of plugins installed? Potentially too verbose debug settings?
I'd be curious how long it took if you created a fresh grails app, copied in all of your domain objects (and the subset of plugins that the domain objects might need to actually operate) and see how long that takes to start.
Jean's suggestion about separating things out if possible is a good one. I've done something similar on previous projects where we have a domain plugin, and our other apps all rely on that domain plugin.
You could also use the grails events to log some timing information on start up to see where your bottlenecks are. Timing the "PluginInstalled" event should be good as I think that the hibernate plugin would be caught by this in addition to the other plugins.
You may have a dependency problem. If a plugin you use relies on a library in maven that has 'open ended' dependencies, grails will go and look each time if there are newer versions to download in the range. I have no idea why anyone would specify it like this. It seems it would lead to unreliable behaviour. For me, the culprit is Amazon's java aws library, naturally used by a plugin that talks to Amazon's cloud.
http://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk/1.2.10
note how some of its dependencies are like this
org.apache.httpcomponents httpclient [4.1, 5.0)
it appears that every time, grails is looking for a newer version (and downloading if it exists, I just noticed 4.2-alpha1 of httpclient come down when I ran this time).
By removing that dependency from the plugin and manually adding the required libraries to my .lib folder, I reduced my startup time from >30sec to <1sec
You might want to see if there are other knobs you can turn other than Grails in order to fix this.
Have you tried approaching this as a performance issue? You can a look at the box performance and try to find out what the bottleneck is. Is it CPU? Is it a disk read issue? Can you attach a profiler to the VM and find out what's using up most of your startup time?
Have you tried basics like these for further deployment to a servlet container of your choice or in-place .war bootstrapping?
grails -Ddisable.auto.recompile=true run-app
grails run-war
grails war

Resources