JSF 404 statt 500 bei nicht existenter JSF-Seite

xehpuk

Top Contributor
Hi,

ich nutze GlassFish 3.1.2 mit Mojarra 2.1.6.

Ruft man eine nicht existente JSF-Seite auf (etwa http://localhost:8080/Test/.jsf), tritt serverseitig eine Exception auf und es wird HTTP 500 zurückgegeben:
Java:
Schwerwiegend: PWC6117: File "…\Test\build\web\.jsp" not found
Warnung: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.NullPointerException
	at com.sun.faces.context.flash.ELFlash.doLastPhaseActions(ELFlash.java:607)
	at com.sun.faces.context.ExternalContextImpl.responseFlushBuffer(ExternalContextImpl.java:857)
	at com.sun.faces.application.view.JspViewHandlingStrategy.buildView(JspViewHandlingStrategy.java:155)
	at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:100)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
	at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
	at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
	at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
	at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
	at java.lang.Thread.run(Thread.java:722)
  1. Kann man verhindern, dass diese Exception fliegt?
  2. Wenn nicht, wie macht man aus dieser speziellen Exception ein HTTP 404 (sodass auf die ggf. vorhandene Fehlerseite weitergeleitet wird)?
Sowas in der web.xml wäre ja Quatsch (zumal es ein HTTP 500 bleibt):
[XML]<error-page>
<exception-type>java.lang.NullPointerException</exception-type>
<location>/error/404.jsf</location>
</error-page>[/XML]

Die gleiche Frage habe ich auch auf Stackoverflow gefunden, diese blieb jedoch unbeantwortet.
 

brauner1990

Bekanntes Mitglied
Eine mögliche Lösung bestände darin einen ExceptionListener einzubinden, der je nach Ex konfiguriert wird und dementsprechend weiterleitet
 

xehpuk

Top Contributor
Ich konnte jetzt nicht herausfinden, was ein ExceptionListener ist.

Mittlerweile denke ich, dass es sich hierbei um einen Bug handelt. Bei einem neuen Projekt tritt dieser Fehler nicht auf. Es wird dort korrekterweise die Standardfehlerseite für 404 angezeigt.

Folgendermaßen lässt sich der Fehler reproduzieren:

Ein neues JSF-Projekt erstellen.

Eine JSF-Seite index.xhtml erstellen:
[XML]<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<head>
<title>Index</title>
</head>
<body>
<h:eek:utputText value="#{requestScope['javax.servlet.error.request_uri']}"/>
</body>
</html>[/XML]
Die individuelle 404-Fehlerseite in der web.xml eintragen:
[XML]<?xml version='1.0' encoding='UTF-8'?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsf</welcome-file>
</welcome-file-list>
<error-page>
<error-code>404</error-code>
<location>/index.jsf</location>
</error-page>
</web-app>[/XML]
Irgendeine URL mit der Endung .jsf (außer natürlich index.jsf) anfordern.

Der im Eingangsbeitrag genannte Fehler tritt auf. Beim Aufruf nicht existenter Seiten (ohne Endung .jsf) wird die individuelle Fehlerseite korrekt angezeigt.

Ich forsche da noch ein wenig weiter.
 
N

nillehammer

Gast
Kenne mich mit JSF überhaupt nicht aus, aber wenn ich mir das so anschaue, muss es am FacesServlet liegen. Bei allen anderen URLs findet der Webcontainer keine passende Resource und antwortet korrekt mit 404 Not Found.

Alles mit *.jsf wird wegen des das servlet-mapping in der web.xml ans FacesServlet geleitet. Dieses findet nun keine passende Resource und antwortet mit 500 Internal Server Error. Aber JSF ist ja sooo schlecht nicht. Ich bin sicher, dass man das auch irgendwie konfigurieren kann. Aber kenne mich wie gesagt nicht damit aus. Das deswegen nur als Tipp, in welcher Richtung Du suchen könntest.
 

Fant

Bekanntes Mitglied
Es ist normal, dass Mojara eine 500er-Meldung schmeißt, jedoch sollte aber eigentlich eine FacesFileNotFoundException geworfen werden.

