Results 1 to 8 of 8

Thread: @Transactional annotation with Aspectj LTW

  1. #1

    Default @Transactional annotation with Aspectj LTW

    Hi,

    When using @Transactional annotation with LTW (Spring 2rc3 and Hibernate transaction manager)
    I am getting the following stack trace

    ** Exception 1 of 1 has message: null
    java.lang.NullPointerException
    at org.springframework.transaction.interceptor.Transa ctionAspectSupport.createTransactionIfNecessary(Tr ansactionAspectSupport.java:234)
    at org.springframework.transaction.aspectj.AbstractTr ansactionAspect.ajc$before$org_springframework_tra nsaction_aspectj_AbstractTransactionAspect$1$2a73e 96c(AbstractTransactionAspect.aj:64)
    at tv.cozmo.central.logic.peer.PeerHandler.createOrUp datePeer(PeerHandler.java)
    at tv.cozmo.central.logic.peer.PeerHandler$$FastClass ByCGLIB$$6f65dbef.invoke(<generated>)
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy. java:149)
    at org.springframework.aop.framework.Cglib2AopProxy$C glibMethodInvocation.invokeJoinpoint(Cglib2AopProx y.java:709)
    at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :148)
    at org.springframework.transaction.interceptor.Transa ctionInterceptor.invoke(TransactionInterceptor.jav a:100)
    at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :170)
    at org.springframework.aop.framework.Cglib2AopProxy$D ynamicAdvisedInterceptor.intercept(Cglib2AopProxy. java:647)
    at tv.cozmo.central.logic.peer.PeerHandler$$EnhancerB yCGLIB$$3a817d71.createOrUpdatePeer(<generated>)
    at tv.cozmo.central.web.controller.RegisterServlet.do Get_aroundBody0(RegisterServlet.java:33)
    at tv.cozmo.central.web.controller.RegisterServlet$Aj cClosure1.run(RegisterServlet.java:1)
    at org.aspectj.runtime.reflect.JoinPointImpl.proceed( JoinPointImpl.java:173)
    at tv.cozmo.central.logic.aop.PerServletAdvice.around AdviceTest(PerServletAdvice.java:41)
    at tv.cozmo.central.web.controller.RegisterServlet.do Get(RegisterServlet.java:1)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:689)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:802)
    at org.springframework.web.servlet.handler.SimpleServ letHandlerAdapter.handle(SimpleServletHandlerAdapt er.java:63)
    at org.springframework.web.servlet.DispatcherServlet. doDispatch(DispatcherServlet.java:798)
    at org.springframework.web.servlet.DispatcherServlet. doService(DispatcherServlet.java:728)
    at org.springframework.web.servlet.FrameworkServlet.p rocessRequest(FrameworkServlet.java:396)
    at org.springframework.web.servlet.FrameworkServlet.d oGet(FrameworkServlet.java:350)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:689)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:802)
    at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:252)
    at org.apache.catalina.core.ApplicationFilterChain.do Filter(ApplicationFilterChain.java:173)
    at org.apache.catalina.core.StandardWrapperValve.invo ke(StandardWrapperValve.java:213)
    at org.apache.catalina.core.StandardContextValve.invo ke(StandardContextValve.java:178)
    at org.apache.catalina.authenticator.AuthenticatorBas e.invoke(AuthenticatorBase.java:432)
    at org.apache.catalina.valves.AccessLogValve.invoke(A ccessLogValve.java:541)
    at org.apache.catalina.core.StandardHostValve.invoke( StandardHostValve.java:126)
    at org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:105)
    at org.apache.catalina.core.StandardEngineValve.invok e(StandardEngineValve.java:107)
    at org.apache.catalina.connector.CoyoteAdapter.servic e(CoyoteAdapter.java:148)
    at org.apache.coyote.http11.Http11Processor.process(H ttp11Processor.java:868)
    at org.apache.coyote.http11.Http11BaseProtocol$Http11 ConnectionHandler.processConnection(Http11BaseProt ocol.java:663)
    at org.apache.tomcat.util.net.PoolTcpEndpoint.process Socket(PoolTcpEndpoint.java:527)
    at org.apache.tomcat.util.net.LeaderFollowerWorkerThr ead.runIt(LeaderFollowerWorkerThread.java:80)
    at org.apache.tomcat.util.threads.ThreadPool$ControlR unnable.run(ThreadPool.java:684)
    at java.lang.Thread.run(Unknown Source)


    The Spring config looks as follows

    <aop:aspectj-autoproxy proxy-target-class="true"/>

    <tx:annotation-driven/>


    My guess (confirmed by some debugging) is that aspectj is "weaving around" (interceptor) bean that
    can't initialize some of its properties (transaction manager) outside the container.

    What is a correct/recommended way of using @Transactional annotation with aspectj LTW ?


    Thanks,

    Alex

  2. #2
    Join Date
    Jun 2006
    Location
    SF Bay Area, California
    Posts
    524

    Default Reproducable project will help

    It is possible to create and send a small project that exhibits this problem?

    -Ramnivas
    Ramnivas Laddad (Follow me on Twitter)
    AspectJ in Action: Enterprise AOP with Spring Applications (2nd edition). Now available!

  3. #3

    Default

    I am kind of busy right now, but I will try to build a small
    example over weekend.

    Thanks,

    Alex

  4. #4
    Join Date
    Aug 2006
    Location
    Now Germany, previously Ukraine
    Posts
    1,546

    Unhappy

    Hi Alex,

    as far as understand you want to use annotation on the objects that are not created by Spring (otherwise you need not AspectJ LTW). <tx:annotation-driven> serves only Spring beans and is of no use for you (more over, it may harm you if you try to use it parallel with LTW, I just recently posted it as bug).

    But it is documented how to achieve what you want; take a look on a snippet at the beginning of chapter 9.5.6 of Spring 2.0 RC3 Reference -

    Code:
    // configure the AnnotationTransactionAspect to use it; this must be done before executing any transactional methods
    AnnotationTransactionAspect.aspectOf().setTransactionManager (txManager);
    Definitely, you need first to obtain this txManager - load as bean from Spring container or just create it if you work outside of Spring IoC container.

    BTW. one remark - I now play a lot with @Transactional and LTW and is quite unsatisfied, it seems to be very fragile and cumbersone and its behavior deviates a lot from behavior of the same annotation when used together with Spring beans and <tx:annotation-driven>. In my opinion (whatever it worth) it very far from production quality and have to be excluded from 2.0 final (or, at least, marked as "experimental" and not intended for production usage).

    Definitely, mileage of Spring development team may vary.

    Regards,

    Oleksandr Alesinskyy

  5. #5
    Join Date
    Aug 2006
    Location
    Now Germany, previously Ukraine
    Posts
    1,546

    Default

    As I have just released you even need not include line
    Code:
    AnnotationTransactionAspect.aspectOf().setTransactionManager (txManager);
    mentioned in my previous post into your code, it's enough to include following bean definition into context

    Code:
    <bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect"
                factory-method="aspectOf">
            <property name="transactionManager" ref="txManager"/>
    </bean>
    Regards,

    Oleksandr Alesinskyy

  6. #6

    Default thanks

    Thanks a lot.

    It works fine the way you described, with or without redundant <tx:annotation-driven/> configuration.

    I have actually, implemented a version of @Transactional annotation with corresponding advice obtaining transaction manager outside of the Spring container. That one also works fine.
    I did not realize, as you have pointed out, that transaction manager can be set in AnnotationTransactionAspect itself ( as described in 9.5.6 ) .

    By the way, a case for using LTW to annotate methods in a Spring bean is when calling transaction-annotated method of a class from non-transactional method of the same class (that is without crossing container boundary). When Spring will support privileged aspects it will be possible to apply this to private methods as well.

    Regards,

    Alex

  7. #7
    Join Date
    Aug 2006
    Location
    Now Germany, previously Ukraine
    Posts
    1,546

    Default

    When Spring will support privileged aspects it will be possible to apply this to private methods as well.

    For Spring it does not matter, if aspects are priviledged, just take source of
    AnnotationTransactionalAspect (distributed with Spring in aspectj directory) and modify whatever you wish. Distributed source, for reasons that are uncomprechesible for me supports only public methods (unlike <tx:annotation-driven> tag which supports as well defult and protected scopes).

    Just chaging in 2 pointcuts in this aspect "public" to "!private" expand make it (almost) consistent. For private you need to do slightly more, but it is absolutely doable.

  8. #8

    Default Thanks

    Thanks,

    Alex

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •