Why <f:validateBean /> won't work? - jsf

I use JSF 2.0, hibernate-validator4.2.jar validation-api.jar tomcat and Eclipse.
I put #Size(min=3, message="xxx") annotation in a #ManagedBean and <f:validateBean /> between <h:inputText value="#{user.name}"></h:inputText>
When I try to run the project i get this error...
exception
javax.servlet.ServletException: Expression Error: Named Object: javax.faces.Bean not found.
javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)
root cause
javax.faces.FacesException: Expression Error: Named Object: javax.faces.Bean not found.
com.sun.faces.application.ApplicationImpl.createValidator(ApplicationImpl.java:1593)
com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl.createValidator(ValidatorTagHandlerDelegateImpl.java:244)
com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl.applyAttachedObject(ValidatorTagHandlerDelegateImpl.java:132)
com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl.applyNested(ValidatorTagHandlerDelegateImpl.java:211)
com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl.apply(ValidatorTagHandlerDelegateImpl.java:87)
javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
why? (this only appears when i put tag)
User.java
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.validation.constraints.Size;
#ManagedBean(name="user")
#SessionScoped
public class User{
#Size(min=3, message="At least 3 characters!")
private String name;
public String getName() {
return nume;
}
public void setName(String name){
this.name=name;
}
}
adduser.xhtml
<!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: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 template="/templates/master_layout.xhtml">
<ui:define name="text_header" >Panou de control: Adauga user </ui:define>
<ui:define name="content">
<h:panelGrid columns="3">
<h:outputText value="Name"></h:outputText>
<h:inputText value="#{user.name}">
<f:validateBean />
</h:inputText>
<h:commandButton value="Inregistreaza" action="index.xhtml"></h:commandButton>
</h:panelGrid>
</ui:define>
</ui:composition>
</html>

It should work perfectly fine, although the empty <f:validateBean/> tag is entirely superfluous in this context. It's supposed to be used to "finetune" validation more, such as grouping of validation and/or disabling the implicit bean validation on a per-input basis by specifying the desired tag attributes. You have however no attributes on that tag, so just remove that tag altogether. On a default JSF 2 + JSR 303 project setup, it's supposed to kick in fully transparently without adding more JSF tags whenever there's a JSR 303 annotation on the property such as #Size and likes.
But I don't think that removing the tag will solve this particular exception. Your problem lies thus deeper. This validator is supposed to be auto-registered on startup. However, the exception basically tells that the validator is not registered at all. With the information given so far, it's not possible to give a targeted answer. I can think of the following possible causes:
There's a bug in the JSF implementation which you're using. Upgrade it to a newer version.
You have multiple JSF libraries of different versions in your classpath. Cleanup it.
The faces-config.xml root declaration is not declared conform JSF 2.x. Fix it.

Related

Value expressions still evaluated despite ui:fragment rendered="false"

I have bean:
class Property{
private String type;
private Date value;
//getters and setters
}
also have block of code on page:
<ui:fragment rendered="#{property.type eq 'checkbox'}">
<ui:include src="checkbox.xhtml">
<ui:param name="property" value="#{property}"/>
</ui:include>
</ui:fragment>
checkbox.xhtml:
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<body>
<ui:composition>
<h:selectBooleanCheckbox value="#{property.value}"/>
</ui:composition>
</body>
</html>
The condition #{property.type eq 'checkbox'} = false
But I get next exception:
javax.servlet.ServletException: checkBox.xhtml value="#{property.value}": Cannot convert 01.11.02 0:00 of type class java.util.Date to class java.lang.Boolean
I expect if the attribute rendered=false in ui:include, then this block will not be processed.
<ui:fragment rendered> prevents it from rendering the HTML output, but it doesn't prevent it from ending up in JSF component tree and being eligible for state saving.
Use <c:if test> instead. It runs during view build time instead of view render time and thus the whole bunch won't end up in JSF component tree at all.
Or, if you have this all inside an <ui:repeat var="property">, and you are using Mojarra, then upgrade to at least 2.1.29 or 2.2.7 wherein this state saving bug was fixed.
See also:
JSTL in JSF2 Facelets... makes sense?
PropertyNotFoundException on conditionally rendered subclasses in ui:repeat

How to integrate Hibernate Validator into Tomcat 7?

