You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by ta...@apache.org on 2014/04/09 21:58:35 UTC

git commit: DELTASPIKE-559 ExceptionHandler lifecycle isn't thread safe

Repository: deltaspike
Updated Branches:
  refs/heads/master ccac36f2f -> fdaf798aa


DELTASPIKE-559 ExceptionHandler lifecycle isn't thread safe

Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/fdaf798a
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/fdaf798a
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/fdaf798a

Branch: refs/heads/master
Commit: fdaf798aa30f0f473dbed77cbfa5d28a96766390
Parents: ccac36f
Author: tandraschko <ta...@apache.org>
Authored: Wed Apr 9 21:58:17 2014 +0200
Committer: tandraschko <ta...@apache.org>
Committed: Wed Apr 9 21:58:17 2014 +0200

----------------------------------------------------------------------
 .../exception/DeltaSpikeExceptionHandler.java   | 136 -------------------
 .../DeltaSpikeExceptionHandlerFactory.java      |  46 -------
 .../control/BridgeExceptionHandlerWrapper.java  | 104 ++++++++++++++
 .../request/DeltaSpikeFacesContextWrapper.java  |  17 +++
 .../main/resources/META-INF/faces-config.xml    |   1 -
 5 files changed, 121 insertions(+), 183 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fdaf798a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/DeltaSpikeExceptionHandler.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/DeltaSpikeExceptionHandler.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/DeltaSpikeExceptionHandler.java
