# JSF - NavigationRule funktioniert nicht



## megachucky (10. Feb 2009)

Hallo.

Ich habe zwei JSPs und möchte über die faces-config und einen Button die Daten der Bean übergeben. Leider komme ich beim Klick auf den Button wieder nur auf die Startseite und http://localhost:8080/jsf//MyJsf.faces wird in der Adressleiste angezeigt.

Gebe ich die zweite Seite manuell Output.jsp im Browser ein, kommt folgender Fehler:


```
type Exception report

message

descriptionThe server encountered an internal error () that prevented it from fulfilling this request.

exception

org.apache.jasper.JasperException: /Output.jsp(32,2) PWC6038: "#{UserDataBackingBean.firstName" contains invalid expression(s): javax.el.ELException: Error Parsing: #{UserDataBackingBean.firstName

note The full stack traces of the exception and its root causes are available in the Sun Java System Application Server 9.1_02 logs.
```

Hier der Code:


```
<%@ page language="java" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
	<base href="<%=basePath%>">

	<title>My JSF 'MyJsf.jsp' starting page</title>
	
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

</head>
  
<body>
	<f:view>
		Enter your first name, last name and email. 

		
		<h:form>
			<h:inputText value="#{ UserDataBackingBean.firstName }"/>
			<h:inputText value="#{UserDataBackingBean.lastName}"/>
			<h:inputText value="#{UserDataBackingBean.email}"/>
		<h:commandButton action="#{UserDataBackingBean.process}" value="send userdata" />
		</h:form>
	</f:view>
	
</body>
</html>
```


```
<%@ page language="java" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
	<base href="<%=basePath%>">

	<title>UserData Output</title>
	
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

</head>
  
<body>
	<f:view>
		Here is the data from the Form which is stored in the BackingBean: 

		
		<h:outputText value="#{UserDataBackingBean.firstName" />
		<h:outputText value="#{UserDataBackingBean.lastName" />
		<h:outputText value="#{UserDataBackingBean.email" />
		
	</f:view>
	
</body>
</html>
```


```
package de.jsf.model.backingbeans;

public class UserDataBackingBean {
	
	private String firstName;
	private String lastName;
	private String email;
	
	public String getFirstName() {
		return firstName;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	
	public String process() {
		
		// use EJBs to do something...
		
		return "success";
	}

}
```


```
<?xml version='1.0' encoding='UTF-8'?>
<faces-config 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_1_2.xsd"
    version="1.2">

 

  <navigation-rule>
    <from-view-id>/MyJsf.jsp</from-view-id>
    <navigation-case>
      <from-action>#{UserDataBackingBean.process}</from-action>
      <from-outcome>success</from-outcome>
      <to-view-id>/Output.jsp</to-view-id>
    </navigation-case>
  </navigation-rule>

  
  

  <managed-bean>
    <managed-bean-name>UserDataBackingBean</managed-bean-name>
    <managed-bean-class>de.jsf.model.backingbeans.UserDataBackingBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
  </managed-bean>

</faces-config>
```

Ich hoffe jemand kann mir weiterhelfen? Vielen Dank schonmal...


----------



## MarcB (10. Feb 2009)

Warum hat du denn from-action und from-outcome?

Lass mal das from-action weg.


----------



## megachucky (10. Feb 2009)

