Skip to content
This repository has been archived by the owner on Mar 20, 2021. It is now read-only.

Injecting in Converter/Validator requires a JSF 2.3 faces-config.xml file #4270

Closed
ConstantinAlin opened this issue Aug 28, 2017 · 7 comments
Milestone

Comments

@ConstantinAlin
Copy link

Injecting in Converter/Validator requires a JSF 2.3 faces-config.xml file, even if the application uses a JSF 2.3 configuration bean:

ConfigurationBean.java

@FacesConfig(version = FacesConfig.Version.JSF_2_3)
public class ConfigurationBean {
}

As pointed by Arjan Tijms in this topic, an empty JSF 2.3 faces-config.xml file is not involved into enabling CDI injection and EL resolution using CDI and switching into a JSF 2.3 mode, thus, it should not be required when using CDI injection into Converter/Validator.

Consider the following example:

index.xhtml

<h:form>
	Phone number:
	<h:inputText id="phoneId" value="#{phoneNumberBean.number}"
			converter="phoneNumberConverter"
			validator="phoneNumberValidator" />
	<h:message for="phoneId"/>
	<h:commandButton value="Send" action="#{phoneNumberBean.pingNumberAction()}"/>
</h:form>
Ping number: #{phoneNumberBean.number}

PhoneNumberConverter.java

@FacesConverter(value = "phoneNumberConverter", managed = true)
public class PhoneNumberConverter implements Converter {

    @Inject
    private PhonePrefixServiceBean phonePrefixServiceBean;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (!value.contains("-")) {
            return phonePrefixServiceBean.computePrefix() + "-" + value;
        }
        return value;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return String.valueOf(value);
    }
}

PhoneNumberValidator.java

@FacesValidator(value = "phoneNumberValidator", managed = true)
public class PhoneNumberValidator implements Validator {

    @Inject
    private PhonePrefixServiceBean phonePrefixServiceBean;

    @Override
    public void validate(FacesContext fc, UIComponent uic, Object o) throws ValidatorException {
        String pn = String.valueOf(o);
        if (!phonePrefixServiceBean.getPrefix().contains(pn.substring(0, 4))) {
            throw new ValidatorException(new FacesMessage(null, "Wrong prefix!"));
        }
    }
}

PhonePrefixServiceBean.java

@Named
@ApplicationScoped
public class PhonePrefixServiceBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private final List prefix;

    public PhonePrefixServiceBean() {
        prefix = new ArrayList<>();
        prefix.add("0721");
        prefix.add("0723");
        prefix.add("0909");
    }

    public String computePrefix() {
        return (String) prefix.get(new Random().nextInt(3));
    }

    public List getPrefix() {
        return prefix;
    }
}

Exception thrown

Without a JSF 2.3 faces-config.xml file or with a faces-config.xml version 2.2 file, the application throws the following exception:

FATAL:   JSF1073: javax.faces.FacesException caught during processing of PROCESS_VALIDATIONS 3 : UIComponent-ClientId=, Message=null
FATAL:   No associated message
javax.faces.FacesException
	at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:85)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:201)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:670)
	at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1606)
	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:654)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:593)
	at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
	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:480)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:180)
	at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
	at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
	at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:242)
	at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
	at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
	at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:539)
	at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
	at beans.PhoneNumberConverter.getAsObject(PhoneNumberConverter.java:18)
	at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:171)
	at javax.faces.component.UIInput.getConvertedValue(UIInput.java:1122)
	at javax.faces.component.UIInput.validate(UIInput.java:1030)
	at javax.faces.component.UIInput.executeValidate(UIInput.java:1334)
	at javax.faces.component.UIInput.processValidators(UIInput.java:757)
	at javax.faces.component.UIForm.processValidators(UIForm.java:269)
	at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1298)
	at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1298)
	at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1332)
	at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:77)
	... 31 more

Testing environment:

JSF 2.3.2, Payara Server 5.0.0.174

@Quix0r
Copy link

Quix0r commented Sep 6, 2017

In faces-config.xml (written from my memory) you can use JSF 2.3 XSD and version="2.3". Have you tried this, too? When I last did this with JSF 2.3 (downloaded here from "Releases" link) all my context-parameter were not processed.

@ConstantinAlin
Copy link
Author

@Quix0r You are right. If I add a JSF 2.3 faces-config.xml file, with version=2.3, the above use case works. However, I'm not looking for a quick fix, but merely to point out that a faces-config.xml file should not be required during CDI injection.

@arjantijms
Copy link
Member

@ConstantinAlin

It should indeed not be required, but this is a bug in Mojarra 2.3.2. We should fix this soon.

Sorry for the inconvenience!

@ConstantinAlin
Copy link
Author

@arjantijms Great! I'm just happy to help in any way I can and I will continue testing JSF 2.3.

arjantijms added a commit that referenced this issue Sep 7, 2017
#4270 Removed forgotten 2.3 switch based on faces-config
@arjantijms
Copy link
Member

@ConstantinAlin I just pushed a fix and tested it via the already existing tests in the project. It should work now, but would be good if you could double test it. Thx!

@ConstantinAlin
Copy link
Author

@arjantijms Confirmed. No empty faces-config.xml required. Tested with JSF 2.3.3-SNAPSHOT build from MOJARRA_2_3X_ROLLING.

@arjantijms
Copy link
Member

@ConstantinAlin

\0/

Great that it's fixed now. It was indeed my "fault"; I forgot to update the code at one location. Sorry for all the confusion.

@arjantijms arjantijms added this to the 2.3.3 milestone Sep 8, 2017
Toberumono pushed a commit to Toberumono/mojarra that referenced this issue Oct 11, 2017
* MOJARRA_2_3X_ROLLING:
  Let's start work for release 2.3.4-SNAPSHOT
  release cut 2.3.3
  javaee#4270 Removed forgotten 2.3 switch based on faces-config
  javaee#4276 Updated pom.xml files so project compiles again with Maven
Toberumono pushed a commit to Toberumono/mojarra that referenced this issue Oct 11, 2017
…le-in-execute-render-rolling

* MOJARRA_2_3X_ROLLING:
  Let's start work for release 2.3.4-SNAPSHOT
  release cut 2.3.3
  javaee#4270 Removed forgotten 2.3 switch based on faces-config
  javaee#4276 Updated pom.xml files so project compiles again with Maven
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants