As per the following spring doc link I can use @Async annotation to make a method call asynchronous. Can I use this facility in Grails from a java src file that I have?
[Update]
This is my java(netty) socket handler class which receives the socket packet.
public class DefaultHandler extends SimpleChannelUpstreamHandler {
private static final Logger LOG = LoggerFactory.getLogger(DefaultHandler.class);
private AggregateSocketData aggregateSocketData;
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
throws Exception {
LOG.trace("In messageRecieved method with event: {}",e);
IEvent event = Events.dataInEvent(e.getMessage());
System.out.println(Thread.currentThread().getName());
aggregateSocketData.receiveSocketData(event);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
throws Exception {
LOG.error("Exception occurred in Default Handler: " ,e.getCause());
}
public AggregateSocketData getAggregateSocketData() {
return aggregateSocketData;
}
public void setAggregateSocketData(AggregateSocketData aggregateSocketData) {
this.aggregateSocketData = aggregateSocketData;
}
}
I have made it a bean in grails- conf – resources.xml
<bean id="defaultECM1240Handler" class="com.appcapture.buildingmgr.netty.DefaultHandler"
scope="prototype">
<property name="aggregateSocketData" ref="binaryDataAggregatorService"></property>
</bean>
And this is my grails service class whose method I have annotated with @Async
class BinaryDataAggregatorService implements AggregateSocketData {
def rawDataService
static transactional = true
@Async
void receiveSocketData(IEvent event) {
println Thread.currentThread().name
log.debug("Going to decode netty packet in receiveSocketData");
Map decodedPacket = decodePacket((INettyPacket)event.getSource())
def rawData = saveRawData (decodedPacket);
log.debug ("Saved raw data, id: ${rawData?.id}")
rawDataService.saveHTTPData(decodedPacket);
}
}
[Update 2] Here is the stack trace for the method call.
Here is the stack. BinaryDataAggregatorService.receiveSocketData(INettyPacket) line: 20
BinaryDataAggregatorService$$FastClassByCGLIB$$82489f62.invoke(int, Object, Object[]) line: not available
MethodProxy.invoke(Object, Object[]) line: 149
Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint() line: 688
Cglib2AopProxy$CglibMethodInvocation(ReflectiveMethodInvocation).proceed() line: 150
TransactionInterceptor.invoke(MethodInvocation) line: 110
Cglib2AopProxy$CglibMethodInvocation(ReflectiveMethodInvocation).proceed() line: 172
Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Object, Method, Object[], MethodProxy) line: 621
BinaryDataAggregatorService$$EnhancerByCGLIB$$1c96985c.receiveSocketData(INettyPacket) line: not available
DefaultHandler.handlePacket(INettyPacket) line: 50
[Update 3]
The grails stack trace on setting the task:annotation-driven element.
011-05-26 17:38:03,109 [main] ERROR context.GrailsContextLoader - Error executing bootstraps: Error creating bean with name 'defaultECM1240Handler' defined in URL [file:./grails-app/conf/spring/resources.xml]: Cannot resolve reference to bean 'binaryDataAggregatorService' while setting bean property 'aggregateSocketData'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'binaryDataAggregatorService': Invocation of init method failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class $Proxy12]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class $Proxy12
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultECM1240Handler' defined in URL [file:./grails-app/conf/spring/resources.xml]: Cannot resolve reference to bean 'binaryDataAggregatorService' while setting bean property 'aggregateSocketData'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'binaryDataAggregatorService': Invocation of init method failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class $Proxy12]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class $Proxy12
Thanks,
Abraham
If it is a spring bean – yes, you can. For that you have to annotate it with
@Serviceand have a<context:component-scan base-package="com.foo.bar" />But to make it easier, you can use a groovy class placed in the
grails-app/services– it will be a spring bean automaticallyIn order to make
@Asyncwork, you need<task:annotation-driven/>in the xml config.