Komischerweise läuft bei mir mit dem mapping auf /faces/* alles wie erwartet. Ändere ich mein mapping auf *.jsf, wie du es hast, dann hab ich das gleiche Problem und die gleiche merkwürdige Fehlermeldung, die du da bekommst.

Wenn du mit dem alternativen mapping leben kannst, dann kannst du die "richtige 500er"-Meldung natürlich abfangen und auf deine 404er-page umleiten. Ich sehe nicht wirklich einen Grund der dagegen spricht ... mal davon abgesehen, dass ich auch keine andere Lösung kenne.

HTML:
<error-page>
  <exception-type>java.io.FileNotFoundException</exception-type>
  <location>....</location>
</error-page>
 

xehpuk

Top Contributor
Bin auch Laie und eigne mir das Zeug nach und nach an. Wusste daher nun auch wenig damit anzufangen, aber bei mir verstärkt sich doch stark der Gedanke, dass es sich hier um einen Bug handeln muss.

Ich finde dieses alternative Mapping ziemlich hässlich, daher würde ich gern darauf verzichten. Darum teste ich damit erst mal nicht weiter.

Der Fehler scheint nicht bei Mojarra, sondern bei GlassFish zu liegen. Mit Tomcat und Mojarra funktioniert es (liefert brav 404 auch bei der Endung .jsf).

Ich habe den Stacktrace anhand des Sourcecodes ein wenig zurückverfolgt:
Java:
public class ELFlash extends Flash {
    // ...
    public void doLastPhaseActions(FacesContext context, boolean outgoingResponseIsRedirect) {
        ExternalContext extContext = context.getExternalContext(); // <--- NPE, also context == null
        // ...
    }
    // ...
}
Java:
public class ExternalContextImpl extends ExternalContext {
    // ...
    public void responseFlushBuffer() throws IOException {
        getELFlash().doLastPhaseActions(FacesContext.getCurrentInstance() /* == null */, false);
        // ...
    }
    // ...
}
Java:
public abstract class FacesContext {
    // ...
    public static FacesContext getCurrentInstance() {
        FacesContext facesContext = instance.get(); // == null
        if (null == facesContext) {
            facesContext = (FacesContext) threadInitContext.get(Thread.currentThread()); // == null
        }
        return facesContext; // == null
    }
    // ...
}
Von der Materie habe ich wie gesagt nicht viel Ahnung, aber gehe nun davon aus, dass es die Aufgabe des Servers ist, dort immer eine Instanz von FacesContext bereitzustellen.

Ich durchforste nachher mal den Bugtracker von GlassFish. Vielleicht werde ich ja fündig. Für mich wäre das jetzt schon Grund genug, es mit einem anderen Server zu probieren.
 

xehpuk

Top Contributor
Okay, mein Hackaround sieht dann so aus:

GlassFishNullPointerExceptionHandler.java
Java:
import java.util.Iterator;
import javax.faces.FacesException;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;

public class GlassFishNullPointerExceptionHandler extends ExceptionHandlerWrapper {
	private final ExceptionHandler wrapped;

	public GlassFishNullPointerExceptionHandler(final ExceptionHandler wrapped) {
		this.wrapped = wrapped;
	}

	@Override
	public ExceptionHandler getWrapped() {
		return wrapped;
	}

	@Override
	public void handle() throws FacesException {
		for (final Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
			final ExceptionQueuedEvent event = i.next();
			final ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
			final Throwable t = context.getException();
			if (t instanceof NullPointerException) {
				final StackTraceElement[] stackTrace = t.getStackTrace();
				final StackTraceElement lastCall = stackTrace[0];
				if ("com.sun.faces.context.flash.ELFlash".equals(lastCall.getClassName()) &&
						"doLastPhaseActions".equals(lastCall.getMethodName())) {
					i.remove(); // Suck it!
				}
			}
		}
		getWrapped().handle();
	}
}
GlassFishNullPointerExceptionHandlerFactory.java
Java:
import javax.faces.context.ExceptionHandlerFactory;

public class GlassFishNullPointerExceptionHandlerFactory extends ExceptionHandlerFactory {
	private final ExceptionHandlerFactory parent;

	public GlassFishNullPointerExceptionHandlerFactory(final ExceptionHandlerFactory parent) {
		this.parent = parent;
	}

	@Override
	public ExceptionHandlerFactory getWrapped() {
		return parent;
	}

