Grails 2.4.3 - Asynchronous Programming #DelegateAsync - grails

Suppose the following situation...
I have to perform a process which takes a lot of time (about 1 hour)
and I do not want the user of my application to wait until it ends.
The business logic of this process is encapsulated in several services.
So:
class MyService{
def myService2
def myService3
public doSomething(){
myService2.doSomething()
myService3.doSomething()
}
}
class MyController{
def myService
def anAction(){
myService.doSomething()
redirect(action:'index')
}
}
I want the call to my service to be asynchronous.
I tried to create an asynchronous service as indicated by the Grails documentation, using #DelegateAsync.
class AsyncMyService {
#DelegateAsync MyService myService
}
class MyController{
def asyncMyService
def anAction(){
asyncMyService.doSomething()
.onComplete { List results ->
println "completed!"
}
redirect(action:'index')
}
}
But I get the following error when compiling my application:
Caused by ConversionNotSupportedException: Failed to convert property value of type
'MyService2$$EnhancerBySpringCGLIB$$f08a1b38' to equired type 'grails.async.Promise'
for property 'myService2'; nested exception is java.lang.IllegalStateException: Cannot
convert value of type [MyService2$$EnhancerBySpringCGLIB$$f08a1b38] to required type
[grails.async.Promise] for property 'myService2': no matching editors or conversion
strategy found
Any ideas to solve this problem?
Thanks!

Related

Grails does not resolve same-named Services as expected

I have two services with the same name in my Grails 2.4.4 project, called RemittanceService. One is in the package on ph.bank (which I created weeks ago) and another is on ph.gov.advice.slip(which I created today). Since now there are two instances of the service with the same name, I replaced all dependency-injection of ph.bank.RemittanceService from:
class ... {
def remittanceService
...
}
into this:
class ... {
def bankRemittanceService
// added the word `bank` from its package
...
}
and the injections for ph.gov.advice.slip.RemittanceService into:
class ... {
def slipRemittanceService
// added the word `slip` from its package
...
}
Now the problem is that it doesn't point the respective Service, and instead, returns an error:
java.lang.NullPointerException:
Cannot invoke method [...] on null object
I decided to revert it my previous code. When I return the declaration into:
def remittanceService
it always points to the Service found on ph.bank, never to my newly-created Service. My current fix is:
import ph.gov.advice.slip.RemittanceService
class ... {
def slipRemittanceService = new RemittanceService()
// Here I initialize it instead on how dependencies should be declared
...
}
Although, I felt that is wrong. Is there more Grails-ly way to do this?
You can declare beans in your resources.groovy file.
beans = {
bankRemittanceService(ph.bank.RemittanceService) {
}
slipRemittanceService(ph.gov.advice.slip.RemittanceService) {
}
}
now you can inject bankRemittanceService and slipRemittanceService

Exposing a configuration property via getter in a quartz job

