Grails plugin dependency injection failing in domain class and controller - grails

| Grails Version: 3.0.7
| Groovy Version: 2.4.4
| JVM Version: 1.8.0_51
I am trying to install a grails plugin : Slug Generator 0.5 (https://grails.org/plugin/slug-generator)
However, the service dependency injection is not working correctly in either domain classes or services and is always a null reference.
This is not the first time I have experienced plugins not successfully injecting services : Grails Geocode plugin dependency injection issue
Basically, it seems I'm at a point where I cannot use some plugins within my application as I cannot count on service dependency injection working.
If anybody could offer some insight, i'd be most appreciative.
I'm following the following example code :
class Dummy {
def slugGeneratorService
String name
String slug = ""
def beforeInsert() {
this.slug = slugGeneratorService.generateSlug(this.class, "slug", name)
}
def beforeUpdate() {
if (isDirty('name')) {
this.slug = slugGeneratorService.generateSlug(this.class, "slug", name)
}
}
}
Here is an example error log :
Caused by: java.lang.NullPointerException: Cannot invoke method generateSlug() on null object
One thing I've noticed is that at the command line, the following returns nothing :
$ grails list-plugins | grep slug
However, If I search for another plugin, I do get a result :
$ grails list-plugins | grep joda
joda-time
I can clearly see (via IntelliJ) that the slug generator plugin is in the classpath and I can actually access all the source via the External libraries.
Maybe that's a hint to the problem?

OK, this seems to be down to me stupidly trying to use a grails 2.x plugin in a grails 3.x plugin.
There are various steps to go through to upgrade a plugin from 2.x to 3.x all detailed within the grails documentation.
My immediate solution was to simply create a new service and copy the code from the plugin into my application. Worked just fine.
Grails 3.x plugins : https://bintray.com/grails/plugins
Grails 2.x plugins : https://grails.org/plugins/
It's not obvious unless you navigate via the grails site. If you come in for example from Google directly to a plugin page, compatibility is shown as 2.5.x >
However, this actually seems to mean greater than 2.5.x but less than 3.x
Hope this helps should anyone else encounter this.

Related

Grails Geocode plugin dependency injection issue

Grails Version: 3.0.7
Groovy Version: 2.4.4
JVM Version: 1.8.0_51
I must be missing something really simple here.
I've added a grails plugin to my project as defined in the read me :
compile 'org.grails.plugins:geocode:0.3'
I can see the relevant dependencies have been pulled down from the repository.
However, when trying to inject the service within my controller using :
def geocodingService
I receive the following error upon execution :
Caused by: java.lang.NullPointerException: Cannot invoke method getPoint() on null object
The relevant line of code is :
Point location = geocodingService.getPoint('XXX XXX, UK')
My guess is the dependancy injection is failing but can anybody please tell me the mistake I am making?
Note : Copied my answer from another almost identical questions ...
OK, this seems to be down to me stupidly trying to use a grails 2.x plugin in a grails 3.x plugin.
There are various steps to go through to upgrade a plugin from 2.x to 3.x all detailed within the grails documentation.
My immediate solution was to simply create a new service and copy the code from the plugin into my application. Worked just fine.
Grails 3.x plugins : https://bintray.com/grails/plugins
Grails 2.x plugins : https://grails.org/plugins/
It's not obvious unless you navigate via the grails site. If you come in for example from Google directly to a plugin page, compatibility is shown as 2.5.x >
However, this actually seems to mean greater than 2.5.x but less than 3.x
Hope this helps should anyone else encounter this.

Grails service injection null when injected service has older grails version

I have written a Grails Plugin, written in Grails 2.1.1, which offers a service. Now, I have created a new Grails project with Grails 2.4.4 and wanted to inject the service, but this fails.
package testproject
class HomeController {
def myService
def index() {
println myService
}
}
Always nullis printed. I tested this with a Grails 2.4.4 project and with a Grail2 2.4.3 project. When I create instead my Grails Project with Grails 2.1.1 it works.
Why? Shouldn't be a service reachable for newer versions? Do I always have to upgrade the plugin, which contains the service, to be able to use newer Grails versions?
I had this problem as well, and it didn't hit me until 2.4.4. I have a custom security plugin that depends on the Spring Security Plugin. In my plugin, I'm setting a custom user details service in doWithSpring. This definition looks like this:
userDetailsService(UserService) {
grailsApplication = ref('grailsApplication')
errorService = ref('errorService')
}
I had references to userService in my application and in my plugin. These references stopped being injected in Grails 2.4.4. I was able to fix it by replacing these references with userDetailsService. I don't like this though, because the reference looks like it points to the Spring Security version of this service, and I'm invoking methods that only exist in my UserService class.
Anyways, I'm not sure if it's a bug or bug fix in 2.4.4, but check and make sure that your plugin and/or resources.groovy files aren't redefining your MyService class as something else.

Grails JMS Plugin - Unable to resolve classes

I'm pretty new to grails so it's possible that i've missed something obvious, but I am trying to utilise the JMS plugin. I've included the following within the plugins section of my BuildConfig.groovy
compile ":jms:1.2"
However when I compile the app I get lots of "unable to resolve class" exceptions for imports within the jms plugin (40 in total, javax.jms.* and org.springframework.jms.* mostly).
e.g.
| Error Compilation error: startup failed:
C:\dev\prj\grails\tApp\target\work\plugins\jms-1.2\grails-app\utils\DefaultJmsBe
ans.groovy: 16: unable to resolve class org.springframework.jms.listener.Default
MessageListenerContainer
# line 16, column 1.
import org.springframework.jms.listener.DefaultMessageListenerContainer
^
C:\dev\prj\grails\tApp\target\work\plugins\jms-1.2\grails-app\services\grails\pl
ugin\jms\JmsService.groovy: 22: unable to resolve class javax.jms.Message
# line 22, column 1.
import javax.jms.Message
Is anyone able to point me in the right direction? The issue can be reproduced just by adding the plugin to the BuildConfig.groovy as mentioned above to a new grails project .
Grails version 2.3.3
Many thanks
Tom
While doing a Grails 2.2 -> 2.3.4 upgrade I ran into a similar issue and was able to get things working by manually adding spring-jms to my dependencies in BuildConfig.groovy:
compile 'org.springframework:spring-jms:3.2.5.RELEASE'
It's odd that this would stop working now of course, since the jms plugin hasn't changed in a very long time. My guess is that it depends on the spring-jms lib, but didn't have it listed as a dependency, instead relying on grails to bring it in. According to the 2.3.x upgrade guide, there have been changes to what grails brings in now, so perhaps spring-jms stopped getting a free ride.
The Grails MX website has a write-up that might help; it's built using 2.3.4:
http://grails.org.mx/2013/12/20/quickstart-jms-en-grails/
It was pretty helpful to me in getting a sample application up and running. It's in Spanish though, so may need to have Google translate it for you...
Have you tried executing the command grails refresh-dependencies before running grails run-app?
I wrote a blog post on installing a Grails plugin if you need more details.

Grails 2.1.1 - Logback integration

I'm developing with Grails 2.1.1 and now I want to integrate Logback (http://logback.qos.ch) as the default logging framework as it should provide some better logging features and could be also configured via Groovy.
As Logback 1.0.7 (latest) does only work with slf4j 1.6.6 I want to upgrade the Grails dependeny. Grails 2.1.1 is using slf4j 1.6.2. How to do this properly?
I tried the following: in BuildConfig.groovy I exclude grails-plugin-log4j and slf4j-api
grails.project.dependency.resolution = {
// inherit Grails' default dependencies
inherits("global") {
excludes "grails-plugin-log4j", "slf4j-api"
}
...
}
and I try to load slf4j-api 1.6.6 in compile build and runtime along with the other necessary libraries
grails.project.dependency.resolution = {
...
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
compile "org.slf4j:slf4j-api:1.6.6"
build "org.slf4j:slf4j-api:1.6.6",
"ch.qos.logback:logback-core:1.0.7",
"ch.qos.logback:logback-classic:1.0.7"
runtime "org.slf4j:slf4j-api:1.6.6",
"org.slf4j:log4j-over-slf4j:1.6.6", // logback dependency for classic module, as seen on http://logback.qos.ch/dependencies.html
"ch.qos.logback:logback-core:1.0.7",
"ch.qos.logback:logback-classic:1.0.7"
}
...
}
now, if I want to do anything from the Grails commandline, either grails compile or grails clean, it's complaining that it couldn't execute the script because it couldn't find the LoggerFactory class:
| Loading Grails 2.1.1
| Configuring classpath
| Error Error executing script Compile: org/slf4j/LoggerFactory (NOTE: Stack trace has been filtered. Use --verbose to see entire trace.)
java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:156)
at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:132)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:272)
at org.springframework.core.io.support.PathMatchingResourcePatternResolver.<clinit>(PathMatchingResourcePatternResolver.java:169)
| Error Error executing script Compile: org/slf4j/LoggerFactory
How can I upgrade the underlying slf4j-api properly?
If I don't exclude the slf4j-api first, I get a conflict with the "old" 1.6.2 api marked as evicted when calling grails dependency-report...
Also, I'd love to have an external config file for Logback. How would I implement it? With Log4j I just declared a log4jConfigurer bean within the conf/spring/resources.groovy file - how would it be done with Logback?
Has anybody experience in logging Grails 2.1.1 with Logback and could give me any advice for this issue?
As I think that this question would be also a matter of fact for other developers willing to implement the Logback Logging Framework with Grails, I'll share my progress on the topic within this answer - trying not to overload the initial question with progress information.
I still had no luck in updating slf4j within Grails, so I stuck
with the solution to simply overload the slf4j-api dependency.
Grails would show no error on grails dependency-report, just an
"eviction notice" on the older slf4j dependency (1.6.2). This seems
to work but I'll keep on searching for a better solution on this
topic.
I'm now able to load an external config file for Logback through
a ServletContextListener and a ConfigLoader class
implemented in grails-app/src/java, with the
ServletContextListener registered within the web.xml file. (to
get the web.xml simply execute grails install-templates on the
commandline. You'll find it under
grails-app/src/templates/war/web.xml) Be sure to make it the first
<listener/> entry within your web.xml so that Logback gets
configured and loaded as soon as possible.
I found this solution along with the full code sample over at
https://bowerstudios.com/node/896 which was the best and shortest
example I found on this topic which seems to work!
This solution just loaded the external configuration file and used
it within the ConfigLoader class but didn't set it for the whole
Grails application. So I googled around a bit more and I found a
solution from Logback, available at GitHub (https://github.com/qos-ch/logback-extensions) and integrating with the
Spring Framework, so I took these classes from this page and
the LogbackConfigurer class from here and tweaked them to fit
my needs.
Now everything works like a charm and I'am able to create an external configuration file and - what I like best - it's hooking in
with the log object which is injected to e.g. Controller classes
by default.
Hope this is also a help for other developers too ;)
If you've got a better or more "groovy" solution for this, pleas let me know!

Issue Deploying a Grails 2.1.1 app to JBoss because of Xerces

I have a Grails app that uses the Rest plugin
When I drop my war into my JBoss deploy directory and start it up, the deployment of the app fails because of the following error:
2012-11-01 15:48:33,931 ERROR [org.jboss.web.tomcat.service.deployers.JBossContextConfig] XML error parsing: context.xml
org.jboss.xb.binding.JBossXBRuntimeException: Failed to create a new SAX parser
I believe this refers to the grails app containing a version on xercesImpl as well as JBoss having it's own. We usually rectify this by removing xercesImpl from our apps or setting them to "provided" scope.
I'm trying to figure out how I fix this deploy issue. I'm assuming I have to edit the BuildConfig.groovy script and tell it, somehow, to exclude xerces right? How would I do that for this plugin? If this were a "dependency" that appears to be easy to specify the exclusions. But I'm not sure how to do it for this plugin...
any ideas?
In your BuildConfig.groovy add this:
inherits('global') {
excludes 'serializer'
}
It turns out, doing the following in the plugin section of my BuildConfig.groovy did the trick after all...
compile(":rest:0.7"){
excludes "xercesImpl"
}

Resources