Access grailsApplication or Service in groovy class - grails

I am trying to access grailsApplication in groovy class under src/groovy but I get a null pointer exception. I also tried to inject a service into the same class and same result. How can I access grailsApplication or a service from groovy class? (I am using Grails 1.3.7)

The ApplicationHolder class is deprecated in newer Grails versions (2.0 and above).
There is another way, which is described in one of Burt's blogposts: http://burtbeckwith.com/blog/?p=1017

After Grails 2.0, you should use:
def grailsApplication = Holders.grailsApplication

Dependency injection does not work for groovy classes under src/groovy. You can get the access to grailsApplication using ApplicationHolder like this:
import org.codehaus.groovy.grails.commons.ApplicationHolder
def grailsApplication = ApplicationHolder.application
You can access all services like this:
def allServicesArtefacts = grailsApplication.services

If you have classes that you want to participate with dependency injection from src/groovy or src/java or even 3rd party jars all you have to do is configure them in grails-app/conf/spring/resources.groovy.
If you had the class mypackage.MyClass in your src/groovy directory that looked like this:
package mypackage
class MyClass{
def grailsApplication
def myMethod(){
//uses grailsApplication
}
}
Then by adding the following to grails-app/conf/spring/resoruces.groovy it would get auto-injected:
myClass(mypackage.MyClass){bean->
bean.autowire = "byName"
}
This will work in any version of grails thusfar, and like I said you can even use 3rd party jars - for example I ALWAYS have the following in my resources.groovy:
jdbcTemplate(org.springframework.jdbc.core.JdbcTemplate){
dataSource = ref('dataSource')
}
For more comprehensive Spring/Grails documentation see:
http://grails.github.io/grails-doc/latest/guide/spring.html

Related

Upgrading to Guice 4 in Play app now seeing "No implementation for CLASSNAME was bound."

I'm upgrading a project from Play 2.3.x -> 2.4.x and consequently, having to update a jar dependency from Guice 3.x to 4.x.
I'm injecting the services in the controller like this with Guice:
import javax.inject._
#Singleton
class HomeController #Inject()(service: MyService) extends Controller
The configure() method for guice bindings in my jar looks like this (just a sample provided here):
bind(classOf[MyService]).in(classOf[Singleton])
bind(classOf[OtherService]).in(classOf[Singleton])
Just want to reiterate that those bindings are defined in a separate jar that is a dependency of my play project. Injection works fine using a service that is already defined in guice bindings (MyService or OtherService)
import com.google.inject.Inject
class MyService #Inject()(otherService: OtherService)
But will fail if I add any other dependency that is manually constructed using the AbstractModule interface like this:
def configure() {
val config = getConfig
bind(classOf[Config]).toInstance(config)
}
And injected into MyService like so:
class MyService #Inject()(otherService: OtherService, config: Config) with InitializingBean
during dependency injection at runtime I get the following error:
No implementation for Config was bound.
Any idea why Guice 3.0 -> 4.0 upgrade would cause this? Or any ideas I can explore as next step? Thanks for the help.
First you import the class
import models.userClass
Then inject your classes/traits at the Class declaration line, and not in the body of the class:
class MyClass #Inject()(val config: Configuration, var userClass: UserClass){...}
If it is the controller class you should extend it with InjectedController.

Grails: plugin injecting service into src groovy within a plugin

Apologies, since there are lots of links out there and I have tried a few examples including stuff that already works within my project(s) that are non plugin:
What I have tried:
Within my Plugin descriptor:
def doWithSpring = {
someService(SomeService)
}
Then within my end src/groovy
//def someService = Holders.grailsApplication.mainContext.getBean 'someService'
def someService
None of above works...
If I instantiate the service everything appears to work fine, I would prefer to inject it and its just taking a lot of time doing something rather basic :(
SomeService someService=new SomeService()
Any help would be appreciated
Not that I have ever seen it before (within a plugin) should I include conf/spring/resources.groovy and initialise bean in there ?
In this case, like most cases, there's a way to access what you want without using holders. The Groovy class implements ServletContextListener, so there's a contextInitialized method with a ServletContextEvent event containing the ServletContext. So it wasn't necessary to use the ServletContextHolder to get the ServletContext - it was right there. You can see from the FAQ that the Spring ApplicationContext is stored in the ServletContext as an attribute. Once you have that, you can access whatever Spring beans you want; in this case the jenkinsService and the grailsApplication beans (you can get the config directly from the grailsApplication without using Holders for that.
I made these changes and did a bunch of cleanup, and sent a pull request.
You can inject your service in a src/groovy class like so:
import com.example.SomeService
import grails.util.Holders
class SrcGroovy {
SomeService someService = Holders.applicationContext.getBean("someService")
// ...
}

Accessing 'grailsApplication' from a plugin

How do I access "grailsApplication" of the main application from a plugin?
An example situation:
I have a class in a plugin, which needs to get a resource link from the main application, which is usually retrieved via "grailsApplication". How do I do that?
SOLUTION
In the plugin class you may simply specify:
import grails.util.Holders
Holders.getGrailsApplication()
In services, you should be able to add
def grailsApplication
and it will be injected into your service.
If your class is a spring bean, then you should be able to inject it inside the
def doWithSpring = { ->
myBean( org.whatever.BeanClass ) {
grailsApplication = ref( 'grailsApplication' )
}
}
block of the plugin main groovy file.
If it's neither of these, have you tried using the Holders class?
def grailsApplication = grails.util.Holders.getGrailsApplication()

issue with injecting grails service in domain class

I am trying to inject 'GraauditService' into grails 'User' domain class.
I am using grails 1.3.7
I have tried direct injection method as I do in controllers
import com.gra.audit.GraauditService
class User {
def graauditService // or even GraauditService graauditService with graauditService as transient
.......
the above does not work. graauditService is always coming up as null
I also tried to inject through ApplicationHolder as shown here
But looks like ApplicationHolder is deprecated now
How can I use the service in the domain class?
The following works for me
class User {
def springSecurityService
static transients = ['springSecurityService']
}
Try injecting it using the transient keyword:
class User {
transient graauditService
}
For Grails 1.3.7, the solution is to inject it through the ApplicationHolder, as shown here by Burt Beckwith.
The above solutions may work for Grails 2.0, but not for 1.3.7 or earlier.

How do I determine if a class is a Grails domain object?

For an arbitrary object what is the easiest way to determine if the type of the object is a Grails domain class?
You can use the GrailsApplication for that. Add a dependency injection to your controller or service:
def grailsApplication
and then you can use it like this:
def foo = ...
if (grailsApplication.isDomainClass(foo.getClass()) {
...
}
Found the following snippet at https://svn.intuitive-collaboration.com/RiskAnalytics/trunk/riskanalytics-grails/src/java/org/codehaus/groovy/grails/web/binding/GrailsDataBinder.java
DomainClassArtefactHandler.isDomainClass(clazz)
The javadoc is here: http://grails.org/doc/latest/api/org/codehaus/groovy/grails/commons/DomainClassArtefactHandler.html#isDomainClass(java.lang.Class)

Resources