You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by jo...@apache.org on 2016/07/13 23:51:28 UTC
deltaspike git commit: DELTASPIKE-1183 Fix concurrency issue when
using proxies.
Repository: deltaspike
Updated Branches:
refs/heads/master db8560c41 -> f2985d502
DELTASPIKE-1183 Fix concurrency issue when using proxies.
Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/f2985d50
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/f2985d50
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/f2985d50
Branch: refs/heads/master
Commit: f2985d5022a04dce005ee3540a350822d4987a3b
Parents: db8560c
Author: John D. Ament <jo...@apache.org>
Authored: Wed Jul 13 19:51:23 2016 -0400
Committer: John D. Ament <jo...@apache.org>
Committed: Wed Jul 13 19:51:23 2016 -0400
----------------------------------------------------------------------
.../core/api/partialbean/uc012/BlockPolicy.java | 39 +++++++
.../partialbean/uc012/ConcurrencyBugTest.java | 109 +++++++++++++++++++
.../partialbean/uc012/MyPartialBeanBinding.java | 32 ++++++
.../partialbean/uc012/MyPartialBeanHandler.java | 32 ++++++
.../core/api/partialbean/uc012/PartialBean.java | 29 +++++
.../AbstractManualInvocationHandler.java | 37 ++-----
6 files changed, 248 insertions(+), 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f2985d50/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/BlockPolicy.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/BlockPolicy.java b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/BlockPolicy.java
new file mode 100644
index 0000000..2f9af70
--- /dev/null
+++ b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/BlockPolicy.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.deltaspike.test.core.api.partialbean.uc012;
+
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.ThreadPoolExecutor;
+
+public class BlockPolicy implements RejectedExecutionHandler
+{
+ @Override
+ public void rejectedExecution(Runnable runnable, ThreadPoolExecutor executor)
+ {
+ try
+ {
+ executor.getQueue().put(runnable);
+ }
+ catch (InterruptedException interruptedException)
+ {
+ Thread.currentThread().interrupt();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f2985d50/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/ConcurrencyBugTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/ConcurrencyBugTest.java b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/ConcurrencyBugTest.java
new file mode 100644
index 0000000..a931768
--- /dev/null
+++ b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/ConcurrencyBugTest.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.deltaspike.test.core.api.partialbean.uc012;
+
+import org.apache.deltaspike.test.core.api.partialbean.util.ArchiveUtils;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+@RunWith(Arquillian.class)
+public class ConcurrencyBugTest
+{
+
+ @Deployment
+ public static WebArchive war()
+ {
+ final String simpleName = ConcurrencyBugTest.class.getSimpleName();
+ final String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1);
+
+ final JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar")
+ .addPackage(ConcurrencyBugTest.class.getPackage())
+ .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
+
+ final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, archiveName + ".war")
+ .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive())
+ .addAsLibraries(testJar)
+ .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
+
+ return webArchive;
+ }
+
+ @Inject
+ private PartialBean bean;
+
+ @Test
+ public void testWithConcurrency() throws Exception
+ {
+ ThreadFactory threadFactory = Executors.defaultThreadFactory();
+ ExecutorService executor = new ThreadPoolExecutor(5, 10, 60, SECONDS, new SynchronousQueue<Runnable>(),
+ threadFactory, new BlockPolicy());
+ int iterations = 100;
+ List<Future<String>> results = new ArrayList<Future<String>>(iterations);
+ for (int i = 0; i < iterations; i++) {
+ results.add(executor.submit(new BeanCaller(bean)));
+ }
+ executor.shutdown();
+ executor.awaitTermination(60, SECONDS);
+ for (int i = 0; i < iterations; i++)
+ {
+ results.get(i).get();
+ }
+ }
+
+ private class BeanCaller implements Callable<String>
+ {
+ private final PartialBean partialBean;
+
+ private BeanCaller(PartialBean partialBean) {
+ this.partialBean = partialBean;
+ }
+
+ @Override
+ public String call() {
+ try {
+ return partialBean.getValue();
+ }
+ catch (NullPointerException e)
+ {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f2985d50/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/MyPartialBeanBinding.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/MyPartialBeanBinding.java b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/MyPartialBeanBinding.java
new file mode 100644
index 0000000..1f73a27
--- /dev/null
+++ b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/MyPartialBeanBinding.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.deltaspike.test.core.api.partialbean.uc012;
+
+import org.apache.deltaspike.partialbean.api.PartialBeanBinding;
+
+import java.lang.annotation.Retention;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@PartialBeanBinding
+@Retention(RUNTIME)
+public @interface MyPartialBeanBinding
+{
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f2985d50/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/MyPartialBeanHandler.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/MyPartialBeanHandler.java b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/MyPartialBeanHandler.java
new file mode 100644
index 0000000..fdd11c1
--- /dev/null
+++ b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/MyPartialBeanHandler.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.deltaspike.test.core.api.partialbean.uc012;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+@MyPartialBeanBinding
+public class MyPartialBeanHandler implements InvocationHandler
+{
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ return method.getName();
+ }
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f2985d50/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/PartialBean.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/PartialBean.java b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/PartialBean.java
new file mode 100644
index 0000000..7a6f3ea
--- /dev/null
+++ b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/PartialBean.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.deltaspike.test.core.api.partialbean.uc012;
+
+import javax.enterprise.context.ApplicationScoped;
+
+@MyPartialBeanBinding
+@ApplicationScoped
+public interface PartialBean
+{
+ String getValue();
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f2985d50/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/AbstractManualInvocationHandler.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/AbstractManualInvocationHandler.java b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/AbstractManualInvocationHandler.java
index 92bfc3c..03fcbd2 100644
--- a/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/AbstractManualInvocationHandler.java
+++ b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/AbstractManualInvocationHandler.java
@@ -18,22 +18,20 @@
*/
package org.apache.deltaspike.proxy.impl.invocation;
+import javax.enterprise.inject.spi.Interceptor;
+import javax.inject.Inject;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.List;
-import javax.enterprise.inject.spi.Interceptor;
-import org.apache.deltaspike.core.api.provider.BeanProvider;
public abstract class AbstractManualInvocationHandler implements InvocationHandler
{
- private volatile Boolean initialized;
+ @Inject
private InterceptorLookup interceptorLookup;
-
+
@Override
public Object invoke(Object proxy, Method method, Object[] parameters) throws Throwable
{
- lazyInit();
-
// check if interceptors are defined, otherwise just call the original logik
List<Interceptor<?>> interceptors = interceptorLookup.lookup(proxy, method);
if (interceptors != null && !interceptors.isEmpty())
@@ -41,7 +39,7 @@ public abstract class AbstractManualInvocationHandler implements InvocationHandl
try
{
ManualInvocationContext invocationContext =
- new ManualInvocationContext(this, interceptors, proxy, method, parameters, null);
+ new ManualInvocationContext(this, interceptors, proxy, method, parameters, null);
Object returnValue = invocationContext.proceed();
@@ -63,33 +61,12 @@ public abstract class AbstractManualInvocationHandler implements InvocationHandl
/**
* Calls the original logic after invoking the interceptor chain.
- *
+ *
* @param proxy The current proxy instance.
* @param method The current invoked method.
* @param parameters The method parameter.
* @return The original value from the original method.
- * @throws Throwable
+ * @throws Throwable
*/
protected abstract Object proceedOriginal(Object proxy, Method method, Object[] parameters) throws Throwable;
-
-
-
- private void lazyInit()
- {
- if (this.initialized == null)
- {
- init();
- }
- }
-
- private synchronized void init()
- {
- // switch into paranoia mode
- if (this.initialized == null)
- {
- this.initialized = true;
-
- this.interceptorLookup = BeanProvider.getContextualReference(InterceptorLookup.class);
- }
- }
}