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.
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.