简体   繁体   中英

FacesConverter is null (JSF 2.3, CDI 2.0)

I tried to setup a FacesConverter to display some entity through my JSF page as referenced in JSF specification.

I'm running the following: - Open Liberty 19.0.0.11 (tested on 19.0.0.6 as well, don't ask me why this version, I picked randomly another one) - Java Open JDK 13 - JSF 2.3 - CDI 2.0

I've added to my project the following web.xml:

<web-app id="WebApp_ID" version="4.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">
    <display-name>TestConverterInjection</display-name>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <enabled>true</enabled>
        <async-supported>false</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>
        *.xhtml</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
</web-app>

The following faces-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd"
    version="2.3">

</faces-config>

The following beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
    bean-discovery-mode="all" 
    version="2.0">
</beans>

I do have an AppConfig class, annotated with @FacesConfig(Version.JSF_2_3). All fine so far.

I've simple TestConverter annotated as such:

@FacesConverter(value = "testConverter", managed = true)

When looking through the BeanManager, my TestConverter seems to be available as it appears in the list.

My test.xhtml file looks like this:

    <!DOCTYPE html>
<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:ui="http://java.sun.com/jsf/facelets"> 


    <h:outputText value="#{testBean.selectedEntity.id}">    
    </h:outputText>
    <br/>
    <h:outputText value="#{testBean.selectedEntity}" converter="testConverter">    
    </h:outputText>
</html>

And my backing bean:

package com.test.beans;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.util.AnnotationLiteral;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;

import com.test.entities.MyEntity;

@Named("testBean")
@ViewScoped
public class TestBean implements Serializable {

    private List<MyEntity> listEntities;

    private MyEntity selectedEntity;

    @Inject private BeanManager beanManager;

    @PostConstruct
    public void init() {

        this.listEntities = new ArrayList<MyEntity>();

        for(int i = 0; i < 5; i++) {
            this.listEntities.add(new MyEntity(i, "test_"+i, i+"_test"));
        }

        this.selectedEntity = this.listEntities.get(0);

        Set<Bean<?>> beans = beanManager.getBeans(Object.class,new AnnotationLiteral<Any>() {});
        for (Bean<?> bean : beans) {       
            System.out.println("bean: "+bean.getBeanClass().getName());
        }       
    }

    public List<MyEntity> getListEntities() {
        return listEntities;
    }

    public void setListEntities(List<MyEntity> listEntities) {
        this.listEntities = listEntities;
    }

    public MyEntity getSelectedEntity() {
        return selectedEntity;
    }

    public void setSelectedEntity(MyEntity selectedEntity) {
        this.selectedEntity = selectedEntity;
    }       

}

Should be all good right? Well, at least it worked with Apache TomEE 8.0.0 PluME. But here on Open Liberty, I'm getting:

SRVE0777E: Exception émise par la classe d'application 'javax.faces.webapp.FacesServlet.service:236' javax.servlet.ServletException: at javax.faces.webapp.FacesServlet.service(FacesServlet.java:236) at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1255) at [internal classes] Caused by: java.lang.NullPointerException: at org.apache.myfaces.cdi.converter.FacesConverterCDIWrapper.getAsString(FacesConverterCDIWrapper.java:62)... 1 more

So, it looks like my bean is instantiated but is null... Features of Open Liberty are javaee8-0 (to be sure there wasn't anything missing). In the example above, if I'm removing the "managed = true" in my converter, it works. Some bug within CDI?

I investigated the issue and I found that it's caused by beanManager.getBeans call. The bean is registered in the beanManger (as you demonstrated), but it's just not retrieved properly. Since the Converter uses generics, you need to search by type instead of class. I opened an issue in the MyFaces community and provided a patch: :)

https://issues.apache.org/jira/browse/MYFACES-4311

The fix will be included in MyFaces 2.3.7.

Thanks for spotting this one!

I would comment instead, but I don't have enough reputation points yet. :(

I tried to replicate your app with code provided, but wasn't able to get that error, neither in 19.0.0.6 or in 19.0.0.11 (which uses MyFaces 2.3.4) when I tested.

Could you share more your code or provide a sample application that reproduces the error, please?

Thanks!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM