jsfprimefacescomponentspropertynotfoundexception

Extending p:fileUpload throws jakarta.el.PropertyNotFoundException: The class does not have the property 'upload'


When I try to extend primefaces fileupload, the listener attribute value is resolved as a ValueExpression in the getListener() and a PropertyNotFoundException is thrown.

My Environment:

Here the exception:

Caused by: jakarta.el.PropertyNotFoundException: The class 'org.test.component.FileUploadBean_ClientProxy' does not have the property 'upload'.
        at jakarta.el.BeanELResolver.getBeanProperty(BeanELResolver.java:626)
        at jakarta.el.BeanELResolver.getValue(BeanELResolver.java:338)
        at jakarta.el.CompositeELResolver.getValue(CompositeELResolver.java:136)
        at org.apache.el.parser.AstValue.getValue(AstValue.java:169)
        at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:190)
        at org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression.getValue(ContextAwareTagValueExpression.java:100)
        ... 50 more

It was with quarkus (3.6.5), primefaces 13.0.3, myfaces 4.0.1. But I also get the same issue in Tomcat 10, primefaces 13.0.3, jakarta.faces 4.0.5, weld-servlet-shaded 4.0.0.Final.

If I directly use the primefaces component <p:fileUpload>, it's working fine, and the upload method is called.

Is there a way to make it works using @FacesComponent.

Here my custom fileupload:

@FacesComponent(value = "org.test.component.FileUpload", tagName = "fileUpload", namespace = "mycomponents", createTag = true)
public class FileUpload extends org.primefaces.component.fileupload.FileUpload {}

The java bean with the upload method:

@Named
@RequestScoped
public class FileUploadBean implements Serializable {
  public void upload(FileUploadEvent event) {
    System.out.println("Upload: " + event.getFile().getFileName());
  }
}

The xhtml page:

<!DOCTYPE html>
<html 
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:faces="jakarta.faces"
  xmlns:ui="jakarta.faces.facelets"
  xmlns:f="jakarta.faces.core"
  xmlns:h="jakarta.faces.html"
  xmlns:p="http://primefaces.org/ui"
  xmlns:w="mycomponents"
>
<h:head>
  <meta charset="UTF-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>Test</title>
</h:head>
<h:body>
  <h:form enctype="multipart/form-data">
    <!-- Get PropertyNotFoundExpression -->
    <w:fileUpload listener="#{fileUploadBean.upload}" auto="true"/>

    <!-- Works fine -->
    <p:fileUpload listener="#{fileUploadBean.upload}" auto="true"/>
  </h:form>
</h:body>
</html>

I tried to use the following EL

#{fileUploadBean.upload(event)}

The upload method is called but the event is null.


Solution

  • I get it work by using the taglib xml file and the primefaces fileupload handler.

    In "mycomponents.taglib.xml":

    <facelet-taglib version="4.0"
                    xmlns="https://jakarta.ee/xml/ns/jakartaee"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-facelettaglibrary_4_0.xsd"
    >
      <namespace>mycomponents</namespace>
      <tag>
        <tag-name>fileUpload</tag-name>
        <component>
          <component-type>org.test.component.FileUpload</component-type>
          <handler-class>org.primefaces.component.fileupload.FileUploadHandler</handler-class>
        </component>
      </tag>
    </facelet-taglib>
    

    In the custom component "FileUpload.java":

    
    @FacesComponent(value = "org.test.component.FileUpload")
    public class FileUpload extends org.primefaces.component.fileupload.FileUpload {}
    

    I'm pretty sure there's other solutions, but for now it's the best if found.