'JSF 2.2 (Mojarra) calls f:ajax twice in nested composite:component

i've got a pretty simple example:

there is a nested composite component.

on my index.xhtml is a component called "ht:wrapper" to which are registered some ajax listeners for onKeyup and onChange events.

the compostite component "ht:wrapper" itself provides some clientBehaviors for given events and a nested compostite component "ht:input" this inner component is a simple h:inputText with clientBehaviors registered for keyup and change.

the ajax listener on index.xhtml will call a javascript function which adds the name of the event ("onKeyup" or "onChange") to a at the bottom of the input.

my problem: "onKeyup" fires twice if i press/release a single button.

is this a bug or im i dooing something wrong?

some tests with myfaces 2.2 seems to work as expected and fires only one event at a time.

here my minimum example:

index.xhtml

<h:form id="htmlForm">
    <p>
        This is a simple example how a behavior (keyup, change) gets called twice. <br /> 
        A simple h:inputText is nested in a composite component,
        which provides clientBehaviors.
    </p>

    <ht:wrapper
        id="htmlWrapper"
        value="#{myBean.htmlString}">
        <f:ajax
            event="onKeyup"
            onevent="add('onKeyup')" />
        <f:ajax
            event="onChange"
            onevent="add('onChange')" />
    </ht:wrapper>

    <script>
        function add(s) {
            $('#htmlBehavior').append('<div>' + s + '</div>');
        }
    </script>
    <div
        id="htmlBehavior"
        style="margin-top:10px; width: 250px; background-color: #ccc; border: 1px solid #472; padding: 5px">
        <div>
            <b>Triggered Behaviors:</b>
        </div>
    </div>
</h:form>

ht:wrapper

    <cc:interface shortDescription="my simple input wrapper">
    <cc:attribute
        name="value"
        required="true" />

    <cc:clientBehavior
        name="onKeyup"
        targets="inputWrapper"
        event="onKeyup" />

    <cc:clientBehavior
        name="onChange"
        targets="inputWrapper"
        event="onChange" />
</cc:interface>

<cc:implementation>
    <ht:input
        id="inputWrapper"
        value="#{cc.attrs.value}" />
</cc:implementation>

ht:input

<cc:interface shortDescription="my input">

    <cc:attribute
        name="value"
        required="true" />

    <cc:clientBehavior
        name="onKeyup"
        targets="inputId"
        event="keyup" />

    <cc:clientBehavior
        name="onChange"
        targets="inputId"
        event="change" />

</cc:interface>

<cc:implementation>

    <h:inputText
        id="inputId"
        value="#{cc.attrs.value}" />

</cc:implementation>

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>com.my.example</groupId>
    <artifactId>behavior</artifactId>
    <packaging>war</packaging>
    <version>1.0</version>
    
    
    <properties>
        <jetty.version>9.4.46.v20220331</jetty.version>
        <mojarra.version>2.2.20</mojarra.version>
        <myfaces.version>2.2.14</myfaces.version>
    </properties>

    <!-- Project dependencies -->
    <dependencies>
        
        <!-- Mojarra 2.2-->
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-api</artifactId>
            <version>${mojarra.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-impl</artifactId>
            <version>${mojarra.version}</version>
            <scope>compile</scope>
        </dependency>
        
         
        <!-- MyFaces 2.2 -->
        <!-- 
        <dependency>
             <groupId>org.apache.myfaces.core</groupId>
             <artifactId>myfaces-api</artifactId>
             <version>${myfaces.version}</version>
        </dependency>
        <dependency>
             <groupId>org.apache.myfaces.core</groupId>
             <artifactId>myfaces-impl</artifactId>
             <version>${myfaces.version}</version>
        </dependency>
         -->
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>${jetty.version}</version>
            </plugin>
        </plugins>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source