Das hatte ich zuerst auch gar nicht. Hatte ich nur optional versucht, aber klappt mit und ohne nicht :-(


----------



## megachucky (10. Feb 2009)

Ich hab jetzt mal debuggt. Es scheint ein Problem mit Eclipse zu sein, am Ende der Process Methode kommt folgeder Fehler:

Source not found
The Jar file C:\programme\genuitec\common\bynary\com.sun.java.jre.win32.x86...\lib\rt.jar has no source attachment.
You can attach the source by clicking attach source below 

?!?

Darunter noch einiges weitere siehe unten. Anscheinend ist dieses JAR irgendwie falsch oder wie ?! 
Ich glaub ich verwende doch wieder das "normale" Eclipse, und nicht MyEclipse :-(


```
//  (version 1.5 : 49.0, super bit)
class sun.reflect.NativeMethodAccessorImpl extends sun.reflect.MethodAccessorImpl {
  
  // Field descriptor #9 Ljava/lang/reflect/Method;
  private java.lang.reflect.Method method;
  
  // Field descriptor #41 Lsun/reflect/DelegatingMethodAccessorImpl;
  private sun.reflect.DelegatingMethodAccessorImpl parent;
  
  // Field descriptor #8 I
  private int numInvocations;
  
  // Method descriptor #44 (Ljava/lang/reflect/Method;)V
  // Stack: 2, Locals: 2
  NativeMethodAccessorImpl(java.lang.reflect.Method arg0);
     0  aload_0
     1  invokespecial sun.reflect.MethodAccessorImpl() [75]
     4  aload_0
     5  aload_1
     6  putfield sun.reflect.NativeMethodAccessorImpl.method : java.lang.reflect.Method [64]
     9  return

  
  // Method descriptor #4 (Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
  // Stack: 7, Locals: 4
  public java.lang.Object invoke(java.lang.Object arg0, java.lang.Object[] arg1) throws java.lang.IllegalArgumentException, java.lang.reflect.InvocationTargetException;
     0  aload_0
     1  dup
     2  getfield sun.reflect.NativeMethodAccessorImpl.numInvocations : int [63]
     5  iconst_1
     6  iadd
     7  dup_x1
     8  putfield sun.reflect.NativeMethodAccessorImpl.numInvocations : int [63]
    11  invokestatic sun.reflect.ReflectionFactory.inflationThreshold() : int [77]
    14  if_icmple 81
    17  new sun.reflect.MethodAccessorGenerator [37]
    20  dup
    21  invokespecial sun.reflect.MethodAccessorGenerator() [73]
    24  aload_0
    25  getfield sun.reflect.NativeMethodAccessorImpl.method : java.lang.reflect.Method [64]
    28  invokevirtual java.lang.reflect.Method.getDeclaringClass() : java.lang.Class [67]
    31  aload_0
    32  getfield sun.reflect.NativeMethodAccessorImpl.method : java.lang.reflect.Method [64]
    35  invokevirtual java.lang.reflect.Method.getName() : java.lang.String [71]
    38  aload_0
    39  getfield sun.reflect.NativeMethodAccessorImpl.method : java.lang.reflect.Method [64]
    42  invokevirtual java.lang.reflect.Method.getParameterTypes() : java.lang.Class[] [70]
    45  aload_0
    46  getfield sun.reflect.NativeMethodAccessorImpl.method : java.lang.reflect.Method [64]
    49  invokevirtual java.lang.reflect.Method.getReturnType() : java.lang.Class [68]
    52  aload_0
    53  getfield sun.reflect.NativeMethodAccessorImpl.method : java.lang.reflect.Method [64]
    56  invokevirtual java.lang.reflect.Method.getExceptionTypes() : java.lang.Class[] [69]
    59  aload_0
    60  getfield sun.reflect.NativeMethodAccessorImpl.method : java.lang.reflect.Method [64]
    63  invokevirtual java.lang.reflect.Method.getModifiers() : int [66]
    66  invokevirtual sun.reflect.MethodAccessorGenerator.generateMethod(java.lang.Class, java.lang.String, java.lang.Class[], java.lang.Class, java.lang.Class[], int) : sun.reflect.MethodAccessor [74]
    69  checkcast sun.reflect.MethodAccessorImpl [38]
    72  astore_3
    73  aload_0
    74  getfield sun.reflect.NativeMethodAccessorImpl.parent : sun.reflect.DelegatingMethodAccessorImpl [65]
    77  aload_3
    78  invokevirtual sun.reflect.DelegatingMethodAccessorImpl.setDelegate(sun.reflect.MethodAccessorImpl) : void [72]
    81  aload_0
    82  getfield sun.reflect.NativeMethodAccessorImpl.method : java.lang.reflect.Method [64]
    85  aload_1
    86  aload_2
    87  invokestatic sun.reflect.NativeMethodAccessorImpl.invoke0(java.lang.reflect.Method, java.lang.Object, java.lang.Object[]) : java.lang.Object [76]
    90  areturn

  
  // Method descriptor #45 (Lsun/reflect/DelegatingMethodAccessorImpl;)V
  // Stack: 2, Locals: 2
  void setParent(sun.reflect.DelegatingMethodAccessorImpl arg0);
    0  aload_0
    1  aload_1
    2  putfield sun.reflect.NativeMethodAccessorImpl.parent : sun.reflect.DelegatingMethodAccessorImpl [65]
    5  return

  
  // Method descriptor #47 (Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
  private static native java.lang.Object invoke0(java.lang.reflect.Method arg0, java.lang.Object arg1, java.lang.Object[] arg2);
}
```


----------



## MarcB (10. Feb 2009)

Eclipse nutze ich kaum und kann jetzt nur von Ganymede reden. MyEclipse hab ich noch nicht getestet.
Geh mal (wenn möglich) auf Window -> Preferences -> Java -> Installed JREs. Markiere dort das JRE und drück auf "Edit. Dort wählst du dann rt.jar aus und drückst "Source Attachment"  -> "External File". Dann wählst du die src.zip, die in deinem JDK liegt. Das sollte helfen.

Um das Problem mit der Navigation zu lösen wäre es noch interessant zu wissen, ob die beiden jsps im gleichen Verzeichnis liegen und wie das url-pattern in der web.xml aussieht.


----------



## megachucky (11. Feb 2009)

> Geh mal (wenn möglich) auf Window -> Preferences -> Java -> Installed JREs. Markiere dort das JRE und drück auf "Edit. Dort wählst du dann rt.jar aus und drückst "Source Attachment" -> "External File". Dann wählst du die src.zip, die in deinem JDK liegt. Das sollte helfen.



Ok, hab ich nun gemacht. Alle anderen JARs hatten auch kein Source Attachment, ich hab das daher bei allen gemacht ?! Wie entsteht denn dieses Problem ???





> Um das Problem mit der Navigation zu lösen wäre es noch interessant zu wissen, ob die beiden jsps im gleichen Verzeichnis liegen und wie das url-pattern in der web.xml aussieht.



Die JSPs sind im selben Verzeichnis. Hier noch die web.xml, evtl. passt ja hier etwas nicht:


```
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	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_2_5.xsd">
	
	<display-name>XYZ</display-name>
	
	<welcome-file-list>
		<welcome-file>/index.jsp</welcome-file>
	</welcome-file-list>
	
 <servlet>
  	<servlet-name>TestServlet</servlet-name>
  	<servlet-class>de.jsf.model.TestServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>TestServlet</servlet-name>
  	<url-pattern>/test</url-pattern>
  </servlet-mapping>
  
  	<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>*.faces</url-pattern>
	</servlet-mapping>
		<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>/faces/*</url-pattern>
	</servlet-mapping>
  
<jsp-config>
  <taglib>
    <taglib-uri>http://java.sun.com/jstl/fmt</taglib-uri>
    <taglib-location>/WEB-INF/lib/fmt.tld</taglib-location>
  </taglib>
  <taglib>
    <taglib-uri>http://java.sun.com/jstl/core</taglib-uri>
    <taglib-location>/WEB-INF/lib/c.tld</taglib-location>
  </taglib> 
  <taglib>
    <taglib-uri>http://java.sun.com/jstl/sql</taglib-uri>
    <taglib-location>/WEB-INF/lib/sql.tld</taglib-location>
  </taglib>
  <taglib>
    <taglib-uri>http://java.sun.com/jstl/x</taglib-uri>
    <taglib-location>/WEB-INF/lib/x.tld</taglib-location>
  </taglib>
</jsp-config>
	
</web-app>
```


----------



## MarcB (11. Feb 2009)

Mit eclipse ist das glaub ich standardmäßig so.

Hm, sehe jetzt auf den ersten Blick nix falsches.
Kannst mal folgende Sachen nacheinander ausprobieren. (Nach Änderungen immer re-deployen -> Server neu starten)
1. Lösche mal bei der Navigation-Rule das from-view-id.
2. Prüfe, ob die Action in deiner Bean gecalled wird (mit Konsolenausgabe oder so).
3. Falls da nix kommt, einfach mal 
	
	
	
	





```
<h:commandButton action="success" value="send userdata" />
```
 ausprobieren.


----------



## megachucky (11. Feb 2009)

> Mit eclipse ist das glaub ich standardmäßig so.



Nur zum Verständnis: Dieser Fehler hat nichts mit der Application zu tun, es geht nur darum, dass mir bei debuggen der Quellcode nicht angezeigt werden kann. Aber laufen tut es, weil ja die .class Files vorhanden sind, richtig?



> Hm, sehe jetzt auf den ersten Blick nix falsches.
> Kannst mal folgende Sachen nacheinander ausprobieren. (Nach Änderungen immer re-deployen -> Server neu starten)
> 1. Lösche mal bei der Navigation-Rule das from-view-id.
> 2. Prüfe, ob die Action in deiner Bean gecalled wird (mit Konsolenausgabe oder so).
> ...




Also bei 3. (action="success") passiert auch nix anderes. 

Die Bean wird aber gecallt, sieht man durch println im log file. Von daher muss der Fehler woanders liegen, nicht an dem "Success" String ?!


Das komische ist auch, ich hatte gestern in der Bean einen Breakpoint gesetzt, wenn ich dann die Web-App neu gestartet habe und sobald ich auf den Button geklickt hab, ist der Debugger von Eclipse angesprungen (d.h. die Bean wurde gecallt).
Aber das mit dem Debuggen über Breakpoint in der Bean müsste ja auf jeden Fall funktionieren, oder muss man zum Debuggen sonst noch etwas einstellen? Statt "Run" einfach "Debug" auszuführen funktioniert ja leider bei ner Web-App nicht :-(


----------



## MarcB (11. Feb 2009)

Zur Verständnisfrage: Ja, nähere Infos dazu gibts z.B. hier (Punkt 3.3).

Was mir sonst an deiner web.xml noch auffällt ist das doppelte Servlet-Mapping für das Faces Servlet. Meines Wissens geht das zwar, aber wenn was nicht funktioniert mache ich solche Sachen immer probeweise raus.
Vllt. bringts auch was einfach mal ein <h:messages/> einzufügen.

Edit: Ggf. kann man auch mal 
	
	
	
	





```
<navigation-rule>
    <navigation-case>
      <from-outcome>success</from-outcome>
      <to-view-id>/Output.jsp</to-view-id>
      <redirect/>
    </navigation-case>
</navigation-rule>
```
 testen.


----------



## megachucky (11. Feb 2009)

Vielen Dank. Klappt aber auch alles nicht. 

Ich werd denk ich Eclipse nochmal neu installieren und auch nochmal ein komplett neues JSF Projekt probieren.


----------

