Reputation: 7789
I want to have an app that listens to TCP socket connections and can react to them. In order for that I need to start a background thread on start - I can do that in BootStrap.groovy.
For the background threading I downloaded the executor plugin.
The code looks like this:
class BootStrap {
def myService
def init = { servletContext ->
log.info("Bootstrapping")
development {
log.info("Doing myService async ")
myService.doSomething()
}
}
class MyService {
def doSomething() {
runAsync {
println "Running!"
}
}
}
}
This code is a copy-paste from an another thread here at SO.
I am getting this error:
| Error 2014-06-06 22:30:37,317 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing the application: Cannot invoke method doSomething() on null object
Message: Cannot invoke method doSomething() on null object
Line | Method
->> 14 | doCall in BootStrap$_closure1_closure2
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
It seems that the myService object is not populated. Do I need to edit some configs or something?
Edit: tried to use executorService, but that didn't help either.
| Error 2014-06-07 00:06:36,099 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing the application: Cannot invoke method doSomething() on null object
Message: Cannot invoke method doSomething() on null object
Line | Method
->> 14 | doCall in BootStrap$_closure1_closure2
Upvotes: 1
Views: 612
Reputation: 2354
Well, I think you should have a look at this plugin: http://grails.org/plugin/routing
The plugin is based on apache camel http://camel.apache.org/ . It has lot of options and components which you could use. I have used it a lot for HL7 integration where we send and receive responses on TCP socket. The simplest example of a TCP would be:
import org.apache.camel.builder.RouteBuilder
class MyMessageRoute extends RouteBuilder {
from('mina2:tcp://localhost:9090').to('stream:out')
}
}
So, whatever comes on localhost 9090 will be printed to your console. Your host and port will start as soon as your application is up and even when you run integration tests, the port will be listening. To run this you will need to have the routing plugin installed and also have below dependencies in you BuildConfig.groovy
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
runtime "org.apache.mina:mina-core:2.0.7"
runtime "org.apache.mina:mina-integration-spring:1.1.7"
runtime "org.apache.camel:camel-mina2:2.13.0"
compile('org.apache.poi:poi-ooxml:3.8') {
}
}
You could even use netty instead on mina2. For more info on their integration with apache camel look at below docs.
Netty component: http://camel.apache.org/netty.html
Mina2 Component: http://camel.apache.org/mina2.html
All camel components: http://camel.apache.org/components.html
Hope this helps!!
Upvotes: 2
Reputation: 457
You should move your doSomethoing() method to a separate service as suggested by @Fabrizio D'Ammassa, and if you don't want to move your code to separate service than you can achieve this goal as follow :
class BootStrap {
def init = { servletContext ->
log.info("Bootstrapping")
development {
log.info("Doing myService async ")
doSomething()
}
}
def doSomething() {
runAsync {
println "Running!"
}
}
}
Upvotes: 2
Reputation: 4769
You should move the service class to the proper folder in Grails project.
Bootstrap.groovy
class BootStrap {
def myService
def init = { servletContext ->
log.info("Bootstrapping")
development {
log.info("Doing myService async ")
myService.doSomething()
}
}
}
MyService.groovy
class MyService {
def doSomething() {
runAsync {
println "Running!"
}
}
}
Upvotes: 2
Reputation: 43
I've created a short SocketServer example (called 'gsocket') here: https://github.com/m-schneider/gsocket In the case where it's not a prerequisite that you define your service class in 'BootStrap.groovy' it should fit your needs - hopefully ;) A Socket Server client (client.groovy) is also in the main folder for rapid testing.
Hope that helps.
Upvotes: 2
Reputation: 93173
no , myService object is populated.
class MyService {
def executorService
def doSomething() {
executorService.submit({
println "Running!"
} as Callable)
}
}
Use this instead of runsync
,if you have executor plugin .
And if Dependency Injection of MyService
did not work , clean your app :
grails stop-app
grails clean-all
grails refresh-dependencies
grails run-app
Upvotes: 1