Call service from plugin - grails

Can we call service from a plugin? For example I have a plugin, it has its own domain, so now can we call the service of the main application from this domain ?

You can inject it yourself in Bootstrap.groovy, as all is initialized at that time.
Maybe better approach would be to autowire it with something like:
def ctx = grailsApplication.mainContext
ctx.beanFactory.autowireBeanProperties(instance, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false)
Where instance is some object from the plugin.
Another approach is to use Bean PostProcessors http://www.intelligrape.com/blog/tag/bean-post-processing/
Also I really recommend "Programming Grails" book, where you can read about such problems and how to resolve them.

Related

Grails : How do you make services available inside services?

I am currently running into an issue where I am attempting to use a service within a service however the service is null
class ApplicationService{
def someService
def someMethod(){
someService.method()//null on someService
}
}
Is there additional wiring that I need to perform for this to work? Thanks in advance for your help.
I was able to do this by using the grailsApplication and loading the service.
if(!someService){
someService = grailsApplication.classLoader.loadClass("org.company.SomeService").newInstance()
}
The most possible explanation i here is, the class behind SomeService is not a Grails service artefact thus you cannot just inject it like that.
Double check on the source code whether that class is really a service or just a Groovy class in src/groovy. The framework will treat these two differently.
Also do not attempt to inject service with manually creating the instance like your answer, that is not the correct way to do dependency injection in Grails (or in Spring).

Grails 3.X Inject service into Custom Listener

i wonder if someone knows hot to inject a service into a custom listener in Grails 3.X. I'm working with spring secuirty plugin in order to avoid brut force attacks. There is one answer but for Grails 2.0. Thanks in advance.
UPDATE !
Just for those who can use it . I tried Autowired and it works. Something like:
#Autowired
public LoginAttemptService loginAttemptService
The LoginAttemptService is already declared as a Bean
As shown here
Declare it like your injection:
MyService myService
Then when needed
def ctx = Holders.applicationContext
myService= ctx.myService
Alternatively
def myService = Holders.grailsApplication.mainContext.getBean('myService')
The alternate method is particulary useful for src/main/groovy calls if required to a service
Think their both the same thing in different ways

Get a service bean from Grails Holders class

I'm trying to update a plugin to Grails 2.4. Thus I have to replace the deprecated ApplicationContext class by the newer Holders class.
But I'm having some problems getting a service bean from the Holders class.
Running the code below:
import grails.util.Holders;
def myService = Holders.grailsApplication.mainContext.myService
println myService
println myService.getClass()
println myService.serviceMethod()
It prints something like:
grails.plugin.my.MyService#1e5cd54d
Exception thrown
java.lang.NullPointerException
at ConsoleScript2.run(ConsoleScript2:6)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1270)
It throws a NullPointerException when I call both: the "getClass" method and the "serviceMethod" method.
I tryed to see what's happening by debugging from eclipse too and I can observe "myService" variable being set to an object. When I click on it I can see it's String representation just like printed above. But I can't see anything inside the object. This service' class has member variables, but I can't see them on debug. It's like uf they were'nt there.
Can someone explain me what is going wrong?
Thanks
Don't use Holders, and avoid pulling in dependencies. Use dependency injection, it's a Good Thing.
Your src/groovy class is probably called from a controller, service, Quartz job, or some other Grails artifact that supports DI, right? If so, inject this service there, and when you call your src/groovy class, pass it as a method argument, or inject it once in a constructor or a setter.
Even if it's not called from a Grails artifact it's likely easy to get access to the service. E.g. a servlet can access the ServletContext and it's simple to access the ApplicationContext from there.

Using resources.groovy to define services

I'm using the resources.groovy to declare a service e.g.
aService(com.foo.OrganizationService)
so that I can tie aService to my controllers instead of using organizationService which could change in the future.
I've noticed that the OrganizationService doesn't get treated special like other services "not" declared in the resources.groovy. For example it doesn't get injected with grailsApplication, and likely a hibernateSession etc and other things I've not hit yet....
Now, I know I can manually wire in stuff to my service but I'd rather not have to maintain that...
Is there a special way to declare a service in the resources.groovy so that gets treated like another service that grails loads up?
TIA
The short answer to your question is "no".
Under the covers, Grails services are driven by some intelligent code that is referencing a specific location and expecting certain properties.
Viewing the source code (especially around the ServicesGrailsPlugin.groovy) is a good way to see the "magic" in how these are wired together.
Is there a reason you wouldn't want to use a bonafide Grails service to solve your problem? If you are expecting things like a grailsApplication, it seems like that use is pretty specific to Grails and would be a good candidate for porting over to a "true" Grails service.
Good luck!
So I've come full circle on this. This is a timing problem. Where services haven't been grails initialized yet.
Basically when you use the resources.groovy to do service wiring you run the risk of using a Service that might initialize itself e.g. afterPropertiesSet method or static initializers that use grails services (log, hibernate session, ..) that haven't been injected yet.
So... What I've turned to instead is to create my own BeanBuilder in a BootStrap.groovy file.
BeanBuilder builder = new BeanBuilder(grailsApplication.parentContext)
def bb = builder.beans {
LoginListener(com.foo.LoginListener) {
springSecurityService = ref("springSecurityService")
userService = ref("userService")
}
}
bb.registerBeans(grailsApplication.mainContext)

Construtor/Setter Injection using IoC in HttpHandler, is it possible?

I've ran into a rather hairy problem. There is probably a simple solution to this but I can't find it!
I have a custom HttpHandler that I want to process a request, log certain info then enter the details in the database. I'm using NUnit and Castle Windsor.
So I have two interfaces; one for logging the other for data entry, which are constructor injected. I quickly found out that there is no way to call the constructor as the default parameterless constructor is always called instead.
So I thought I would use Setter injection and let Castle windsor sort it out. This actually works as when I use container.Resolve<CustomHttpHandler>(); I can check that the logger is not null. (In Application_Start in Global.asax.cs)
The problem is although Castle Windsor can create the instance the http application is not using it??? I think??
Basically the whole reason for doing it this way was to be able to test the logger and data repository code in isolation via mocking and unit testing.
Any ideas how I can go about solving this problem?
Thanks!
Not possible, at least not directly. IHttpHandler objects are instantiated by the ASP.NET runtime and it doesn't allow Windsor to get involved in its creation. You can either:
Pull dependencies, by using the container as a service locator.
Set up a base handler that creates, injects and delegates to your own handlers (see how Spring does it)
Use the container as a service locator for another service that handles the entire request (as saret explained)
What you could do is have the HttpHandler call out to another object that actually handles the request. so in your HttpHandler's ProcessRequest method you would do something like this:
public void ProcessRequest(HttpContext context)
{
var myHandlerObject = container.Resolve<HandlerObject>();
myHandlerObject.ProcessRequest(context or some state/info that is required)
}

Resources