puniverse / comsat

Fibers and actors for web development
docs.paralleluniverse.co/comsat
Other
598 stars 103 forks source link

Issue regarding JOOQ instrumenation and transaction proxies #36

Closed imperatorx closed 9 years ago

imperatorx commented 9 years ago

I have created the sample project https://github.com/imperatorx/comsat-jooq-test to illustrate this issue.

I'm using spring @Transactional annotations and Jooq. The FiberDataSource is wrapped in a spring TransactionAwareDataSourceProxy, which is instrumented via the suspendables and suspendable-supers file.

If I manually aquire a connection from the DataSourceProxy and run a PreparedStatement, I get no errors, and the proxied method call runs with a connection that is provided from the proxy with automatic transactions (logging is set to TRACE)

If I call a JOOQ method, which executes a query, I get no instrumentation warnings, but I get a strange NullPointerException, when Jooq prepares the statement. The last call seems to be to co.paralleluniverse.fibers.jdbc.FiberConnection.prepareStatement(FiberConnection.java:65)

Note that I hadd to add

The exception:

Exception in Fiber "fiber-10000002" If this exception looks strange, perhaps you've forgotten to instrument a blocking method. Run your program with -Dco.paralleluniverse.fibers.verifyInstrumentation to catch the culprit!
java.lang.NullPointerException
    at co.paralleluniverse.fibers.FiberAsync.run(FiberAsync.java:121)
    at co.paralleluniverse.fibers.FiberAsync.runBlocking(FiberAsync.java:409)
    at co.paralleluniverse.fibers.jdbc.JDBCFiberAsync.exec(JDBCFiberAsync.java:29)
    at co.paralleluniverse.fibers.jdbc.FiberConnection.prepareStatement(FiberConnection.java:65)
    at co.paralleluniverse.fibers.jdbc.FiberConnection.prepareStatement(FiberConnection.java:41)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:240)
    at com.sun.proxy.$Proxy40.prepareStatement(Unknown Source)
    at org.jooq.impl.ProviderEnabledConnection.prepareStatement(ProviderEnabledConnection.java:112)
    at org.jooq.impl.SettingsEnabledConnection.prepareStatement(SettingsEnabledConnection.java:76)
    at org.jooq.impl.AbstractResultQuery.prepare(AbstractResultQuery.java:216)
    at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:316)
    at org.jooq.impl.AbstractResultQuery.fetchLazy(AbstractResultQuery.java:319)
    at org.jooq.impl.AbstractResultQuery.fetchLazy(AbstractResultQuery.java:306)
    at org.jooq.impl.AbstractResultQuery.fetchOne(AbstractResultQuery.java:440)
    at org.jooq.impl.DefaultDSLContext.fetchOne(DefaultDSLContext.java:541)
    at foo.quasar.test.MyServiceImpl.jooqTransactionalMethod(MyServiceImpl.java:32)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:64)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy34.jooqTransactionalMethod(Unknown Source)
    at foo.quasar.test.App$2.run(App.java:78)
    at foo.quasar.test.App$2.run(App.java:65)
Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.NullPointerException
    at co.paralleluniverse.fibers.Fiber.get(Fiber.java:1304)
    at co.paralleluniverse.fibers.Fiber.join(Fiber.java:1279)
    at foo.quasar.test.App.test(App.java:83)
    at foo.quasar.test.App.main(App.java:30)
Caused by: java.lang.NullPointerException
    at co.paralleluniverse.fibers.FiberAsync.run(FiberAsync.java:121)
    at co.paralleluniverse.fibers.FiberAsync.runBlocking(FiberAsync.java:409)
    at co.paralleluniverse.fibers.jdbc.JDBCFiberAsync.exec(JDBCFiberAsync.java:29)
    at co.paralleluniverse.fibers.jdbc.FiberConnection.prepareStatement(FiberConnection.java:65)
    at co.paralleluniverse.fibers.jdbc.FiberConnection.prepareStatement(FiberConnection.java:41)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:240)
    at com.sun.proxy.$Proxy40.prepareStatement(Unknown Source)
    at org.jooq.impl.ProviderEnabledConnection.prepareStatement(ProviderEnabledConnection.java:112)
    at org.jooq.impl.SettingsEnabledConnection.prepareStatement(SettingsEnabledConnection.java:76)
    at org.jooq.impl.AbstractResultQuery.prepare(AbstractResultQuery.java:216)
    at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:316)
    at org.jooq.impl.AbstractResultQuery.fetchLazy(AbstractResultQuery.java:319)
    at org.jooq.impl.AbstractResultQuery.fetchLazy(AbstractResultQuery.java:306)
    at org.jooq.impl.AbstractResultQuery.fetchOne(AbstractResultQuery.java:440)
    at org.jooq.impl.DefaultDSLContext.fetchOne(DefaultDSLContext.java:541)
    at foo.quasar.test.MyServiceImpl.jooqTransactionalMethod(MyServiceImpl.java:32)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:64)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy34.jooqTransactionalMethod(Unknown Source)
    at foo.quasar.test.App$2.run(App.java:78)
    at foo.quasar.test.App$2.run(App.java:65)
    at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1014)
    at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:729)
    at co.paralleluniverse.fibers.FiberForkJoinScheduler$FiberForkJoinTask.exec1(FiberForkJoinScheduler.java:257)
    at co.paralleluniverse.concurrent.forkjoin.ParkableForkJoinTask.doExec(ParkableForkJoinTask.java:116)
    at co.paralleluniverse.concurrent.forkjoin.ParkableForkJoinTask.exec(ParkableForkJoinTask.java:73)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:902)
    at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1689)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1644)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
circlespainter commented 9 years ago

The verification failure disappeared when using a Quasar version containing a fix for https://github.com/puniverse/quasar/issues/108 which allowed me to find the remaining uninstrumented parts.