Relating to Accessing grails application config from a quartz job:
Apparently, DI doesn't happen prior to the creation of a job. I'm guessing this is the same with other grails artefacts (couldn't spot relevant documentation).
In my particular case, I was aiming to load a property from config and expose that property from the job class. In general though, it seems a valid use-case to me, that artefacts will load configuration, and then return those properties via API.
I'm wondering then, how could this be achieved when a class cannot rely on access to grailsApplication.config at construction.
Thanks
Try with:
import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH
class MyJob {
def execute() {
def myConfigVar = CH.flatConfig.get('my.var.setup.in.config.groovy')
...
}
}
OR
import grails.util.Holders
class MyJob {
def execute() {
def myConfigVar = Holders.config.my.var.setup.in.config.groovy
...
}
}

Grails integration test cannot invoke method on null service object?

Simple service class, AnalyzerService, calls stored proc in a database.
Attempting to run integration test to ensure service calls the stored proc and correct data is returned after analyzer class operates on it. However, getting the dreaded exception that "Cannot invoke method calculateEstimateNumberOfPositions() on null object". Why is the service object null? What am I missing?
THANK YOU!
package foobar.analyze
import static org.junit.Assert.*
import org.junit.*
import foobar.analyze.AnalyzerService
//#TestFor(AnalyzerService)
class AnalyzerServiceTests {
def AnalyzerService service
def dataSource
#Before
void setUp() { }
#After
void tearDown() { }
#Test
void testcalculateEstimateNumberOfPositions() {
String positionName = "crew"
String city = "Great Neck"
String state = "NY"
int numberOfPositionsSought = 100
int expectedNumberOfPositionsEstimate = 100
def numberOfPositionsEstimate = service.calculateEstimateNumberOfPositions(positionName, city, state, numberOfPositionsSought)
fail (numberOfPositionsEstimate != expectedNumberOfPositionsEstimate)
}
}
Convention. Stick to the convention. Anything out of convention, regarding nomenclature, will create problem during dependency injection.
Convention is to use the service class name as analyzerService instead of service in integration test.
The integration test should look like
class AnalyzerServiceTests extends GroovyTestCase {
//Service class injected only if you
//use the naming convention as below for AnalyzerService
def analyzerService
def dataSource
......
......
}
It was possible to use service in unit test case when you use the test mixin
#TestFor(AnalyzerService)
By using the above in unit test cases, you could use the default service variable in the test cases. This is not the same in case of integration tests.

NullPointerException for Service-in-Service Injection during test-app

Recently came across with a weird scenario, that dependency injection for a service within a service, threw NPE while running test-app
Reason for service-in-service injection is to make the GORM/criteriaBuilder as DRY as possible. So following are my two services.
Following class SearchService1.groovy is implemented to provide search capability.
class SearchService1{
def search = { ...//Calls to local closures to build a dynamic criteria }
...
}
Class SearchService2.groovy uses the search closure of SearchService1 class
class SearchService2{
def searchService1
...
def searchEntity(){
searchService1.search()
}
}
Now, the above stated code works pretty well in run-app mode.
But for Integration test written for SearchService2 throws NPE as follows :
Cannot invoke method searchEntity() on null object
java.lang.NullPointerException: Cannot invoke method search() on null object
at com.myapp.service.SearchService2.searchEntity(SearchService2.groovy:326)
at com.myapp.service.SearchService2$searchEntity$0.callCurrent(Unknown Source)
at com.myapp.service.SearchService2.searchEntity(SearchService2.groovy:295)
at com.myapp.service.SearchService2$searchEntity.call(Unknown Source)
at com.myapp.integration.SearchService2Tests.testWhenSearch(SearchService2Tests.groovy:125)
Am I missing something very basic here ? Any thoughts are greatly appreciated. Many Thnx :)
Snippet from TestClass :
class SearchService2Tests extends GroovyTestCase{
...
def searchService2
...
void testWhenSearch(){
def resultSet = searchService2.searchEntity() //This is the line throwing NPE
...
}
}
Woah ! Got rid of this stupid error by this workaround.
To TestClass, inject the searchService1 to searchService2 object like this :
def searchService2
def searchService2.searchService1 = new SearchService1()
But come on ! Is this the right way to do it ? Can anyone explain the above error by the way, that why a Service-in-Service is not instantiated while running test-app.
try this:
class SearchService2Tests extends GroovyTestCase {
...
def searchService1
def searchService2
...
void testWhenSearch(){
def resultSet = searchService2.searchEntity()
...
}
}
but use standard Grails service naming convention and placement

Grails Dependency Injection Problem

I am having problems when using dependency injection with Services in Grails.
class ExampleService{
def example2Service
def example3Service
def method1(){
def result = example2Service.method2()
}
}
class ExampleService{
def example3Service
def method2(){
def result = example3Service.method3()
return result
}
}
class Example3Service{
def method3(){
return true
}
}
Basically in Example2Service, I am getting a Null Pointer Exception when trying to call method3 in Example3Service.
I would appreciate any help than anybody can give me with this issue
thanks
Dependency Injection needs to be initialized. (The same applies to other kinds of runtime meta programming, like augmenting Domain classes with their save() and validate() methods.)
A Grails application will be initialized when
being run from the grails run-app command
being run after having been deployed to a web server
being run from the grails test-app command (integration tests, only; unit tests do not trigger initialization).
Involved classes are not initialized when
executing a single Groovy file (i.e., by using groovy, groovysh, or groovyConsole)
or when executing a unit test.
The following as an integration test should work:
class Test2ServiceTests extends GroovyTestCase {
def test2Service
void testMethod2() {
assert test2Service.method2() == true
}
}

Resources