Custom taglib results in MethodNotFoundException

1k views Asked by At

What I want to do is declare a common datatable header as a composite component. But this answer set me straight since it was not rendered:

How to create a composite component for a datatable column?

Basically it instructed me to try my own taglib and this works really well except my header has a link in it that does reRender. When this link is pressed MethodNotFoundException is thrown.

This is my custom taglib:

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <namespace>http://stackoverflowdummy.com/dumb/components</namespace>
    <tag>
        <tag-name>tableHeader</tag-name>
        <source>tags/tableHeader.xhtml</source>
        <attribute>
            <description></description>
            <name>value</name>
        </attribute>
        <attribute>
            <description>The listener that handles sorting</description>
            <name>sortAction</name>
            <method-signature>java.lang.String action()</method-signature>
        </attribute>
        <attribute>
            <description>The property that holds the current id to sort on
            </description>
            <name>sortValue</name>
        </attribute>
        <attribute>
            <description>The component that needs to be updated after changes
            </description>
            <name>reRender</name>
        </attribute>
    </tag>
</facelet-taglib>

I tried without method-signature and I also tried removing "action". My web.xml does include the taglib like this:

<context-param>
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
    <param-value>/WEB-INF/cc.taglib.xml</param-value>
</context-param>

I also tried with "facelets.LIBRARIES" but it made no difference.

            <h:commandLink value="#{o.label}" action="#{sortAction}" immediate="true" reRender="#{reRender}">
                <f:setPropertyActionListener target="#{sortValue}" value="#{o.column.sortId}" />
            </h:commandLink>

End usage is defined like this:

sortAction="#{myBean.sort}"

That bean has a method called with signature String sort(); and it works really well if I just define it and skip using my own tag. However everything works with the tag except the action method...

1

There are 1 answers

1
L-Ray On BEST ANSWER

The JavaBean Specification gives multiple ways on how to call a method. In fact, you can call a action the normal way #{actionBean.actionMethod}, but also the way #{actionBean['actionMethod']}.

The sorting Action you are giving is transferred as a MethodExpression, which compared to ValueExpressions gave me problems in some JSF Environments.

What I'd like you to try testwise is, to give the action as two separate (value) parameters:

  • sortActionBean="#{myBean}"
  • sortActionMethod="sort"

and call those in the template as #{sortActionBean['sortActionMethod']}. A good article on this topic is Passing action methods facelets tags.

Hope it helps...