I've successfully integrated JSF (Mojarra) and CDI (Weld), but can't get Hibernate Validator to work.
The following jars are added to WEB-INF/lib:
validation-api-1.1.0.Final.jar
hibernate-validator-5.1.0.Final.jar
jboss-logging-3.1.3.GA.jar
classmate-1.0.0.jar
Tomcat 7 comes with EL 2.2 jars so I didn't add them.
My JSF page:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h:form>
<h1><h:outputText id="hello" value="Hello, #{testController.name}!"/></h1>
<p:inputText id="name" value="#{testController.name}"/>
<h:message id="error" for="name"/>
<h:commandButton value="Change Name">
<f:ajax execute="name" render="hello error"/>
</h:commandButton>
</h:form>
</h:body>
</html>
And my backing bean:
#Named
#ApplicationScoped
public class TestController {
#NotNull
#Size(min = 3, max = 5)
private String name;
#PostConstruct
private void init() {
name = "Bill";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
It's expected that when the size of the name is smaller than 3 or bigger than 5, an error message is shown, but it turns out to be not. Seems the Hibernate Validator is not working . I did see it's detected but was no longer logged:
Mar 11, 2014 9:31:40 PM org.hibernate.validator.internal.util.Version <clinit>
INFO: HV000001: Hibernate Validator 5.1.0.Final
Is there anything wrong?
Update
Finally I figured out it's a Mojarra regression. The Hibernate Validator works now with MyFaces.
Just to avoid confusion (as I have been confused, looking for the error despite it had already been solved because I didn't see the update section at the end of the post), let me add the answer on behalf of the OP:
It seems the OP used a Mojarra version that was broken. They solved the problem by migrating to MyFaces (see the update to their question). FWIW, I tried their example using Mojarra 2.2.12, and it worked fine.
When you say you integrated with Tomcat 7, how did you do that? There is some glue code in application servers which make sure that for example the ValidatorFactory is visible to JSF. Not sure whether something like this would be required for you as well.
Have you enabled debug/trace logging to verify whether Validator bootstraps or get called?
Also you could try to add to the JSF page, but this should be optional.
Aren't you missing the <f:validateBean> tag on the page? I think you might also need to call the Validator.validate(bean) method in order to get it to fire.

How to form #Named Backing Bean in JSF

I read somewhere that it's better to use CDI #Named instead of JSF #ManagedBean, because of CDI, so I'm trying to convert some of my code.
I'm trying to use #Named in JSF, but it's always unreachable.
When using #ManagedBean there was no problem.
I'm using it like #ManagedBean, as below
CustomerBacking.java
package com.wordpress.marczykm.backing;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
#Named("customer")
#RequestScoped
public class CustomerBacking {
#EJB
private CustomerService customerService;
public CustomerBacking() {
}
public String addCustomer(Customer customer) {
customerService.addCustomer(customer);
return "customer_overview";
}
public Customer getCustomer(){
return customerService.getCustomer();
}
}
index.xhtml
<!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: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>EJB 3.0 Test</title>
</h:head>
<h:body>
<h:outputText value="#{customer.firstname}"/>
<h:form>
<h:outputText value="ImiÄ™"/>
<h:inputText id="firstname" name="firstname" value="#{customer.firstname}" /><br/>
<h:outputText value="Nazwisko"/>
<h:inputText id="lastname" name="lastname" value="#{customer.lastname}" /><br/>
<h:commandButton value="Dodaj" actionListener="#{customer.addCustomer}"/>
</h:form>
</h:body>
</html>
To sum up, looking at Netbeans sample CDI app, the bean which needs to be accesible by JSF page needs to:
have #Named annotation (javax.inject.Named)
have scope annotation (like #SessionScoped, #RequestScoped, #ViewScoped), but imported from javax.enterprise.context.*
doesn't have to have empty, non-argument constructor
and the thing that wasn't in my code is that, that the bean needs to implement Serializable (java.io.Serializable)
last thing is that if your app is a web application it needs a beans.xml (can be completly empty) in WEB-INF directory, if it is a bean app it have to be in META-INF directory
You don't mention which servlet container/application server and which CDI implementation version you're using.
I have no clue what Spring Tool Suite assumes as default, presumably it's Tomcat, Spring and no CDI at all, so you have to add and configure a CDI implementation (e.g. Weld or OpenWebBeans).
For CDI 1.0, you'll have to add a WEB-INF/beans.xml descriptor (which may be empty) to have your beans discovered. This is no longer necesary for CDI 1.1.

JSF 2.0 ViewScoped life cycle

My problem is that one of my ViewScoped bean is created several time within the same view. The constructor of ViewScopedBean is created every time I select a node in the tree.
<h:form>
<p:tree value="#{treeBean.root}" var="node"
selectionMode="single" selection="#{viewScopedBean.selectedNode}">
<p:ajax event="select" update="selectedNode, treeBeanUpdate, otherBeanUpdate, panel" listener="#{treeBean.onNodeSelect}" />
<p:treeNode>
<h:outputText value="#{node}" />
</p:treeNode>
</p:tree>
Selected Node: <h:outputText value="#{viewScopedBean.selectedNode}" id="selectedNode"/><br/>
Current TreeBean: <h:outputText value="#{treeBean}" id="treeBeanUpdate"/><br/>
Current OtherBean: <h:outputText value="#{viewScopedBean}" id="otherBeanUpdate"/><br/>
<p:outputPanel id="panel">
<ag:profileComponent managedBean="#{viewScopedBean.profileBean}"/>
</p:outputPanel>
</h:form>
If I remove this part (reference to a composite component), the constructor of ViewScopedBean is not called:
<p:outputPanel id="panel">
<ag:profileComponent managedBean="#{viewScopedBean.profileBean}"/>
</p:outputPanel>
All the beans used are set as #ViewScoped.
#ManagedBean
#ViewScoped
public class ViewScopedBean implements Serializable {
private TreeNode selectedNode;
private ProfileBean profileBean;
public ViewScopedBean() {
System.out.println("Constructor of ViewScopedBean " + this);
}
#PostConstruct
public void init() {
System.out.println("ViewScoped init" + this);
profileBean = new ProfileBean();
}
}
Is it the correct behaviour? If not what can cause it?
Update: I tried to use an empty composite, and I have the same problem.
<?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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="managedBean" required="true"/>
</composite:interface>
<composite:implementation>
</composite:implementation>
</html>
But if I made the managedBean not required, that's fine.
Another thing I don't get is when the constructor is called, it seems that the object created is not used.
Initiating the view (console output):
Constructor of ViewScopedBean xxx.bean.ViewScopedBean#4e1d2b8e
2 clicks on the tree:
Constructor of ViewScopedBean xxx.bean.ViewScopedBean#4eb64f2e
Constructor of ViewScopedBean xxx.bean.ViewScopedBean#66863941
Then I open the debug window <ui:debug/>, the viewScopedBean is set to xxx.bean.ViewScopedBean#4e1d2b8e
The view scoped bean will be recreated on every request from/to the same view, when you use JSTL tags like <c:if>, <c:forEach> and so on in the view, or when you bind a JSF component as a property of the view scoped bean using binding attribute. That's apparently what's happening in your composite component.
You need to rewrite your composite component as such that it does not utilize any JSTL tags. Binding some JSF component as a property of the bean can also be avoided in many ways, but if that is really not avoidable, then disabling the partial state saving in web.xml should work in most of the cases:
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>
If that doesn't work for you, then you really have to share your composite component implementation code with us so that we can point out the caveats and propose the right approaches.

Private/scoped variable in JSF2/Facelets <ui:component>?

I might not be thinking correctly in terms of visual components in JSF, but I guess that's part of my question. My question is around the seeming lack of scope around variables declared within JSF <ui:component> implementations.
So, say I have /resources/comp/myPanel.xhtml:
<?xml version="1.0" encoding="UTF-8" ?>
<ui:component xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:cc="http://java.sun.com/jsf/composite">
<cc:interface>
</cc:interface>
<cc:implementation>
<f:loadBundle var="bundle" basename="panelOnly.bundle" />
<h:outputText value="#{bundle.myText}" />
</cc:implementation>
</ui:component>
And there is a resource bundle that gets loaded in that component, panelOnly/bundle.properties:
myText = This is a panel resource
And then I have a page that places the myPanel component, mainPage.xhtml:
<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:comp="http://java.sun.com/jsf/composite/comp">
<h:body>
<f:view>
<f:loadBundle basename="mainPage.bundle" var="bundle" />
<comp:myPanel />
<h:outputText value="#{bundle.myText}" />
</f:view>
</h:body>
</html>
and there is a resource bundle that gets loaded in the main page, mainPage/bundle.properties:
myText = This is a main page resource
Now, I would assume that my page should render as:
This is a panel resource
This is a main page resource
But, instead, I get:
This is a panel resource
This is a panel resource
And I assume that is because I clobbered what the "bundle" symbol refers to in my component so that when the mainPage.xhtml tries to resolve that value, it looks to the component's "bundle" object and not the original mainPage's.
My workaround to date has been to just use unique named variables within my components that would never clash with variables on my main pages. But I would prefer if there was a way to coax JSF to recognize anything declared in my component as locally scoped variables and not clobber the caller's symbols.
I think there are and other tags that one can use to make locally scoped variables under #{cc.attrs...}. If you could enumerate my local scoping options in your answer, that would be very helpful. I suspect my <f:loadBundle> is a special case, and maybe there isn't a workaround for that one as it was not designed with <ui:component> in mind.
Thanks!
P.S. I'm running Mojarra 2.1.1 (FCS 20110408)
(edited for formatting and copy and paste bugs 6/15/2011)
Unfortunately, that's how <f:loadBundle> works. It's an one-time setting for the entire view. And any subsequent <f:loadBundle> calls in the same view will just override the previous one.
Your best bet is to manage it by a backing component.
<cc:interface componentType="myPanel">
with
#FacesComponent(value="myPanel")
public class MyPanel extends UIComponentBase implements NamingContainer {
private ResourceBundle bundle;
public MyPanel() {
bundle = ResourceBundle.getBundle("panelOnly.bundle",
FacesContext.getCurrentInstance().getViewRoot().getLocale());
}
#Override
public String getFamily() {
return "javax.faces.NamingContainer";
}
public ResourceBundle getBundle() {
return bundle;
}
}
which can be used as
<cc:implementation>
<h:outputText value="#{cc.bundle.myText}" />
</cc:implementation>

Resources