Sebastian Wramba
Sebastian Wramba

Reputation: 10127

ValueChangeListener on custom component leads to PropertyNotFoundException

We have a custom JSF component that renders some buttons and a select box in a specific way. This is done by a class that extends UIInput. This custom component used in the xhtml templates like so:

<xx:fooComponent
    value="#{fooBean.someProperty}" 
    valueChangeListener="#{fooBean.someMethodInBean}"
    someOtherProperties="true" />

Now since we changed from JBoss 4.2.2 running JSF 2.0 to JBoss 7.1.1 running with the built-in JSF libs, it complains about someMethodInBean not being a property. Of course it's not a property, it's a method. Who in the world would bind a property to a valueChangeListener?

At first I thought, this had something to do with the method being in a superclass of the referenced bean, but that wasn't the case. Adding this particular method to FooBean did not make any difference.

So my question is, what did they change so that this breaks now and how can I fix it in a migrating-friendly way?

edit

The component is declared as such in our *.taglib.xml:

<!DOCTYPE facelet-taglib PUBLIC
  "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
  "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">

<!-- ... -->
<tag>
    <tag-name>fooComponent</tag-name>       
    <component>
        <component-type>myProject.FooComponent</component-type>                     
    </component>        
</tag>

... which leads to this declaration in faces-config.xml:

<component>
    <component-type>myProject.FooComponent</component-type>
    <component-class>com.myproject.somemore.UIFooComponent</component-class>
</component>

... which leads to the class UIFooComponent extends UIInput.

edit 2

Now the taglib xml looks like this:

<facelet-taglib version="2.0"
            xmlns="http://java.sun.com/xml/ns/javaee"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd">

<tag>
    <tag-name>fooComponent</tag-name>       
    <component>
        <component-type>myProject.FooComponent</component-type>                     
    </component>
    <attribute>
        <name>valueChangeListener</name>
        <method-signature>void valueChanged(javax.faces.event.ValueChangeEvent)</method-signature>  
    </attribute>        
</tag>
</facelet-taglib>

Still, he complains about fooBean not having the property someMethodInBean.

edit 3

The stack trace is:

Caused by: javax.el.ELException: /abc/abc.xhtml: The class 'com.myproject.managedbeans.foo.FooBean' does not have the property 'someMethodInBean'.
    at com.sun.faces.facelets.compiler.AttributeInstruction.write(AttributeInstruction.java:94)
    at com.sun.faces.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:82)
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:302)
    at com.sun.faces.renderkit.html_basic.GridRenderer.renderRow(GridRenderer.java:185)
    at com.sun.faces.renderkit.html_basic.GridRenderer.encodeChildren(GridRenderer.java:129)
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1779)
    at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1779)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:402)
    at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288)
    at org.apache.myfaces.tomahawk.application.ResourceViewHandlerWrapper.renderView(ResourceViewHandlerWrapper.java:93)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
    ... 21 more

Upvotes: 3

Views: 1905

Answers (1)

BalusC
BalusC

Reputation: 1108782

This indicates that the tag attribute isn't been declared as a <method-signature> in the component's <tag> declaration in the .taglib.xml file as follows:

<attribute>
    <name>valueChangeListener</name>
    <method-signature>void valueChange(javax.faces.event.ValueChangeEvent)</method-signature>
</attribute>

Make sure that this is properly been declared as above.


Update: you need to make sure that you've declared the .taglib.xml file conform JSF 2.x Facelets XSD (and thus not a DTD as it was in legacy Facelets 1.x).

<facelet-taglib
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
    version="2.0"
>

    <!-- Tags here -->

</facelet-taglib>

Upvotes: 4

Related Questions