deleted file mode 100644
index 360655a..0000000
--- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/DeltaSpikeExceptionHandler.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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.jsf.impl.exception;
-
-import java.lang.annotation.Annotation;
-import java.util.Iterator;
-import javax.el.ELException;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.faces.FacesException;
-import javax.faces.context.ExceptionHandler;
-import javax.faces.context.ExceptionHandlerWrapper;
-import javax.faces.context.FacesContext;
-import javax.faces.event.ExceptionQueuedEvent;
-import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent;
-import org.apache.deltaspike.core.api.provider.BeanManagerProvider;
-import org.apache.deltaspike.core.api.provider.BeanProvider;
-import org.apache.deltaspike.core.spi.activation.Deactivatable;
-import org.apache.deltaspike.core.util.ClassDeactivationUtils;
-import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider;
-import org.apache.deltaspike.jsf.api.config.JsfModuleConfig;
-
-public class DeltaSpikeExceptionHandler extends ExceptionHandlerWrapper implements Deactivatable
-{
-    private final ExceptionHandler wrapped;
-
-    private volatile Boolean initialized;
-    
-    private Annotation exceptionQualifier;
-    private boolean isActivated = true;
-
-    public DeltaSpikeExceptionHandler(ExceptionHandler wrapped)
-    {
-        this.isActivated = ClassDeactivationUtils.isActivated(getClass());
-        this.wrapped = wrapped;
-    }
-
-    @Override
-    public ExceptionHandler getWrapped()
-    {
-        return wrapped;
-    }
-
-    @Override
-    public void handle() throws FacesException
-    {
-        if (isActivated)
-        {
-            lazyInit();
-            
-            FacesContext context = FacesContext.getCurrentInstance();
-
-            if (context.getResponseComplete())
-            {
-                return;
-            }
-
-            Iterable<ExceptionQueuedEvent> exceptionQueuedEvents = getUnhandledExceptionQueuedEvents();
-            if (exceptionQueuedEvents != null && exceptionQueuedEvents.iterator() != null)
-            {
-                Iterator<ExceptionQueuedEvent> iterator = exceptionQueuedEvents.iterator();
-
-                BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager();
-
-                while (iterator.hasNext())
-                {
-                    Throwable throwable = iterator.next().getContext().getException();
-                    Throwable rootCause = getRootCause(throwable);
-
-                    ExceptionToCatchEvent event = new ExceptionToCatchEvent(rootCause, exceptionQualifier);
-
-                    beanManager.fireEvent(event);
-
-                    if (event.isHandled())
-                    {
-                        iterator.remove();
-                    }
-
-                    // a handle method might redirect and set responseComplete
-                    if (context.getResponseComplete())
-                    {
-                        break;
-                    }
-                }
-            }
-        }
-
-        super.handle();
-    }
-
-    @Override
-    public Throwable getRootCause(Throwable throwable)
-    {
-        while ((ELException.class.isInstance(throwable) || FacesException.class.isInstance(throwable))
-                && throwable.getCause() != null)
-        {
-            throwable = throwable.getCause();
-        }
-
-        return throwable;
-    }
-
-    private void lazyInit()
-    {
-        if (this.initialized == null)
-        {
-            init();
-        }
-    }
-
-    private synchronized void init()
-    {
-        if (this.initialized == null)
-        {
-            this.exceptionQualifier = AnnotationInstanceProvider.of(
-                    BeanProvider.getContextualReference(JsfModuleConfig.class).getExceptionQualifier());
-
-            this.initialized = true;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fdaf798a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/DeltaSpikeExceptionHandlerFactory.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/DeltaSpikeExceptionHandlerFactory.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/DeltaSpikeExceptionHandlerFactory.java
deleted file mode 100644
index c105648..0000000
--- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/DeltaSpikeExceptionHandlerFactory.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.jsf.impl.exception;
-
-import javax.faces.context.ExceptionHandler;
-import javax.faces.context.ExceptionHandlerFactory;
-
-public class DeltaSpikeExceptionHandlerFactory extends ExceptionHandlerFactory
-{
-    private final ExceptionHandlerFactory wrapped;
-    private final DeltaSpikeExceptionHandler handler;
-
-    public DeltaSpikeExceptionHandlerFactory(final ExceptionHandlerFactory wrapped)
-    {
-        this.wrapped = wrapped;
-        this.handler = new DeltaSpikeExceptionHandler(wrapped.getExceptionHandler());
-    }
-
-    @Override
-    public ExceptionHandler getExceptionHandler()
-    {
-        return handler;
-    }
-
-    @Override
-    public ExceptionHandlerFactory getWrapped()
-    {
-        return wrapped;
-    }
-}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fdaf798a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/control/BridgeExceptionHandlerWrapper.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/control/BridgeExceptionHandlerWrapper.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/control/BridgeExceptionHandlerWrapper.java
new file mode 100644
index 0000000..7cc4bb0
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/control/BridgeExceptionHandlerWrapper.java
@@ -0,0 +1,104 @@
+/*
+ * 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.jsf.impl.exception.control;
+
+import java.lang.annotation.Annotation;
+import java.util.Iterator;
+import javax.el.ELException;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.faces.FacesException;
+import javax.faces.context.ExceptionHandler;
+import javax.faces.context.ExceptionHandlerWrapper;
+import javax.faces.context.FacesContext;
+import javax.faces.event.ExceptionQueuedEvent;
+import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent;
+import org.apache.deltaspike.core.api.provider.BeanManagerProvider;
+import org.apache.deltaspike.core.spi.activation.Deactivatable;
+
+public class BridgeExceptionHandlerWrapper extends ExceptionHandlerWrapper implements Deactivatable
+{
+    private final ExceptionHandler wrapped;
+    private final Annotation exceptionQualifier;
+
+    public BridgeExceptionHandlerWrapper(ExceptionHandler wrapped, Annotation exceptionQualifier)
+    {
+        this.wrapped = wrapped;
+        this.exceptionQualifier = exceptionQualifier;
+    }
+
+    @Override
+    public ExceptionHandler getWrapped()
+    {
+        return wrapped;
+    }
+
+    @Override
+    public void handle() throws FacesException
+    {
+        FacesContext context = FacesContext.getCurrentInstance();
+
+        if (context.getResponseComplete())
+        {
+            return;
+        }
+
+        Iterable<ExceptionQueuedEvent> exceptionQueuedEvents = getUnhandledExceptionQueuedEvents();
+        if (exceptionQueuedEvents != null && exceptionQueuedEvents.iterator() != null)
+        {
+            Iterator<ExceptionQueuedEvent> iterator = exceptionQueuedEvents.iterator();
+
+            BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager();
+
+            while (iterator.hasNext())
+            {
+                Throwable throwable = iterator.next().getContext().getException();
+                Throwable rootCause = getRootCause(throwable);
+
+                ExceptionToCatchEvent event = new ExceptionToCatchEvent(rootCause, exceptionQualifier);
+
+                beanManager.fireEvent(event);
+
+                if (event.isHandled())
+                {
+                    iterator.remove();
+                }
+
+                // a handle method might redirect and set responseComplete
+                if (context.getResponseComplete())
+                {
+                    break;
+                }
+            }
+        }
+
+        super.handle();
+    }
+
+    @Override
+    public Throwable getRootCause(Throwable throwable)
+    {
+        while ((ELException.class.isInstance(throwable) || FacesException.class.isInstance(throwable))
+                && throwable.getCause() != null)
+        {
+            throwable = throwable.getCause();
+        }
+
+        return throwable;
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fdaf798a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeFacesContextWrapper.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeFacesContextWrapper.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeFacesContextWrapper.java
index 18d5e72..83be4be 100644
--- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeFacesContextWrapper.java
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeFacesContextWrapper.java
@@ -18,6 +18,7 @@
  */
 package org.apache.deltaspike.jsf.impl.listener.request;
 
+import java.lang.annotation.Annotation;
 import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver;
 import org.apache.deltaspike.core.api.provider.BeanProvider;
 import org.apache.deltaspike.core.util.ClassDeactivationUtils;
@@ -35,6 +36,8 @@ import javax.faces.context.FacesContextWrapper;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CopyOnWriteArrayList;
+import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider;
+import org.apache.deltaspike.jsf.impl.exception.control.BridgeExceptionHandlerWrapper;
 
 import org.apache.deltaspike.jsf.impl.security.SecurityAwareViewHandler;
 import org.apache.deltaspike.jsf.spi.scope.window.ClientWindow;
@@ -47,6 +50,9 @@ class DeltaSpikeFacesContextWrapper extends FacesContextWrapper
 
     private boolean defaultErrorViewExceptionHandlerActivated;
 
+    private boolean bridgeExceptionHandlerActivated;
+    private Annotation bridgeExceptionQualifier;
+
     private ExternalContext wrappedExternalContext;
 
     private JsfModuleConfig jsfModuleConfig;
@@ -94,10 +100,16 @@ class DeltaSpikeFacesContextWrapper extends FacesContextWrapper
 
         ExceptionHandler exceptionHandler = this.wrappedFacesContext.getExceptionHandler();
 
+        if (this.bridgeExceptionHandlerActivated)
+        {
+            exceptionHandler = new BridgeExceptionHandlerWrapper(exceptionHandler, this.bridgeExceptionQualifier);
+        }
+        
         if (this.defaultErrorViewExceptionHandlerActivated)
         {
             exceptionHandler = new DefaultErrorViewAwareExceptionHandlerWrapper(exceptionHandler);
         }
+
         return exceptionHandler;
     }
 
@@ -137,6 +149,11 @@ class DeltaSpikeFacesContextWrapper extends FacesContextWrapper
             this.defaultErrorViewExceptionHandlerActivated =
                     viewConfigResolver.getDefaultErrorViewConfigDescriptor() != null &&
                             ClassDeactivationUtils.isActivated(DefaultErrorViewAwareExceptionHandlerWrapper.class);
+            
+            this.bridgeExceptionHandlerActivated =
+                    ClassDeactivationUtils.isActivated(BridgeExceptionHandlerWrapper.class);
+            
+            this.bridgeExceptionQualifier = AnnotationInstanceProvider.of(jsfModuleConfig.getExceptionQualifier());
 
             this.preDestroyViewMapEventFilterMode = ClassDeactivationUtils.isActivated(SecurityAwareViewHandler.class);
             this.initialized = true;

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fdaf798a/deltaspike/modules/jsf/impl/src/main/resources/META-INF/faces-config.xml
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/resources/META-INF/faces-config.xml b/deltaspike/modules/jsf/impl/src/main/resources/META-INF/faces-config.xml
index b06e277..fbebb8f 100644
--- a/deltaspike/modules/jsf/impl/src/main/resources/META-INF/faces-config.xml
+++ b/deltaspike/modules/jsf/impl/src/main/resources/META-INF/faces-config.xml
@@ -49,7 +49,6 @@
     </application>
 
     <factory>
-        <exception-handler-factory>org.apache.deltaspike.jsf.impl.exception.DeltaSpikeExceptionHandlerFactory</exception-handler-factory>
         <lifecycle-factory>org.apache.deltaspike.jsf.impl.listener.request.DeltaSpikeLifecycleFactoryWrapper</lifecycle-factory>
         <faces-context-factory>org.apache.deltaspike.jsf.impl.listener.request.DeltaSpikeFacesContextFactory</faces-context-factory>
     </factory>