	@Override
	public GlassFishNullPointerExceptionHandler getExceptionHandler() {
		return new GlassFishNullPointerExceptionHandler(getWrapped().getExceptionHandler());
	}
}
faces-config.xml
[XML]<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.1"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd">
<factory>
<exception-handler-factory>
[packages]GlassFishNullPointerExceptionHandlerFactory
</exception-handler-factory>
</factory>
</faces-config>[/XML]
Eine unglaublich edle Lösung! :D

Die individuelle 404-Fehlerseite wird nun mit korrektem HTTP-Code zurückgegeben.
Ändert natürlich nichts daran, dass das totaler Käse ist. Den Bugtracker muss ich noch immer konsultieren …
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
OnDemand API output Wert, statt ID Web Tier 19
x22 Autocomplete statt Drop Down Web Tier 3
D "meineseite.de/user" statt "meineseite.de/index.jsp?site=user" Web Tier 2
R GWT 2.1.1 mit Java 1.6 statt 1.5 Web Tier 8
G JSF: .xhtml statt .jsf? Web Tier 2
D Codierung im Frontend funktioniert nicht richtig Web Tier 2
hjpsoft JSP <TEXTAREA>-Tag unterstützt EL-Variablen nicht Web Tier 7
krgewb Base64 funktioniert nicht, aber btoa funktioniert Web Tier 10
6 JSF Form Attribute nicht an Bean übergeben Web Tier 2
C JSP data wird nicht angezeigt Web Tier 6
M webapp controller funktioniert nicht Web Tier 3
Psypsy Spring Thymeleaf Layer werden nicht angezeigt. Web Tier 0
J Https Verknüpfung funktioniert nicht Web Tier 0
P JSF (Primefaces) SelectOneMenu Value auf Array wird nicht gesetzt Web Tier 0
K Vaadin Projekt Funkioniert nicht... Web Tier 1
M JSP PrimeFaces LayoutUnits <- breite lässt sich nicht erzwingen wenn 'center' Web Tier 0
R JSF selectOneListbox speichert Value nicht. Web Tier 1
W Tabelle wird nicht aktualisiert Web Tier 8
W JSF DataTable - Filter Funktion funktioniert nicht Web Tier 3
A JSF String wird nicht angezeigt Web Tier 2
S JSF CSS wird gefunden aber inhaltlich nicht angewendet Web Tier 2
FINF_AW_Alex EJB - property nicht vorhanden Web Tier 6
R JSF Bilder aus CSS Datei werden nicht angezeigt. Web Tier 2
F JSF Bean funktioniert nicht immer.. Web Tier 3
C JSF JSF Daten aus Klasse werden nicht angezeigt Web Tier 4
F JSF h:selectOneMenu Wert vorbelegen klappt nicht? Web Tier 2
R JSF ManagedProperty wird nicht erstellt Web Tier 1
H JSF jsf/sessionScoped Bean - Bilder (jpg) werden nicht richtig dargestellt Web Tier 1
L error-page mit ui:composite funktioniert nicht Web Tier 0
S Primefaces commandButton in einem Dialog/Form/PanelGrid führt actionListener nicht aus Web Tier 4
A Faces Context nicht mehr erreichbar nach Servlet Aufruf Web Tier 1
D JSF DataTable konvertiert Felder nicht Web Tier 1
G JSF Radio Button ValueChangeListener Wert wird nicht übernommen Web Tier 2
L JSF Composit Component mit ajax funktioniert nicht. Web Tier 4
M fileUploadListener geht nicht wenn Element zur Laufzeit gerendert wird Web Tier 2
Phash Link geht nicht Web Tier 4
S setInterval() will nicht Web Tier 2
A Aufruf eines Servlets auf einer JSP Seite funktioniert nicht Web Tier 10
B JSP Warum nicht ThreadSafe? Web Tier 21
G GWT 404 - Servlet nicht gefunden Web Tier 6
H Servlet lässt sich nicht deployen Web Tier 7
M rendered ruft eine Methode auf, andere aber nicht Web Tier 15
M System-Event in der faces-config.xml klappt nicht Web Tier 15
J JSF BigInteger nicht null sondern 0 Web Tier 3
nrg Java-Code in Taglib wird nicht richtig ausgeführt. Web Tier 7
F JSF CSS Verschachtelung wird nicht abgebildet Web Tier 2
F.S.WhiTeY Servlet Servlet wird nicht angesprochen Web Tier 3
D JSF a4j:support wird nicht gefunden Web Tier 2
D JSF cellpadding oder cellspacing funktioniert nicht Web Tier 4
W JSF Login funktioniert nicht Web Tier 12
K Neue Entitäten werde nicht angezeigt Web Tier 4
F PrimeFaces p:selectOneMenu funktioniert nicht Web Tier 12
H JSP, Eclipse, Tomcat - Java Klasse wird nicht gefunden Web Tier 8
A JSF WebappClassloader.modified() aktualisiert Klassen nicht Web Tier 2
A JSF Rücksicht auf nicht eingeschaltetes JavaScript nehmen Web Tier 2
T JSF wird nicht ausgeführt Web Tier 4
R RadioButton nicht disabled Web Tier 5
J @Named Notation funktioniert nicht Web Tier 3
aze JSF CommandButton:Action wird nicht ausgeführt Web Tier 2
P JSF Netbeans 7.1.1 unterstützt JSF nicht? Web Tier 2
T RichFaces will nicht funktionieren :( Web Tier 2
L Applet kann unter WEB-INF/classes nicht gefunden werden Web Tier 10
H JSF ActionListener wird ausgeführt, aber ändert den Wert nicht. Web Tier 7
R JSF Beans werden nicht ausgeführt Web Tier 4
D richTable sort funktioniert nicht Web Tier 2
L JSF Beispiel wird nicht ausgeführt Web Tier 2
D Fehler: Cookies nicht gesetzt Web Tier 5
A Servlet File Upload funktioniert nur lokal auf Entwicklungsrechner, nicht in Tomcat Web Tier 5
Dit_ JSP Überprüfen ob Benutzer eingeloggt ist oder nicht | SessionSicherheit Web Tier 7
M JSF Button - Methode wird nicht aufgerufen Web Tier 4
L einfache JSF-Seite wird nicht angezeigt Web Tier 8
B JSF HtmlCommandButton --- Action wird nicht aufgerufen Web Tier 2
N JSF [Maven] Seam 2.2, Richfaces 3.3 - a4j wird nicht umgewandelt Web Tier 6
NoXiD JSF h:selectOneMenu - änderungen nicht übernommen Web Tier 14
C JSON-Antwort an Javascript geht nicht Web Tier 7
H Servlet Apache Geronimo: Servlet nicht erreichbar Web Tier 2
P JSF AJAX render wird nicht ausgeführt Web Tier 4
P SelectOneMenu liest Daten nicht ein Web Tier 7
E JSF JSF findet Property im ManagedBean nicht Web Tier 5
J JSF Richfaces Tabs, dynamisches include funktioniert nicht Web Tier 4
P Servlet wird nicht gefunden - HTTP Error 503 Web Tier 7
S JSF Primefaces Thema, Css wird geladen, nur die Bilder nicht, bzw Resource wird nicht aufgelöst Web Tier 5
D Fileupload in GWT funktioniert nicht Web Tier 10
B JSF Login authentication schaffe ich nicht Web Tier 2
P Eclipse zeigt Errors an, die auf Tomcat nicht auftreten Web Tier 2
F Property nicht gefunden (trotz getter und setter) Web Tier 3
B JSF Servlectexception: Verwalteter Bean "..bean" kann nicht erstellt werden Web Tier 2
C JSF JSF 2 - Anwendung lädt nicht Web Tier 4
S JSP lässt sich nicht ausführen Web Tier 2
I JSF Daten aus Formular werden nicht übernommen Web Tier 6
F Property in ManagedBean nicht gefunden? Web Tier 3
T JSF @ManagedBean nicht erkannt Web Tier 3
A JSF Weiterleitung funktioniert einfach nicht Web Tier 2
R Message Bundles werden nicht geladen Web Tier 2
J JSF JSF2.0 template wird nicht gerendert!? Web Tier 2
D [GWT] Celltable SimplePager funktioniert in 2.2 nicht Web Tier 1
T JSF Dependency-Injection funktioniert offenbar nicht - warum? Web Tier 4
D JSP Programm geht einfach nicht in If-Schleife rein Web Tier 7
J JSP-Seite kann nicht aufgerufen werden Web Tier 14
S Bean Validation (JSF 2.0) funktioniert nicht. Web Tier 4

Ähnliche Java Themen

Neue Themen


Oben