Return-Path: X-Original-To: apmail-deltaspike-commits-archive@www.apache.org Delivered-To: apmail-deltaspike-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 2AD9611B9C for ; Wed, 9 Apr 2014 19:58:42 +0000 (UTC) Received: (qmail 34980 invoked by uid 500); 9 Apr 2014 19:58:41 -0000 Delivered-To: apmail-deltaspike-commits-archive@deltaspike.apache.org Received: (qmail 34919 invoked by uid 500); 9 Apr 2014 19:58:36 -0000 Mailing-List: contact commits-help@deltaspike.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@deltaspike.apache.org Delivered-To: mailing list commits@deltaspike.apache.org Received: (qmail 34906 invoked by uid 99); 9 Apr 2014 19:58:35 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 09 Apr 2014 19:58:35 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 65C9294FB98; Wed, 9 Apr 2014 19:58:35 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: tandraschko@apache.org To: commits@deltaspike.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: git commit: DELTASPIKE-559 ExceptionHandler lifecycle isn't thread safe Date: Wed, 9 Apr 2014 19:58:35 +0000 (UTC) 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 Authored: Wed Apr 9 21:58:17 2014 +0200 Committer: tandraschko 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 exceptionQueuedEvents = getUnhandledExceptionQueuedEvents(); - if (exceptionQueuedEvents != null && exceptionQueuedEvents.iterator() != null) - { - Iterator 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 exceptionQueuedEvents = getUnhandledExceptionQueuedEvents(); + if (exceptionQueuedEvents != null && exceptionQueuedEvents.iterator() != null) + { + Iterator 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 @@ - org.apache.deltaspike.jsf.impl.exception.DeltaSpikeExceptionHandlerFactory org.apache.deltaspike.jsf.impl.listener.request.DeltaSpikeLifecycleFactoryWrapper org.apache.deltaspike.jsf.impl.listener.request.DeltaSpikeFacesContextFactory