I defined viewParam to process a GET request but the session bean is null.
/treeTable2.xhtml #28,119 value="#{conformanceProfileController.dataValueAssertionController.library_line}": Target Unreachable, identifier 'conformanceProfileController' resolved to null
GET request:
treeTable2.jsf?category=Message
XHTML code
<f:metadata>
<f:viewParam name="category" value="#{conformanceProfileController.category}" />
</f:metadata>
The Bean
#ManagedBean
#SessionScoped
public class ConformanceProfileController implements Serializable {
private String category;
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}
My development server is Tomcat 7.0 and I use Mojarra 2.1.0
EDIT: I created a simplified version with a new page and new bean. The code in the post is the same as the one on my machine.
XHTML Code:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
>
<h:head>
</h:head>
<f:metadata>
<f:viewParam name="category" value="#{myBean.category}" />
</f:metadata>
<h:body>
</h:body>
</html>
MyBean:
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class MyBean implements Serializable {
private String category;
public MyBean() {
System.out.println("Creation");
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}
The GET request: treeTable3.jsf?category=Message
The error message: /treeTable3.xhtml #8,60 value="#{myBean.category}": Target Unreachable, identifier 'myBean' resolved to null
Mojarra 2.1.0 do not work in Tomcat/Jetty due to a bug in annotation scanning. Upgrade to at least 2.1.1 or the current 2.1.3.
This has nothing to do with view parameters or session scoped beans. It will just fail in all cases where you expect a #ManagedBean.
Give the #Named annotation a try: http://download.oracle.com/javaee/6/tutorial/doc/gjbak.html
Related
I'm having an issue similar to this post and the answer from #BalusC with 3 solutions but:
I'm not using of the mentioned EL expressions
I don't want to go with the second solution (it's complex enough for me like this)
and partial state saving is set to false.
My code is as follows:
index.xhtml:
<?xml version="1.0" encoding="windows-1256" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Insert title here</title>
</h:head>
<h:body>
<h:form>
<p:panelMenu id="westMenu">
<p:submenu id="sub1" label="System Monitor">
<p:menuitem id="menu1" value="live monitoring"
action="#{menusBean.activateMenu('sub1_menu1')}"
update=":centerPane,westMenu"
disabled="#{menusBean.active['sub1_menu1']}" />
<p:menuitem id="menu2" value="reports"
action="#{menusBean.activateMenu('sub1_menu2')}"
update=":centerPane,westMenu"
disabled="#{menusBean.active['sub1_menu2']}" />
</p:submenu>
<p:submenu id="sub2" label="Charging System Nodes" />
<p:submenu id="sub3" label="Additional Nodes" />
</p:panelMenu>
</h:form>
<h:panelGroup id="centerPane">
...
</h:panelGroup>
</h:body>
</html>
MenusBean.java:
package menus;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.view.ViewScoped;
#ManagedBean
#ViewScoped
public class MenusBean implements Serializable{
private static final long serialVersionUID = -7793281454064343472L;
private String mainPage="sub1_menu1";
private Map<String, Boolean> active;
public MenusBean(){
System.out.println("MenusBean created");
active = new HashMap<>();
active.put(mainPage, true);
active.put("sub1_menu2", false);
}
public boolean activateMenu(String page){
active.put(mainPage, false);
active.put(page, true);
mainPage = page;
for (Map.Entry<String, Boolean> e : active.entrySet())
System.out.println(e.getKey()+":"+e.getValue());
return true;
}
public Map<String, Boolean> getActive() {
return active;
}
}
When executed, I get:
MenusBean created
MenusBean created
MenusBean created
How is this caused and how can I solve it?
This,
import javax.faces.view.ViewScoped;
is the JSF 2.2-introduced CDI-specific annotation, intented to be used in combination with CDI-specific bean management annotation #Named.
However, you're using the JSF-specific bean management annotation #ManagedBean.
import javax.faces.bean.ManagedBean;
You should then be using any of the scopes provided by the very same javax.faces.bean package instead. The right #ViewScoped is over there:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class MenusBean implements Serializable{
If you use the wrong combination, the bean behaves as a #RequestScoped bean and be recreated on each call.
Alternatively, if your environment supports CDI (GlassFish/JBoss/TomEE with Weld, OpenWebBeans, etc), then you could also replace #ManagedBean by #Named:
import javax.inject.Named;
import javax.faces.view.ViewScoped;
#Named
#ViewScoped
public class MenusBean implements Serializable{
It's recommended to move to CDI. The JSF-specific bean management annotations are candidate for deprecation in future JSF / Java EE versions as everything is slowly moving/unifying towards CDI.
I'm having an issue similar to this post and the answer from #BalusC with 3 solutions but:
I'm not using of the mentioned EL expressions
I don't want to go with the second solution (it's complex enough for me like this)
and partial state saving is set to false.
My code is as follows:
index.xhtml:
<?xml version="1.0" encoding="windows-1256" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Insert title here</title>
</h:head>
<h:body>
<h:form>
<p:panelMenu id="westMenu">
<p:submenu id="sub1" label="System Monitor">
<p:menuitem id="menu1" value="live monitoring"
action="#{menusBean.activateMenu('sub1_menu1')}"
update=":centerPane,westMenu"
disabled="#{menusBean.active['sub1_menu1']}" />
<p:menuitem id="menu2" value="reports"
action="#{menusBean.activateMenu('sub1_menu2')}"
update=":centerPane,westMenu"
disabled="#{menusBean.active['sub1_menu2']}" />
</p:submenu>
<p:submenu id="sub2" label="Charging System Nodes" />
<p:submenu id="sub3" label="Additional Nodes" />
</p:panelMenu>
</h:form>
<h:panelGroup id="centerPane">
...
</h:panelGroup>
</h:body>
</html>
MenusBean.java:
package menus;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.view.ViewScoped;
#ManagedBean
#ViewScoped
public class MenusBean implements Serializable{
private static final long serialVersionUID = -7793281454064343472L;
private String mainPage="sub1_menu1";
private Map<String, Boolean> active;
public MenusBean(){
System.out.println("MenusBean created");
active = new HashMap<>();
active.put(mainPage, true);
active.put("sub1_menu2", false);
}
public boolean activateMenu(String page){
active.put(mainPage, false);
active.put(page, true);
mainPage = page;
for (Map.Entry<String, Boolean> e : active.entrySet())
System.out.println(e.getKey()+":"+e.getValue());
return true;
}
public Map<String, Boolean> getActive() {
return active;
}
}
When executed, I get:
MenusBean created
MenusBean created
MenusBean created
How is this caused and how can I solve it?
This,
import javax.faces.view.ViewScoped;
is the JSF 2.2-introduced CDI-specific annotation, intented to be used in combination with CDI-specific bean management annotation #Named.
However, you're using the JSF-specific bean management annotation #ManagedBean.
import javax.faces.bean.ManagedBean;
You should then be using any of the scopes provided by the very same javax.faces.bean package instead. The right #ViewScoped is over there:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class MenusBean implements Serializable{
If you use the wrong combination, the bean behaves as a #RequestScoped bean and be recreated on each call.
Alternatively, if your environment supports CDI (GlassFish/JBoss/TomEE with Weld, OpenWebBeans, etc), then you could also replace #ManagedBean by #Named:
import javax.inject.Named;
import javax.faces.view.ViewScoped;
#Named
#ViewScoped
public class MenusBean implements Serializable{
It's recommended to move to CDI. The JSF-specific bean management annotations are candidate for deprecation in future JSF / Java EE versions as everything is slowly moving/unifying towards CDI.
I'm wondering if I'm having the same findings but after creating a javaee6 web project generated from jboss maven archetype I have the following result.
f:viewParam, did not work on dependent or view scope only in request scope.
public class BaseBean {
protected boolean edit;
public boolean isEdit() {
System.out.println("get edit=" + edit);
return edit;
}
public void setEdit(boolean edit) {
System.out.println("set edit=" + edit);
this.edit = edit;
}
}
#Named
#RequestScoped
public class RequestBean extends BaseBean { }
#Named
public class DependentBean extends BaseBean { }
#Named
#ViewScoped
public class ViewBean extends BaseBean { }
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
template="/WEB-INF/templates/default.xhtml">
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="edit" value="#{dependentBean.edit}" />
</f:metadata>
</ui:define>
<ui:define name="content">
<h:outputText value="#{dependentBean.edit}"></h:outputText>
</ui:define>
</ui:composition>
For the request and view scope views, it's almost the same as the one above except for the manage bean used.
Any idea?
The problem is that you're mixing JSF annotations from package javax.faces.bean with CDI annotations (noticed by the usage of #Named) from package javax.enterprise.context and they can't be used altogether for being handled by different managers (JSF and CDI managers). In your application, your managed beans should be from JSF or from CDI, not from a mix of both.
Note that CDI doesn't support #ViewScoped yet, this scope is available only for JSF. More info: CDI missing #ViewScoped and #FlashScoped
Original question is below, but as I have come up with a more minimal example to demonstrate this problem, and figured it should go at the top.
Anyway, it appears that ui:repeat tags are processed before checking to see if parent elements are actually rendered. To recreate this, here is the facelet (minimalTest.xhtml):
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Test JSF <ui:repeat> inside <h:panelGroup rendered="false"></title>
</h:head>
<h:body>
<h:form>
<h1>Testing</h1>
<h:panelGroup rendered="false">
<span>#{minimalTestBean.alsoThrowsException}</span>
<ul>
<ui:repeat value="#{minimalTestBean.throwsException}" var="item">
<li>#{item}</li>
</ui:repeat>
</ul>
</h:panelGroup>
</h:form>
</h:body>
</html>
With using this bean (MinimalTestBean.java):
package com.lucastheisen.beans;
import java.io.Serializable;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class MinimalTestBean implements Serializable {
private static final long serialVersionUID = 9045030165653014015L;
public String getAlsoThrowsException() {
throw new RuntimeException( "rendered is false so this shouldnt get called either" );
}
public List<String> getThrowsException() {
throw new RuntimeException( "rendered is false so this shouldnt get called" );
}
}
From this example you can see that the h:panelGroup that contains the ui:repeat is statically set to rendered=false which I would assume would mean that none of the EL expressions inside of that h:panelGroup would get executed. The EL expressions just call getters which throw a RuntimeException. However, the ui:repeat is actually calling the getter for its list thus causing the exception even though it should not be getting rendered in the first place. If you comment out the ui:repeat element, no exceptions get thrown (even though the other EL expression remains in the h:panelGroup) as I would expect.
Reading other questions here on stackoverflow leads me to believe that is likely related to the oft-referred-to chicken/egg issue, but I am not sure exactly why, nor what to do about it. I imagine setting the PARTIAL_STATE_SAVING to false might help, but would like to avoid the memory implications.
---- ORIGINAL QUESTION ----
Basically, I have a page that conditionally renders sections using <h:panelGroup rendered="#{modeXXX}"> wrapped around <ui:include src="pageXXX.xhtml" /> (per this answer). The problem is that if one of the pageXXX.xhtml has a <ui:repeat> inside of it, it seems to get processed even when the containing <h:panelGroup> has rendered=false. This is a problem because some of my sections rely on having been initialized by other sections that should be visited before them. Why is the included pageXXX.xhtml getting processed?
This is a painful bug and incredibly hard to boil down to a small example, but here is the most minimal case I could build that demonstrates the issue. First a base page:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Test JSF <ui:include></title>
</h:head>
<h:body>
<h:form>
<h1>#{testBean.title}</h1>
<h:panelGroup rendered="#{testBean.modeOne}">
<ui:include src="modeOne.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{testBean.modeTwo}">
<ui:include src="modeTwo.xhtml" />
</h:panelGroup>
</h:form>
</h:body>
</html>
As you can see this page will conditionally include either the modeOne page or the modeTwo page based upon the value in the testBean bean. Then you have modeOne (the default):
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
<ui:composition>
<span>Okay, I'm ready. Take me to </span>
<h:commandLink action="#{testBean.setModeTwo}">mode two.</h:commandLink>
</ui:composition>
</html>
Which in my real world app would be a page that sets up things needed by modeTwo. Once set up, an action on this page will direct you to modeTwo:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
<ui:composition>
<div>Here is your list:</div>
<ui:repeat value="#{testBeanToo.list}" var="item">
<div>#{item}</div>
</ui:repeat>
</ui:composition>
</html>
The modeTwo page basically presents a details for the modeOne page in a ui:repeat as the actual information is in a collection. The main managed bean (TestBean):
package test.lucastheisen.beans;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class TestBean implements Serializable {
private static final long serialVersionUID = 6542086191355916513L;
private Mode mode;
#ManagedProperty( value="#{testBeanToo}" )
private TestBeanToo testBeanToo;
public TestBean() {
System.out.println( "constructing TestBean" );
setModeOne();
}
public String getTitle() {
System.out.println( "\ttb.getTitle()" );
return mode.getTitle();
}
public boolean isModeOne() {
return mode == Mode.One;
}
public boolean isModeTwo() {
return mode == Mode.Two;
}
public void setModeOne() {
this.mode = Mode.One;
}
public void setModeTwo() {
testBeanToo.getReadyCauseHereICome();
this.mode = Mode.Two;
}
public void setTestBeanToo( TestBeanToo testBeanToo ) {
this.testBeanToo = testBeanToo;
}
private enum Mode {
One("Mode One"),
Two("Mode Two");
private String title;
private Mode( String title ) {
this.title = title;
}
public String getTitle() {
return title;
}
}
}
Is the bean for all the main data, and the TestBeanToo bean would be for the details:
package test.lucastheisen.beans;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class TestBeanToo implements Serializable {
private static final long serialVersionUID = 6542086191355916513L;
private ObjectWithList objectWithList = null;
public TestBeanToo() {
System.out.println( "constructing TestBeanToo" );
}
public String getTitle() {
System.out.println( "\ttb2.getTitle()" );
return "Test Too";
}
public List<String> getList() {
System.out.println( "\ttb2.getList()" );
return objectWithList.getList();
}
public void getReadyCauseHereICome() {
System.out.println( "\ttb2.getList()" );
objectWithList = new ObjectWithList();
}
public class ObjectWithList {
private List<String> list;
public ObjectWithList() {
list = new ArrayList<String>();
list.add( "List item 1" );
list.add( "List item 2" );
}
public List<String> getList() {
return list;
}
}
}
<ui:repeat> does not check the rendered attribute of itself (it has actually none) and its parents when the view is to be rendered. Consider using Tomahawk's <t:dataList> instead.
I've got two instances of a SessionScoped CDI bean for the same session. I was under the impression that there would be one instance generated for me by CDI, but it generated two. Am I misunderstanding how CDI works, or did I find a bug?
Here is the bean code:
package org.mycompany.myproject.session;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.servlet.http.HttpSession;
#Named #SessionScoped public class MyBean implements Serializable {
private String myField = null;
public MyBean() {
System.out.println("MyBean constructor called");
FacesContext fc = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession)fc.getExternalContext().getSession(false);
String sessionId = session.getId();
System.out.println("Session ID: " + sessionId);
}
public String getMyField() {
return myField;
}
public void setMyField(String myField) {
this.myField = myField;
}
}
Here is the Facelet code:
<?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"
xmlns:f="http://java.sun.com/jsf/core">
<f:view contentType="text/html" encoding="UTF-8">
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h:form id="form">
<h:inputText value="#{myBean.myField}"/>
<h:commandButton value="Submit"/>
</h:form>
</h:body>
</f:view>
</html>
Here is the output from deployment and navigating to page:
INFO: Loading application org.mycompany_myproject_war_1.0-SNAPSHOT at /myproject
INFO: org.mycompany_myproject_war_1.0-SNAPSHOT was successfully deployed in 8,237 milliseconds.
INFO: MyBean constructor called
INFO: Session ID: 175355b0e10fe1d0778238bf4634
INFO: MyBean constructor called
INFO: Session ID: 175355b0e10fe1d0778238bf4634
Using GlassFish 3.0.1
Ryan, as covener already wrote, the constructor will also get called for each and every proxy for that bean. This is a standard behaviour of all proxy mechanisms which provide not only interface-proxying (like java.lang.reflect.proxy stuff) but real class-proxying.
Also imagine that the ct will also be called for each and every serialization. So if you work on a heavily load balanced cluster, you will see this lots of times. So please use #PostConstruct for beans in general.
LieGrue,
strub
It's likely that your CDI implementation calls the underlying beans default constructor when newing up proxies to use for injection points -- this is the default behavior of javassist which is used in weld and openwebbeans.
Avoid heavy lifting in your default constructor, moving it into #PostConstruct if you can!