JSF: ViewExpiredException kann nicht abgefangen werden

Ich entwickle eine JSF 2.0-Anwendung auf Glassfish v3 und versuche, die ViewExpiredException zu behandeln. Aber was auch immer ich tue, ich bekomme immer einen Glassfish-Fehlerbericht anstatt meiner eigenen Fehlerseite.

Um das Auftreten der VEE zu simulieren, habe ich die folgende Funktion in meine Backing Bean eingefügt, die die VEE auslöst. Ich starte diese Funktion von meiner JSF-Seite über einen CommandLink. Der Code

@Named
public class PersonHome {
  (...)
  public void throwVEE() {
    throw new ViewExpiredException();
  }
}

Zuerst habe ich es versucht, indem ich einfach eine Fehlerseite zu meiner web.xml hinzugefügt habe:

<error-page>
  <exception-type>javax.faces.application.ViewExpiredException</exception-type>
  <location>/error.xhtml</location>
</error-page>  

Aber dies funktioniert nicht, ich werde nicht zum Fehler weitergeleitet, aber es wird die Glassfish-Fehlerseite angezeigt, auf der eine HTTP-Status 500-Seite mit folgendem Inhalt angezeigt wird:

description:The server encountered an internal error () that prevented it from fulfilling this request.
exception: javax.servlet.ServletException: javax.faces.application.ViewExpiredException
root cause: javax.faces.el.EvaluationException:javax.faces.application.ViewExpiredException
root cause:javax.faces.application.ViewExpiredException

Nächst habe ich versucht, ExceptionHandlerFactory und einen CustomExceptionHandler zu schreiben, wie in @ beschriebeJavaServerFaces 2.0 - Die komplette Referenz. Also habe ich das folgende Tag in faces-config.xml eingefügt:

<factory>
  <exception-handler-factory>
    exceptions.ExceptionHandlerFactory
  </exception-handler-factory>
</factory>

Und fügte diese Klassen hinzu: Die Fabrik:

package exceptions;

import javax.faces.context.ExceptionHandler;

public class ExceptionHandlerFactory extends javax.faces.context.ExceptionHandlerFactory {

    private javax.faces.context.ExceptionHandlerFactory parent;

    public ExceptionHandlerFactory(javax.faces.context.ExceptionHandlerFactory parent) {
        this.parent = parent;
    }

    @Override
    public ExceptionHandler getExceptionHandler() {
        ExceptionHandler result = parent.getExceptionHandler();
        result = new CustomExceptionHandler(result);
        return result;
    }

}

Die benutzerdefinierte Ausnahmebehandlung:

package exceptions;

import java.util.Iterator;

import javax.faces.FacesException;
import javax.faces.application.NavigationHandler;
import javax.faces.application.ViewExpiredException;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.context.FacesContext;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;

class CustomExceptionHandler extends ExceptionHandlerWrapper {

    private ExceptionHandler parent;

    public CustomExceptionHandler(ExceptionHandler parent) {
        this.parent = parent;
    }

    @Override
    public ExceptionHandler getWrapped() {
        return this.parent;
    }

    @Override
    public void handle() throws FacesException {
        for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
            ExceptionQueuedEvent event = i.next();
            System.out.println("Iterating over ExceptionQueuedEvents. Current:" + event.toString());
            ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
            Throwable t = context.getException();
            if (t instanceof ViewExpiredException) {
                ViewExpiredException vee = (ViewExpiredException) t;
                FacesContext fc = FacesContext.getCurrentInstance();

                NavigationHandler nav =
                        fc.getApplication().getNavigationHandler();
                try {
                    // Push some useful stuff to the flash scope for
                    // use in the page
                    fc.getExternalContext().getFlash().put("expiredViewId", vee.getViewId());

                    nav.handleNavigation(fc, null, "/login?faces-redirect=true");
                    fc.renderResponse();

                } finally {
                    i.remove();
                }
            }
        }
        // At this point, the queue will not contain any ViewExpiredEvents.
        // Therefore, let the parent handle them.
        getWrapped().handle();
    }
}

ABER NOCH, ich werde NICHT auf meine Fehlerseite umgeleitet - ich erhalte den gleichen HTTP 500-Fehler wie oben. Was mache ich falsch, was könnte in meiner Implementierung fehlen, dass die Ausnahme nicht richtig behandelt wird?Irgendei Hilfe sehr geschätzt!

BEARBEITE

Ok, ich bin ehrlich. Eigentlich ist mein Code in Scala geschrieben, aber das ist eine lange Geschichte. Ich dachte, es sei die ganze Zeit ein Java-Problem. Der WIRKLICHE Fehler in diesem Fall war meine eigene Dummheit. In meinem (Scala) Code habe ich in CustomExceptionHandler vergessen, die Zeile mit dem "i.remove ();" Die ViewExpiredException blieb also nach der Bearbeitung in der UnhandledExceptionsQueue und "sprudelte". Und wenn es explodiert, wird es zu einer ServletException.

Es tut mir wirklich leid, dass ich euch beide verwirrt habe!