JSF converter fails to intialize - jsf

I have a facelet page in which i have a primefaces selectCheckboxMenu where a user can select one or more conferences.
Primefaces 8.0,
5.194 #badassfish (build 327)|#]
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.faces</artifactId>
<version>2.3.9</version>
<scope>provided</scope>
</dependency>
I neeed to create a converter to convert between object and string. But no matter what I'm doing it does not work.
Either the stateless EJB I inject to be used as a service is not instantiated or I receive a NPE when CDI tries to create the converter:
Error Rendering View[/conferences.xhtml]
java.lang.NullPointerException
at com.sun.faces.cdi.CdiUtils.createConverter(CdiUtils.java:102)
at com.sun.faces.application.applicationimpl.InstanceFactory.createConverter(InstanceFactory.java:481)
at com.sun.faces.application.ApplicationImpl.createConverter(ApplicationImpl.java:510)
at javax.faces.application.ApplicationWrapper.createConverter(ApplicationWrapper.java:431)
at org.primefaces.renderkit.SelectRenderer.findImplicitConverter(SelectRenderer.java:202)
at org.primefaces.renderkit.SelectRenderer.getOptionAsString(SelectRenderer.java:181)
at org.primefaces.component.selectcheckboxmenu.SelectCheckboxMenuRenderer.encodeOption(SelectCheckboxMenuRenderer.java:143)
at org.primefaces.component.selectcheckboxmenu.SelectCheckboxMenuRenderer.encodeOption(SelectCheckboxMenuRenderer.java:137)
at org.primefaces.component.selectcheckboxmenu.SelectCheckboxMenuRenderer.encodeInputs(SelectCheckboxMenuRenderer.java:128)
at org.primefaces.component.selectcheckboxmenu.SelectCheckboxMenuRenderer.encodeMarkup(SelectCheckboxMenuRenderer.java:93)
at org.primefaces.component.selectcheckboxmenu.SelectCheckboxMenuRenderer.encodeEnd(SelectCheckboxMenuRenderer.java:63)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:595)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1654)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:152)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:566)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1647)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1650)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1650)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:468)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:170)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:132)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:102)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:76)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:199)
at javax.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:708)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:451)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1628)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:258)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:755)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:575)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:159)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:520)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:217)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:182)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:156)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:218)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:95)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:260)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:177)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:109)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:88)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:53)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:524)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:89)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:94)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:33)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:114)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:569)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:549)
at java.base/java.lang.Thread.run(Thread.java:834)
|#]
JSF1073: java.lang.NullPointerException caught during processing of RENDER_RESPONSE 6 : UIComponent-ClientId=, Message=null|#]
No associated message
java.lang.NullPointerException
at com.sun.faces.cdi.CdiUtils.createConverter(CdiUtils.java:102)
at com.sun.faces.application.applicationimpl.InstanceFactory.createConverter(InstanceFactory.java:481)
at com.sun.faces.application.ApplicationImpl.createConverter(ApplicationImpl.java:510)
at javax.faces.application.ApplicationWrapper.createConverter(ApplicationWrapper.java:431)
at org.primefaces.renderkit.SelectRenderer.findImplicitConverter(SelectRenderer.java:202)
at org.primefaces.renderkit.SelectRenderer.getOptionAsString(SelectRenderer.java:181)
at org.primefaces.component.selectcheckboxmenu.SelectCheckboxMenuRenderer.encodeOption(SelectCheckboxMenuRenderer.java:143)
at org.primefaces.component.selectcheckboxmenu.SelectCheckboxMenuRenderer.encodeOption(SelectCheckboxMenuRenderer.java:137)
at org.primefaces.component.selectcheckboxmenu.SelectCheckboxMenuRenderer.encodeInputs(SelectCheckboxMenuRenderer.java:128)
at org.primefaces.component.selectcheckboxmenu.SelectCheckboxMenuRenderer.encodeMarkup(SelectCheckboxMenuRenderer.java:93)
at org.primefaces.component.selectcheckboxmenu.SelectCheckboxMenuRenderer.encodeEnd(SelectCheckboxMenuRenderer.java:63)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:595)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1654)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:152)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:566)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1647)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1650)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1650)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:468)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:170)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:132)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:102)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:76)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:199)
at javax.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:708)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:451)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1628)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:258)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:755)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:575)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:159)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:520)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:217)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:182)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:156)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:218)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:95)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:260)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:177)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:109)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:88)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:53)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:524)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:89)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:94)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:33)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:114)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:569)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:549)
at java.base/java.lang.Thread.run(Thread.java:834)
Please find all my code below.
My facelet:
<?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:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<style type="text/css">
.ui-selectlistbox-listcontainer{
overflow: initial !important;
}
</style>
</h:head>
<h:body>
<h2>SelectManyMenu Example</h2>
<h:form>
<p:selectCheckboxMenu value="#{conferenceSelectionBean.selectedConferences}"
multiple="true"
filter="true" filterMatchMode="contains"
style="width:300px;">
<f:selectItems value="#{conferenceSelectionBean.allConferences}" var="conf"
itemLabel="#{conf.title}" itemValue="#{conf}"/>
</p:selectCheckboxMenu>
<p:commandButton value="Submit" action="#{conferenceSelectionBean.blabla}" update="selectedEmpPanel"/>
<h3>Selected Employees:</h3>
<h:panelGrid id="selectedEmpPanel" columns="1">
<ui:repeat value="#{conferenceSelectionBean.selectedConferences}" var="conf">
<h:outputText value="#{conf.id} (#{conf.title}) - #{conf.date}"/>
<br/>
</ui:repeat>
</h:panelGrid>
</h:form>
</h:body>
</html>
My Conference bean:
package com.logicbig.example;
public class Conference {
private String id;
private String title;
private String date;
public Conference(String id, String title, String date) {
this.id = id;
this.title = title;
this.date = date;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
My converter
package com.logicbig.example;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;
#FacesConverter(forClass=Conference.class, managed=true)
public class ConferenceConverter implements Converter<Conference> {
#Inject
ConferenceService conferenceService;
public ConferenceConverter() { System.out.println("HOLA 2");
}
#Override
public Conference getAsObject(FacesContext fc, UIComponent comp, String value) {System.out.println("Get as object");
if(conferenceService == null){
System.out.println("SERVICE IS NULL");
}
return null;
}
#Override
public String getAsString(FacesContext fc, UIComponent comp, Conference value) { System.out.println("Get as String");
return ((Conference) value).getId();
}
}
In this case i receive the exception mentioned in the beginning.
Also, I've tried this:
package com.logicbig.example;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;
#FacesConverter(value = "confConverter")
public class ConferenceConverter implements Converter {
#Inject
ConferenceService conferenceService;
public ConferenceConverter() { System.out.println("HOLA 2");
}
#Override
public Object getAsObject(FacesContext fc, UIComponent comp, String value) {System.out.println("Get as object");
if(conferenceService == null){
System.out.println("SERVICE IS NULL");
}
return null;
}
#Override
public String getAsString(FacesContext fc, UIComponent comp, Object value) { System.out.println("Get as String");
return ((Conference) value).getId();
}
}
and entered the link in my xhtml:
<p:selectCheckboxMenu value="#{conferenceSelectionBean.selectedConferences}"
multiple="true" converter="confConverter"
filter="true" filterMatchMode="contains"
style="width:300px;">
<f:selectItems value="#{conferenceSelectionBean.allConferences}" var="conf"
itemLabel="#{conf.title}" itemValue="#{conf}"/>
</p:selectCheckboxMenu>
In this case the injected bean is always null.
My backing bean
package com.logicbig.example;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
#Named
#ViewScoped
public class ConferenceSelectionBean implements Serializable {
#Inject
ConferenceService conferenceService;
private List<Conference> selectedConferences = new ArrayList();
private List<Conference> allConferences;
#PostConstruct
private void init() {
allConferences = conferenceService.getAllConferences();
}
public void blabla(){
for(Conference c : selectedConferences){
System.out.println(c.getId() +" " + c.getTitle()+ " " + c.getDate());
}
}
public ConferenceService getConferenceService() {
return conferenceService;
}
public void setConferenceService(ConferenceService conferenceService) {
this.conferenceService = conferenceService;
}
public List<Conference> getSelectedConferences() {
return selectedConferences;
}
public void setSelectedConferences(List<Conference> selectedConferences) {
this.selectedConferences = selectedConferences;
}
public List<Conference> getAllConferences() {
return allConferences;
}
public void setAllConferences(List<Conference> allConferences) {
this.allConferences = allConferences;
}
}
My stateless session bean
package com.logicbig.example;
import java.util.Arrays;
import java.util.List;
import javax.ejb.Stateless;
#Stateless
public class ConferenceService {
private final List<Conference> conferences;
public ConferenceService() {
conferences = Arrays.asList(
new Conference("1", "Cool conference 1", "2010-05-10"),
new Conference("2", "Cool conference 2", "2010-05-10"),
new Conference("3", "Cool conference 3", "2010-05-10"),
new Conference("4", "Cool conference 4", "2010-05-10"),
new Conference("5", "Cool conference 5", "2010-05-10")
);
}
public List<Conference> getAllConferences() {
return conferences;
}
public Conference getConferenceById(String value) {
return conferences.stream()
.filter(e -> e.getId().equals(value))
.findAny().orElse(null);
}
}
and my configuration bean
package com.logicbig.example;
import javax.enterprise.context.ApplicationScoped;
import javax.faces.annotation.FacesConfig;
#ApplicationScoped
#FacesConfig(version = FacesConfig.Version.JSF_2_3)
public class ConfigurationBean {
public ConfigurationBean() {
}
}
EDIT:
If I change the beginning of my converter to:
#FacesConverter(value = "confConverter", managed = true)
public class ConferenceConverter implements Converter<Object> {
the injection of the EJB service works as expected.
I need to have the following in my XHTML page
<f:converter converterId="confConverter"/>
So now it works as expected and I can retire the #MangedBean code.

As you already answered yourself, you need a converter for your non-primitive datatype.
For primitive datatypes or generic datatypes where the generic runtime information is lost there is regression / bug in mojarra which maybe is fixed in 2.3.10. https://github.com/eclipse-ee4j/mojarra/issues/4500.
Enums
converting enums without using omnifaces.genericEnumConverter
generics
Create concrete implementation class.
I had a class DataRange<T extends Comparable<T>> like DataRange<Date> and in p:calendar value="#{cc.attrs.range.start}" mojarra only retrieved Comparable<T> instead Date in conversion phase.
As a workaround i am using DataRangeDate to make sure runtime information of Date is not lost.
primefaces 6.19
This basically occurs when relying on default converters like in p:calendar or p:inputNumber.

Related

What is the best practice to Manage Facade pattern for EJB session bean?

Hello,
I would like to know the best practice for managing Facades.
The main objective of my project:
Once connected via a login system, we arrive on our account page. Depending on the status of the user (project manager or executant) we can access either the project itself as well as each of its phases (status: project manager) or phases only (status: executant).
In this project, i use entities, i created a persistence unit, and used the Facade pattern to manipulate my database.
In my Netbeans, if I do New > Sessions Bean for Entity Classes, and let say that I select Example entity, then Netbeans would generate public abstract class AbstractFacade<T> {...} with many methode and
#Stateless
public class ExampleFacade extends AbstractFacade<User> {...}
for all entities i have select. For all Facade i use one ManagerBean and i use :
#EJB
private ExampleFacade exempleFacade;
in him .
I have a problem recovering data from other bean managers because for get projet or phase i have use #RequestScope because in .xhtml get param in URL. After search on google, i understand why i can't .
For resolv my problem, i have create a general manager for all facade.
My project works perfectly but I want to know if it's the best practice and if it's secure?
I ask myself it's a question to progress in my learning of jee and jsf
This is my generalManager
package logic;
import facade.PhasesFacade;
import facade.PostesFacade;
import facade.ProjetsFacade;
import facade.UtilisateursFacade;
import javax.inject.Named;
import java.io.Serializable;
import java.util.ArrayList;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedProperty;
import javax.faces.context.FacesContext;
import model.Phases;
import model.Projets;
import model.Utilisateurs;
/**
*
* #author valibert
*/
#Named(value = "generalManager")
#SessionScoped
public class GeneralManager implements Serializable {
private Utilisateurs currentUser;
private Projets currentProjet;
private Phases currentPhase;
ArrayList<Utilisateurs> listUtilisateurs;
ArrayList<Projets> listProjets;
ArrayList<Phases> listPhases;
private String validForm;
private String mailUtil;
private String mdpUtil;
private int idProjet;
FacesContext context = FacesContext.getCurrentInstance();
FacesMessage message = new FacesMessage();
#ManagedProperty(value = "#{param.idProjet}")
private String idProjetResquest;
#EJB
private PhasesFacade phasesFacade;
#EJB
private PostesFacade postesFacade;
#EJB
private ProjetsFacade projetsFacade;
#EJB
private UtilisateursFacade utilisateursFacade;
/**
* Creates a new instance of generalManager
*/
public GeneralManager() {
}
public Utilisateurs getCurrentUser() {
return currentUser;
}
public void setCurrentUser(Utilisateurs currentUser) {
this.currentUser = currentUser;
}
public Projets getCurrentProjet() {
return currentProjet;
}
public void setCurrentProjet(Projets currentProjet) {
this.currentProjet = currentProjet;
}
public Phases getCurrentPhase() {
return currentPhase;
}
public void setCurrentPhase(Phases currentPhase) {
this.currentPhase = currentPhase;
}
public ArrayList<Utilisateurs> getListUtilisateurs() {
return listUtilisateurs;
}
public void setListUtilisateurs(ArrayList<Utilisateurs> listUtilisateurs) {
this.listUtilisateurs = listUtilisateurs;
}
public ArrayList<Projets> getListProjets() {
return listProjets;
}
public void setListProjets(ArrayList<Projets> listProjets) {
this.listProjets = listProjets;
}
public ArrayList<Phases> getListPhases() {
return listPhases;
}
public void setListPhases(ArrayList<Phases> listPhases) {
this.listPhases = listPhases;
}
public PhasesFacade getPhasesFacade() {
return phasesFacade;
}
public void setPhasesFacade(PhasesFacade phasesFacade) {
this.phasesFacade = phasesFacade;
}
public PostesFacade getPostesFacade() {
return postesFacade;
}
public void setPostesFacade(PostesFacade postesFacade) {
this.postesFacade = postesFacade;
}
public ProjetsFacade getProjetsFacade() {
return projetsFacade;
}
public void setProjetsFacade(ProjetsFacade projetsFacade) {
this.projetsFacade = projetsFacade;
}
public UtilisateursFacade getUtilisateursFacade() {
return utilisateursFacade;
}
public void setUtilisateursFacade(UtilisateursFacade utilisateursFacade) {
this.utilisateursFacade = utilisateursFacade;
}
public String getValidForm() {
return validForm;
}
public void setValidForm(String validForm) {
this.validForm = validForm;
}
public String getMailUtil() {
return mailUtil;
}
public void setMailUtil(String mailUtil) {
this.mailUtil = mailUtil;
}
public String getMdpUtil() {
return mdpUtil;
}
public void setMdpUtil(String mdpUtil) {
this.mdpUtil = mdpUtil;
}
public String getIdProjetResquest() {
return idProjetResquest;
}
public void setIdProjetResquest(String idProjetResquest) {
this.idProjetResquest = idProjetResquest;
}
public int getIdProjet() {
return idProjet;
}
public void setIdProjet(int idProjet) {
this.idProjet = idProjet;
}
//Méthode
public String submitFormLogin(){
currentUser = utilisateursFacade.findOne(mailUtil);
if ((utilisateursFacade.findOne(mailUtil).getMdpUtil().equals(mdpUtil)) && (utilisateursFacade.findOne(mailUtil).getMailUtil().equals(mailUtil)) ){
currentUser = utilisateursFacade.findOne(mailUtil);
validForm = "toCompteFromIndex";
return validForm;
}
currentUser = new Utilisateurs();
message.setSeverity(FacesMessage.SEVERITY_INFO);
message.setSummary("L'utilisateur ou le mot de passe n'est pas valide merci de rééssayer");
message.setDetail("Message detail.");
context.addMessage("formConnection", message);
validForm = "";
return validForm;
}
public void onload(){
try {
idProjet = Integer.parseInt(idProjetResquest);
currentProjet = projetsFacade.findByIdAndUserManager(idProjet, currentUser.getIdUtil());
} catch (NumberFormatException e){
idProjetResquest = "404";
}
}
#PostConstruct
public void initUtilisateurs(){
this.listUtilisateurs = new ArrayList();
this.listUtilisateurs.addAll(utilisateursFacade.findAll());
}
}
and this is a view for example
<ui:composition template="/templates.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<f:metadata>
<f:viewParam id="idProjet" name="idProjet" value="#{generalManager.idProjetResquest}" required="true" />
<f:viewAction action="#{generalManager.onload}" />
</f:metadata>
<ui:define name="content-main">
<h2>Chef Projet #{generalManager.currentUser.prenomUtil}</h2>
<h2>Projet #{generalManager.currentProjet.libelleProj}</h2>
<p>Date du début du projet :<h:outputText value="#{generalManager.currentProjet.dateDebutProj}" >
<f:convertDateTime pattern="MM/dd/yyyy" />
</h:outputText></p>
<p>Phases du projet</p>
<ul>
<ui:repeat value="#{generalManager.phasesFacade.findPhaseByProjet(projetsManager.projetChoose.idProjet)}" var="itemPhase">
<li>
<h:outputLink value="../phases/View.xhtml" >
<f:param name="idPhase" value="#{itemPhase.idPhase}" />
<h:outputText value="#{itemPhase.libellePhase}"/>
</h:outputLink>
</li>
</ui:repeat>
</ul>
</ui:define>
thank you in advance

#ManagedProperty null after #PostConstruct in JSF 2.2

My specs:
Dynamic Web Module 3.1
GlassFish Web Extensions 4.0
Java 1.8
JavaScript 1.0
JavaServer Faces 2.2
Server: glassfish-4.1.1
OS: Win 10
IDE: Version: Neon.2 Release (4.6.2)
Please, note that I have researched this topic and found several related posts.
e.g.
#ManagedProperty + #PostConstruct + init() = Nullpointer
#ManagedProperty injected AFTER #PostConstruct
But neither of the proposed solutions worked for me or applied to my situation.
I don't mix CDI and/or JSF and/or Spring. It's JSF 2.2 annotations only.
I inject #ManagedProperty("#{country}") Country country; to my ChangeCountrySystemEventListener but the value of the #ManagedProperty country is null.
I don't really see where the issue is. The Country constructor does get invoked.
Any tips where the issues is?
Here's my full code:
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://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Title</title>
</h:head>
<h:body>
<h3><h:outputText value="#{country.name}" /> </h3>
<h:form>
<h:commandButton
id="changeCountryNameBtn"
value="Change"
action="result"
actionListener="#{appBean.changeCountryName}"
/>
</h:form>
</h:body>
</html>
AppBean.java
package com.test.beans;
import javax.faces.application.Application;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
#ManagedBean
#SessionScoped
public class AppBean {
public void changeCountryName(ActionEvent ev) {
FacesContext context = FacesContext.getCurrentInstance();
Application app = context.getApplication();
app.publishEvent(context, ChangeCountrySystemEvent.class, ev.getSource());
System.out.println(">>>> AppBean.publishEvent(ChangeCountrySystemEvent) fired... " + ev.getSource());
}
}
ChangeCountrySystemEvent.java
package com.test.beans;
import javax.faces.event.SystemEvent;
public class ChangeCountrySystemEvent extends SystemEvent {
private static final long serialVersionUID = -1587717461942271611L;
public ChangeCountrySystemEvent(Object source) {
super(source);
System.out.println(">>>> ChangeCountrySystemEvent.class :: constructor invoked!");
}
}
ChangeCountrySystemEventListener.java
package com.test.beans;
import javax.faces.bean.ManagedProperty;
import javax.faces.context.FacesContext;
import javax.faces.event.SystemEvent;
import javax.faces.event.SystemEventListener;
public class ChangeCountrySystemEventListener implements SystemEventListener {
#ManagedProperty("#{country}")
Country country;
// getters and setters
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
public ChangeCountrySystemEventListener(FacesContext fc) {
super();
System.out.println(">>>> ChangeCountrySystemEventListener.class :: Listener constructor invoked!!!");
}
#Override
public void processEvent(SystemEvent se) {
if (country != null) {
country.setName("Sweden");
System.out.println(">>>> ChangeCountrySystemEventListener.class :: SYSTEM EVENT PROCESSED... <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ");
} else if (country == null) {
System.out.println(">>>> ChangeCountrySystemEventListener.class :: processEvent() > country managed property is EMPTY !!!!");
}
}
#Override
public boolean isListenerForSource(Object source) {
return true; // needs to be set to true, otherwise "processEvent" won't be called...
}
}
Country.java
package com.test.beans;
import javax.annotation.PostConstruct;
import javax.faces.application.Application;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
#ManagedBean(name = "country", eager = true)
#SessionScoped
public class Country {
private String name = "Norway";
public Country() {
System.out.println(">>>> Country constructor called...");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#PostConstruct
public void init() {
FacesContext fc = FacesContext.getCurrentInstance();
Application app = fc.getApplication();
app.subscribeToEvent(ChangeCountrySystemEvent.class, new ChangeCountrySystemEventListener(fc));
System.out.println(">>>> Country.class :: app.subscribeToEvent() called... ");
}
}
Console output:
2017-04-02T21:49:51.392-0300|Info: JSF_TestProject was successfully deployed in 579 milliseconds.
2017-04-02T21:49:52.251-0300|Info: >>>> Country constructor called...
2017-04-02T21:49:52.277-0300|Info: >>>> ChangeCountrySystemEventListener.class :: Listener constructor invoked!!!
2017-04-02T21:49:52.277-0300|Info: >>>> Country.class :: app.subscribeToEvent() called...
2017-04-02T21:50:16.572-0300|Info: >>>> ChangeCountrySystemEvent.class :: constructor invoked!
2017-04-02T21:50:16.572-0300|Info: >>>> ChangeCountrySystemEventListener.class :: processEvent() > country managed property is EMPTY !!!!
2017-04-02T21:50:16.572-0300|Info: >>>> AppBean.publishEvent(ChangeCountrySystemEvent) fired... javax.faces.component.html.HtmlCommandButton#424c250c
The ManagedProperty can be used on a field of a class annotated with ManagedBean to inject a value into this property.
If this annotation is present on a class that does not have the ManagedBean annotation, the implementation must take no action on this annotation.
Please see http://docs.oracle.com/javaee/6/api/javax/faces/bean/ManagedProperty.html
Since the class ChangeCountrySystemEventListener is not annotated with ManagedBean, no action is taken on the ManagedProperty field country and its null.

Adding validators to UIInputs outside of <h:inputText> tag

Is it possible to add validators to inputText fields from outside the h:inputText tag?
<!-- instead of this -->
<h:inputText id="field1" value="#{backingBean.field1}">
<f:validator validatorId="CustomValidator" />
</h:inputText>
<!-- something like this -->
<h:inputText id="field1" value="#{backingBean.field1}" />
<abc:validations>
<abc:validation for="field1" validator="CustomValidatorName" />
</abc:validations>
The abc:validation is a really short custom component
<cc:interface componentType="validation">
<cc:attribute name="for" />
<cc:attribute name="validator" />
</cc:interface>
<cc:implementation>
</cc:implementation>
</ui:composition>
and a faces component class
package at.sozvers.ecm.webclient.frontend.component;
import java.io.Serializable;
import javax.faces.component.FacesComponent;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponentBase;
import javax.faces.component.UINamingContainer;
import javax.faces.validator.Validator;
#FacesComponent("validation")
public class Validation extends UIComponentBase implements NamingContainer, Serializable {
private static final long serialVersionUID = 1L;
private String for1;
private Validator validator;
#Override
public String getFamily() {
return UINamingContainer.COMPONENT_FAMILY;
}
public String getFor() {
return for1;
}
public void setFor(String for1) {
this.for1 = for1;
}
public Validator getValidator() {
return validator;
}
public void setValidator(Validator validator) {
this.validator = validator;
}
}
I read about TagHandlers and ComponentHandlers but I have no idea how to start.
I found a solution
I created a class extending ComponentHandlerWrapper and override the onComponentPopulated method where I read the ViewMap and put a ValidatorSet for each inputText id that has to be validated. The ValidatorSet contains a Set where I write the FacesValidator names into.
public class ParentAddingComponentHandlerWrapper extends ComponentHandlerWrapper {
#Override
public void onComponentPopulated(FaceletContext ctx, UIComponent c, UIComponent parent) {
super.onComponentPopulated(ctx, c, parent);
Map<String, Object> viewMap = ctx.getFacesContext().getViewRoot().getViewMap();
if (c instanceof Validation) { // Validation is the FacesComponent class for <abc:validation>
TagAttribute uiInputName = getAttribute("for");
if (null == viewMap.get(uiInputName.getValue())) {
viewMap.put(uiInputName.getValue(), new ValidatorSet());
}
TagAttribute validator = getAttribute("validator"); // the validator attribute contains a FacesValidator name
ValidatorSet validators = (ValidatorSet) viewMap.get(uiInputName.getValue());
if (validator != null) {
validators.addValidator(validator.getValue());
}
}
}
Than I created a CustomComponent where I'm "decorating" a inputText. I also created a componentType/FacesComponent named field which I annotated with #ListenerFor(systemEventClass = PreValidateEvent.class)
Than I had to override the processEvent method where I added the FacesValidator to the UIInput component
#Override
public void processEvent(ComponentSystemEvent event) throws AbortProcessingException {
super.processEvent(event);
Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
String id = getAttributeValue("id", "");
ValidatorSet validators = (ValidatorSet) viewMap.get(id);
if (validators != null) {
UIComponent findComponent = findComponent(id);
if (findComponent instanceof UIInput) {
UIInput input = (UIInput) findComponent;
List<Validator> inputValidators = Arrays.asList(input.getValidators());
for (Validator validator : validators.getValidators()) {
if (!doesUIInputContainsValidator(inputValidators, validator)) {
input.addValidator(validator);
}
}
}
}
}
private boolean doesUIInputContainsValidator(List<Validator> inputValidators, Validator validator) {
for (Validator inputValidator : inputValidators) {
if (inputValidator.getClass().isInstance(validator)) {
return true;
}
}
return false;
}

Getting selection from p:selectOneMenu in PrimeFaces

I want to select a value from a p:selectOneMenu component (a dropdownlist) in Primefaces. I get my data from a Java Bean. I have the following code:
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"
xmlns:p="http://primefaces.org/ui">
<h:body>
<h:form>
<p:messages id="errorMessages" style="color:red;margin:8px;" />
<br></br>
<p:panelGrid columns="2" style="margin-bottom:10px" cellpadding="5">
<h:outputText value="Tasks: "/>
<p:selectOneMenu value="#{devTestController.selectedTask}">
<f:selectItems value="#{devTestController.tasks}" var="task" itemLabel="#{task.label}" itemValue="#{task.value}"/>
<f:converter converterId="infoRowBeanConverter" />
</p:selectOneMenu>
</p:panelGrid>
<br/>
<p:commandButton value="Execute Task" update = "errorMessages" action="#{devTestController.executeTask()}"/>
</h:form>
</h:body>
</html>
Java Bean DevTestController.java:
package mypackage;
import java.util.LinkedList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
#ManagedBean
#RequestScoped
public class DevTestController
{
private InfoRowBean selectedTask;
private static List<InfoRowBean> tasks;
#PostConstruct
public void initList()
{
if (tasks == null)
{
tasks = new LinkedList<>();
tasks.add(new InfoRowBean("Task 1", "Task 1"));
tasks.add(new InfoRowBean("Task 2", "Task 2"));
}
}
public InfoRowBean getSelectedTask()
{
return selectedTask;
}
public void setSelectedTask(InfoRowBean selectedTask)
{
this.selectedTask = selectedTask;
}
public List<InfoRowBean> getTasks()
{
return tasks;
}
public void executeTask()
{
System.out.println("Executing task " + selectedTask.label);
}
}
InfoRowBean.java:
package mypackage;
import java.util.List;
public class InfoRowBean
{
String label = null;
String value = null;
public InfoRowBean(String label, String value)
{
setLabel(label);
setValue(value);
}
public String getLabel()
{
return label;
}
public void setLabel(String label)
{
this.label = label;
}
public String getValue()
{
return value;
}
public void setValue(String value)
{
this.value = value;
}
// This must return true for another InfoRowBean object with same label/id.
public boolean equals(Object other)
{
return other instanceof InfoRowBean && (label != null) ? label.equals(((InfoRowBean) other).label) : (other == this);
}
// This must return the same hashcode for every InfoRowBean object with the same label.
public int hashCode()
{
return label != null ? this.getClass().hashCode() + label.hashCode() : super.hashCode();
}
// Override Object#toString() so that it returns a human readable String representation.
// It is not required by the Converter or so, it just pleases the reading in the logs.
public String toString()
{
return "InfoRowBean[" + label + "," + value + "]";
}
}
Converter InfoRowBeanConverter.java:
package mypackage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
#FacesConverter("infoRowBeanConverter")
public class InfoRowBeanConverter implements Converter
{
public Object getAsObject(FacesContext context, UIComponent component, String value)
{
return value;
}
public String getAsString(FacesContext context, UIComponent component, Object value)
{
return value.toString();
}
}
If I press the button nothing happens (no error also). If I remove the parameter "value" from tag (namely leave ), the button works fine, but of course I don't get the selected item. What is the problem here?
The problem is that your converter isn't converting the submitted string value to a concrete InfoRowBean instance in getAsObject() method, but instead returning the raw submitted String value as you have generated in getAsString() method. This doesn't match the type of selectedTask, which is InfoRowBean.
You need to fix your converter accordingly in such way that getAsString() returns the unique string representation of the complex object, usually in flavor of the database identifier (so that it can be used further in text based formats such as HTML output and HTTP request parameters), and that getAsObject() converts exactly that unique string representation back to the concrete complex object instance, usually via a DB call using the unique identifier as key.
An alternative is to use omnifaces.SelectItemsConverter of the JSF utility library OmniFaces, so that you never need to create custom converters for components using <f:selectItem(s)> with complex objects as values.
Another alternative is to change selectedTask to be String instead of InfoRowBean (and get rid of the whole converter as it is completely useless in this construct).
See also:
How to populate options of h:selectOneMenu from database?

Prime Faces error Cannot add the same component twice

I am new to Java Server Faces. I am doing one simple login jsf application which has layout.xhtml, login.xhtml, loginbean.java, changepassword.xhtml, changepasswordbean.java. Login functions are working fine but changepassword function is causing some problem which I can't find what's the reason for error. I am getting error when clicking Clear Button in changepassword.xhtml page. If I click changepassword button a Null pointer exception have occured because I am trying to get a value(companyid) from another loginbean to changepasswordbean. After clicking back button in browser then selecting changepassword menu I am getting a error like Parent was not null, but this component not related. Sometimes menus will not be displayed. I don't know what's the problem, so any help here.
LoginBean.java
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import java.io.Serializable;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
#ManagedBean
#SessionScoped
public class LoginBean implements Serializable
{
Logger log;
#ManagedProperty(value = "loginBean")
public boolean isLoggedin;
public String username;
public String password;
public String companyid;
public boolean notloggedin;
#ManagedProperty(value = "#{tabMenu}")
private TabMenu tabMenu;
public LoginBean()
{
log=LoggerFactory.getLogger(LoginBean.class);
}
public void clear()
{
setUsername(null);
setPassword(null);
setCompanyId(null);
}
public String login()
{
setIsLoggedin(true);
setNotLoggedIn(false);
setCompanyId("companyid_1");
tabMenu.setTabMenu();
return "home";
}
public String logout()
{
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
setIsLoggedin(false);
setNotLoggedIn(true);
return "/login.xhtml?faces-redirect=true";
}
public void setUsername(String username)
{
this.username=username;
}
public String getUsername()
{
return username;
}
public void setPassword(String password)
{
this.password=password;
}
public String getPassword()
{
return password;
}
public void setIsLoggedin(boolean isloggedin)
{
this.isLoggedin=isloggedin;
}
public boolean getIsLoggedin()
{
return isLoggedin;
}
public void setNotLoggedIn(boolean notloggedin)
{
this.notloggedin=notloggedin;
}
public boolean getNotLoggedIn()
{
if(getIsLoggedin())
{
this.notloggedin=false;
}
else
this.notloggedin=true;
return notloggedin;
}
public void setCompanyId(String companyid)
{
this.companyid=companyid;
}
public String getCompanyId()
{
return companyid;
}
public TabMenu getTabMenu()
{
return tabMenu;
}
public void setTabMenu(TabMenu tabMenu)
{
this.tabMenu = tabMenu;
}
}
ChangePasswordBean.java
import java.io.Serializable;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
#ManagedBean
#RequestScoped
public class ChangePasswordBean implements Serializable
{
Logger log;
#ManagedProperty(value = "changePasswordBean")
public String oldPassword;
public String newPassword;
public String retypePassword;
#ManagedProperty(value = "#{loginBean}")
public LoginBean lbean;
public ChangePasswordBean()
{
log=LoggerFactory.getLogger(ChangePasswordBean.class);
}
public void changePassword()
{
log.debug("Company Id: "+lbean.getCompanyId());
log.debug("User Name: "+lbean.getUsername());
boolean flag=false;
ChangePasswordDAO changepass=new ChangePasswordDAO();
if(oldPassword!=null && newPassword!=null && retypePassword!=null)
{
if(newPassword.equals(retypePassword))
{
flag=changepass.changePassword(oldPassword, newPassword,lbean.getUsername(),lbean.getCompanyId());
if(flag)
{
FacesContext.getCurrentInstance().addMessage("changepassform:btnchange", new FacesMessage(FacesMessage.SEVERITY_INFO,"Info", "Password Changed Successfully"));
}
else
{
FacesContext.getCurrentInstance().addMessage("changepassform:btnchange", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "Password Not Changed"));
}
}
else
{
FacesContext.getCurrentInstance().addMessage("changepassform:btnchange", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "New Password and Retype Password didn't match"));
}
}
else
{
FacesContext.getCurrentInstance().addMessage("changepassform:btnchange", new FacesMessage(FacesMessage.SEVERITY_WARN, "Warning", "Old Password/New Password/Retype Password Should not be empty"));
}
}
public void clear()
{
setOldPassword(null);
setNewPassword(null);
setRetypePassword(null);
}
public void setOldPassword(String oldPassword)
{
this.oldPassword=oldPassword;
}
public String getOldPassword()
{
return oldPassword;
}
public void setNewPassword(String newPassword)
{
this.newPassword=newPassword;
}
public String getNewPassword()
{
return newPassword;
}
public void setRetypePassword(String retypePassword)
{
this.retypePassword=retypePassword;
}
public String getRetypePassword()
{
return retypePassword;
}
public void setLbean(LoginBean lbean)
{
this.lbean=lbean;
}
public LoginBean getLbean()
{
return lbean;
}
}
changepassword.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<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:p="http://primefaces.org/ui">
<body>
<ui:composition template="../templates/layout.xhtml">
<ui:define name="content">
<h:form id="changepassform" rendered="#{loginBean.isLoggedin}">
<p:messages id="messages" autoUpdate="true" redisplay="false"
showDetail="true"/>
<h:panelGrid columns="2">
<h:outputLabel value="Current Password"/>
<p:inputText value="#{changePasswordBean.oldPassword}" style="width: 106px;"/>
<h:outputLabel value="New Password"/>
<p:password value="#{changePasswordBean.newPassword}" style="width: 106px;"></p:password>
<h:outputLabel value="Retype New Password"/>
<p:inputText value="#{changePasswordBean.retypePassword}" style="width: 106px;"/>
</h:panelGrid>
<br></br>
<h:panelGrid columns="2" style="margin-left: 100px">
<h:commandButton action="#{changePasswordBean.changePassword()}" value="Change Password" id="btnchange" />
<h:commandButton action="#{changePasswordBean.clear()}" value="Clear" id="btnclear" />
</h:panelGrid>
</h:form>
</ui:define>
</ui:composition>
</body>
</html>
I solved this issue by setting the transient option=true. Because I was creating menus dynamically which resulted in "WARNING: Unable to save dynamic action with clientId 'j_idt8:j_idt9:0:j_id3' because the UIComponent cannot be found" and "Cannot remove the same component twice: j_idt8:j_idt9:j_id3" problems.
public void setMenus(String type)
{
MenuItem item;
item=new MenuItem();
item.setValue("Change Password");
item.setStyle("color:black");
item.setTransient(true); /* Set this to solve the problem */
item.setUrl("/adminAccount/changepassword.xhtml");
submenus.addMenuItem(item);
}

Resources