Hi John, I tested the fix and I didn't get the problem anymore.
Thanks, Xavier ---------------------------------------- > From: [email protected] > Date: Wed, 13 Jul 2016 23:52:19 +0000 > Subject: Re: NPE in AbstractManualInvocationHandler > To: [email protected] > > Xavier, > > I just pushed up a fix. Can you check out, rebuild and see if it fixes the > issue for you? The error was pretty quick to reproduce with your test. > > John > > On Wed, Jul 13, 2016 at 11:25 AM John D. Ament <[email protected]> > wrote: > >> Thanks, I put in https://issues.apache.org/jira/browse/DELTASPIKE-1183 >> >> I'll port your test over to create a reproducible test as a part of this. >> Thanks for not using data in the test, since yes the issue is in partial >> bean/proxy. >> >> John >> >> >> On Wed, Jul 13, 2016 at 11:20 AM Xavier Dury <[email protected]> wrote: >> >>> Here is a reproducible test (I am using ApplicationComposer from TomEE), >>> I replaced the repository by some other partial bean to simplify. >>> >>> import static java.lang.annotation.RetentionPolicy.RUNTIME; >>> import static java.util.concurrent.TimeUnit.SECONDS; >>> >>> import java.lang.annotation.Retention; >>> import java.lang.reflect.InvocationHandler; >>> import java.lang.reflect.Method; >>> import java.util.ArrayList; >>> import java.util.List; >>> import java.util.concurrent.ExecutorService; >>> import java.util.concurrent.Future; >>> import java.util.concurrent.RejectedExecutionHandler; >>> import java.util.concurrent.SynchronousQueue; >>> import java.util.concurrent.ThreadPoolExecutor; >>> >>> import javax.annotation.Resource; >>> import javax.enterprise.concurrent.ManagedThreadFactory; >>> import javax.inject.Inject; >>> >>> import org.apache.deltaspike.core.api.provider.BeanManagerProvider; >>> import org.apache.deltaspike.partialbean.api.PartialBeanBinding; >>> import org.apache.deltaspike.partialbean.impl.PartialBeanBindingExtension; >>> import >>> org.apache.deltaspike.proxy.impl.invocation.DelegateManualInvocationHandler; >>> import org.apache.deltaspike.proxy.impl.invocation.InterceptorLookup; >>> import org.apache.openejb.junit.ApplicationComposerRule; >>> import org.apache.openejb.testing.CdiExtensions; >>> import org.apache.openejb.testing.Module; >>> import org.junit.Rule; >>> import org.junit.Test; >>> import org.junit.rules.TestRule; >>> >>> public @CdiExtensions({BeanManagerProvider.class, >>> PartialBeanBindingExtension.class}) class ConcurrencyBugTest { >>> >>> public final @Rule TestRule composer = new >>> ApplicationComposerRule(this); >>> >>> public @PartialBeanBinding @Retention(RUNTIME) @interface >>> MyPartialBeanBinding { >>> } >>> >>> public @MyPartialBeanBinding interface PartialBean { >>> >>> String getValue(); >>> } >>> >>> public static @MyPartialBeanBinding class MyPartialBeanHandler >>> implements InvocationHandler { >>> >>> public Object invoke(Object proxy, Method method, Object[] args) >>> throws Throwable { >>> return method.getName(); >>> } >>> } >>> >>> private class BlockPolicy implements RejectedExecutionHandler { >>> >>> public @Override void rejectedExecution(Runnable runnable, >>> ThreadPoolExecutor executor) { >>> try { >>> executor.getQueue().put(runnable); >>> } catch (InterruptedException interruptedException) { >>> Thread.currentThread().interrupt(); >>> } >>> } >>> } >>> >>> public @Module Class<?>[] classes() { >>> return new Class<?>[] { DelegateManualInvocationHandler.class, >>> InterceptorLookup.class, PartialBean.class, MyPartialBeanHandler.class, >>> MyPartialBeanHandler.class }; >>> } >>> >>> private @Resource ManagedThreadFactory threadFactory; >>> private @Inject PartialBean bean; >>> >>> public @Test void test() throws Exception { >>> ExecutorService executor = new ThreadPoolExecutor(5, 10, 60, >>> SECONDS, new SynchronousQueue<>(), this.threadFactory, new BlockPolicy()); >>> List<Future<String>> results = new ArrayList<>(100); >>> for (int i = 0; i < 100; i++) { >>> results.add(executor.submit(this.bean::getValue)); >>> } >>> executor.shutdown(); >>> executor.awaitTermination(60, SECONDS); >>> for (int i = 0; i < 100; i++) { >>> results.get(i).get(); >>> } >>> } >>> } >>> >>> >>> java.util.concurrent.ExecutionException: java.lang.NullPointerException >>> at java.util.concurrent.FutureTask.report(Unknown Source) >>> at java.util.concurrent.FutureTask.get(Unknown Source) >>> at >>> be.fgov.sfpd.attestation.ConcurrencyBugTest.test(ConcurrencyBugTest.java:79) >>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>> at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) >>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) >>> at java.lang.reflect.Method.invoke(Unknown Source) >>> at >>> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) >>> at >>> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) >>> at >>> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) >>> at >>> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) >>> at >>> org.apache.openejb.junit.DeployApplication$1.call(DeployApplication.java:44) >>> at >>> org.apache.openejb.junit.DeployApplication$1.call(DeployApplication.java:40) >>> at >>> org.apache.openejb.testing.ApplicationComposers.evaluate(ApplicationComposers.java:1067) >>> at >>> org.apache.openejb.junit.DeployApplication.evaluate(DeployApplication.java:40) >>> at org.junit.rules.RunRules.evaluate(RunRules.java:20) >>> at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) >>> at >>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) >>> at >>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) >>> at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) >>> at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) >>> at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) >>> at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) >>> at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) >>> at org.junit.runners.ParentRunner.run(ParentRunner.java:363) >>> at >>> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) >>> at >>> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) >>> at >>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) >>> at >>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) >>> at >>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) >>> at >>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) >>> Caused by: java.lang.NullPointerException >>> at >>> org.apache.deltaspike.proxy.impl.invocation.AbstractManualInvocationHandler.invoke(AbstractManualInvocationHandler.java:38) >>> at >>> org.apache.deltaspike.proxy.impl.invocation.DelegateManualInvocationHandler$$OwbNormalScopeProxy0.invoke(org/apache/deltaspike/proxy/impl/invocation/DelegateManualInvocationHandler.java) >>> at >>> org.apache.deltaspike.proxy.impl.invocation.DelegateManualInvocationHandler.staticInvoke(DelegateManualInvocationHandler.java:40) >>> at >>> be.fgov.sfpd.attestation.ConcurrencyBugTest$PartialBean$$DSPartialBeanProxy.getValue(Unknown >>> Source) >>> at java.util.concurrent.FutureTask.run(Unknown Source) >>> at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) >>> at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) >>> at java.lang.Thread.run(Unknown Source) >>> >>> ---------------------------------------- >>>> From: [email protected] >>>> To: [email protected] >>>> Subject: RE: NPE in AbstractManualInvocationHandler >>>> Date: Wed, 13 Jul 2016 16:54:20 +0200 >>>> >>>> I can reproduce the problem in a test (~4 times out of 5) with my whole >>> application, if needed I can try to isolate the problem by reducing my app >>> to the bare minimum. >>>> I am using your snapshots but, if needed, I can build it myself. >>>> >>>> Xavier >>>> >>>> ---------------------------------------- >>>>> From: [email protected] >>>>> Date: Wed, 13 Jul 2016 14:46:29 +0000 >>>>> Subject: Re: NPE in AbstractManualInvocationHandler >>>>> To: [email protected] >>>>> >>>>> Do you have a reproducible sequence or is it only under load? I think I >>>>> know the issue. Also did you build 1.7.1 yourself or pointing to our >>>>> snapshots? >>>>> >>>>> John >>>>> >>>>> On Wed, Jul 13, 2016 at 10:41 AM Xavier Dury <[email protected]> >>> wrote: >>>>> >>>>>> Sorry, >>>>>> >>>>>> I spoke too soon, I still have the problem: >>>>>> >>>>>> Caused by: java.lang.NullPointerException >>>>>> at >>>>>> >>> org.apache.deltaspike.proxy.impl.invocation.AbstractManualInvocationHandler.invoke(AbstractManualInvocationHandler.java:38) >>>>>> at >>>>>> >>> org.apache.deltaspike.proxy.impl.invocation.DelegateManualInvocationHandler$$OwbNormalScopeProxy0.invoke(org/apache/deltaspike/proxy/impl/invocation/DelegateManualInvocationHandler.java) >>>>>> at >>>>>> >>> org.apache.deltaspike.proxy.impl.invocation.DelegateManualInvocationHandler.staticInvoke(DelegateManualInvocationHandler.java:40) >>>>>> >>>>>> Xavier >>>>>> >>>>>> ---------------------------------------- >>>>>>> From: [email protected] >>>>>>> To: [email protected] >>>>>>> Subject: RE: NPE in AbstractManualInvocationHandler >>>>>>> Date: Wed, 13 Jul 2016 16:36:18 +0200 >>>>>>> >>>>>>> Hi, >>>>>>> >>>>>>> Indeed, 1.7.1-SNAPSHOT fixed my problem. >>>>>>> >>>>>>> Thanks, >>>>>>> >>>>>>> Xavier >>>>>>> ---------------------------------------- >>>>>>>> From: [email protected] >>>>>>>> Date: Wed, 13 Jul 2016 14:23:43 +0000 >>>>>>>> Subject: Re: NPE in AbstractManualInvocationHandler >>>>>>>> To: [email protected] >>>>>>>> >>>>>>>> Hi Xavier, >>>>>>>> >>>>>>>> Could you try with 1.7.1-snapshot? There was some weird static logic >>>>>> doing >>>>>>>> initialization which has been changed in the up coming 1.7.1 >>>>>>>> >>>>>>>> John >>>>>>>> >>>>>>>> On Wed, Jul 13, 2016 at 9:49 AM Xavier Dury <[email protected]> >>> wrote: >>>>>>>> >>>>>>>>> Hi, >>>>>>>>> >>>>>>>>> Since I upgraded to DeltaSpike 1.7.0 / TomEE 7.0.1, I get NPEs when >>>>>>>>> calling some repositories in a multi-threaded batch. >>>>>>>>> >>>>>>>>> Caused by: java.lang.NullPointerException >>>>>>>>> at >>>>>>>>> >>>>>> >>> org.apache.deltaspike.proxy.impl.invocation.AbstractManualInvocationHandler.invoke(AbstractManualInvocationHandler.java:40) >>>>>>>>> at >>>>>>>>> >>>>>> >>> org.apache.deltaspike.proxy.impl.invocation.DelegateManualInvocationHandler.staticInvoke(DelegateManualInvocationHandler.java:39) >>>>>>>>> >>>>>>>>> That line contains the following code: >>>>>>>>> >>>>>>>>> List<Interceptor<?>> interceptors = interceptorLookup.lookup(proxy, >>>>>>>>> method); >>>>>>>>> >>>>>>>>> So it seems that interceptorLookup was not initialized correctly. >>>>>>>>> >>>>>>>>> I see there is a double-check locking on a volatile Boolean for >>>>>>>>> initialization in that class... Wouldn't it be better if the >>> locking >>>>>>>>> occurred on the interceptorLookup or if the interceptorLookup would >>>>>> also be >>>>>>>>> declared as volatile? >>>>>>>>> >>>>>>>>> Regards, >>>>>>>>> >>>>>>>>> Xavier >>>>>>>>> >>>>>>> >>>>>> >>>> >>> >> >>
