DuplicateIdException - myfaces 3.02, primefaces 13.0.0, TomEE 9.1

30 Views Asked by At

I have a page with two forms. When an ajax call is made to the backing bean to update text in the calling form, myfaces DuplicateIdException is thrown. When the web socket tag is removed, the form updates as expected.

Looking at the stack trace, the problem appears to be in the myfaces state saving algorithm, but I have zero knowledge in this area.

Any clue how to remedy and still use websocket client?

Thank you

Form 1: <f:websocket> form (because the production application uses a websocket for push notifications)

Form 2: Display for file downloads using Primefaces DataView or Facelets repeat and attempting to do an ajax update on the form. (the DuplicateIdException is identical whether using <p:dataView or <ui:repeat)

Environment: TomEE 9.1, Jakartaee-api 9.1, JSF Apache MyFaces 3.0.2, PrimeFaces 13.0.0, OmniFaces 4.2

The stack trace:

    SEVERE: Component with duplicate id "j_id__v_6" found. The first component is {Component-Path : [Class: jakarta.faces.component.UIViewRoot,ViewId: /test-pages/test-dup-ids.xhtml][Class: org.apache.myfaces.component.ComponentResourceContainer,Id: jakarta_faces_location_head][Class: jakarta.faces.component.UIOutput,Id: j_id__v_6]}
org.apache.myfaces.view.facelets.compiler.DuplicateIdException: Component with duplicate id "j_id__v_6" found. The first component is {Component-Path : [Class: jakarta.faces.component.UIViewRoot,ViewId: /test-pages/test-dup-ids.xhtml][Class: org.apache.myfaces.component.ComponentResourceContainer,Id: jakarta_faces_location_head][Class: jakarta.faces.component.UIOutput,Id: j_id__v_6]}
    at org.apache.myfaces.view.facelets.compiler.CheckDuplicateIdFaceletUtils.createAndQueueException(CheckDuplicateIdFaceletUtils.java:150)
    at org.apache.myfaces.view.facelets.compiler.CheckDuplicateIdFaceletUtils.checkIds(CheckDuplicateIdFaceletUtils.java:105)
    at org.apache.myfaces.view.facelets.compiler.CheckDuplicateIdFaceletUtils.checkIds(CheckDuplicateIdFaceletUtils.java:120)
    at org.apache.myfaces.view.facelets.compiler.CheckDuplicateIdFaceletUtils.checkIds(CheckDuplicateIdFaceletUtils.java:120)
    at org.apache.myfaces.view.facelets.compiler.CheckDuplicateIdFaceletUtils.checkIds(CheckDuplicateIdFaceletUtils.java:114)
    at org.apache.myfaces.view.facelets.compiler.CheckDuplicateIdFaceletUtils.checkIds(CheckDuplicateIdFaceletUtils.java:87)
    at org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy.saveView(DefaultFaceletsStateManagementStrategy.java:724)
    at org.apache.myfaces.application.StateManagerImpl.saveView(StateManagerImpl.java:213)
    at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.renderView(FaceletViewDeclarationLanguage.java:1923)
    at org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:315)
    at jakarta.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:73)
    at jakarta.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:73)
    at org.omnifaces.viewhandler.OmniViewHandler.renderView(OmniViewHandler.java:166)
    at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:122)
    at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:266)
    at jakarta.faces.webapp.FacesServlet.service(FacesServlet.java:206)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:223)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
    at org.apache.openejb.server.httpd.EEFilter.doFilter(EEFilter.java:67)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
    at io.smallrye.metrics.jaxrs.JaxRsMetricsServletFilter.doFilter(JaxRsMetricsServletFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.tomee.catalina.OpenEJBSecurityListener$RequestCapturer.invoke(OpenEJBSecurityListener.java:97)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:356)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:870)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1762)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:1589)

test.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
xmlns:p="http://primefaces.org/ui">

<h:form id="websocket-form">

    <f:websocket id="websocket-0" 
        channel="_pushContext">
        <f:ajax event="updateNotifications" render=":messaging-menu" />
    </f:websocket>

</h:form> 

<h:form id="list-form"> 
    <div style="text-align:center">
        <h2>
            <h:outputText value="#{testBeanDuplicateIds.heading}" />
        </h2>
    </div>
    <ui:repeat var="item" 
            value="#{testBeanDuplicateIds.itemList}">
        <div class="row">
            <p:outputPanel style="text-align:center;">
                <h:outputText value="#{item.name}"/>
            </p:outputPanel>
            <p:outputPanel style="text-align:center;">
                <p:commandButton id="download-button-#{item.id}"
                        onclick="PrimeFaces.monitorDownload(startDownload, stopDownload);"
                        value="Download Flyer"
                        ajax="false"
                        >
                        
                    <p:fileDownload id="download-#{item.id}-file-download" 
                            value="#{testBeanDuplicateIds.testFileDownload}"/>
                </p:commandButton> 
                    
                <p:commandButton id="button-#{item.id}-button"
                        actionListener="#{testBeanDuplicateIds.doSomething(item.id)}"
                        value="Do #{item.name}"
                        ajax="true"
                        update="@form">
                </p:commandButton> 
                    
            </p:outputPanel>
        </div>              
    </ui:repeat>    
</h:form>

<script>
    //<![CDATA[
    function startDownload() {
        PF('statusDialog').show();
    }

    function stopDownload() {
        PF('statusDialog').hide();
    }
    //]]>
</script>   

<p:dialog id="status-dialog"
        modal="true" 
        widgetVar="statusDialog" 
        header="Downloading" 
        draggable="false" 
        closable="false"
        resizable="false">
    <i class="pi pi-spinner pi-spin" style="font-size:3rem" />
</p:dialog>       

TestBeanDuplicateIds.java

package com.ui.testbeans;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;

import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

import jakarta.annotation.PostConstruct;
import jakarta.faces.context.ExternalContext;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;

@Named
@ViewScoped
public class TestBeanDuplicateIds implements Serializable
{
    private static final long serialVersionUID = 1L;

    private StreamedContent _testFileDownload;

    private ArrayList<Product> _itemList;
    private String _heading;
    
    @PostConstruct
    public void init()
    {
        _heading = "Testing Duplicate IDs";
        buildTestFileDownload();
        _itemList = new ArrayList<Product>();
        for(int index = 0; index < 4; index++)
        {
            String name = "Item-" + index;
            String description = name + " description";
            Product product =
                    new Product(index, name, description);
            _itemList.add(product);
        }
    }
    
    private void buildTestFileDownload()
    {
        String absolutePath = "/resources/default/testFolder/flyer.pdf";
       
        try
        {
            InputStream inputStream;
            ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
            inputStream = externalContext.getResourceAsStream(absolutePath);
            
            _testFileDownload = DefaultStreamedContent.builder()
                    .name("sample_pdf.pdf")
                    .contentType("application/pdf")
                    .stream(() -> inputStream)
                    .build();
            
            if (inputStream != null)
            {
                inputStream.close();    
            }
            else
            {
                String nullWarning = "InputStream was null!";
                throw new IOException(nullWarning);
            }
        } 
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
    
    public void doSomething(String name)
    {
        System.out.println("Doing: " + name);
        _heading = "Testing " + name;
    }

    public StreamedContent getTestFileDownload()
    {
        return _testFileDownload;
    }

    public void setTestFileDownload(StreamedContent testFileDownload)
    {
        _testFileDownload = testFileDownload;
    }

    public ArrayList<Product> getItemList()
    {
        return _itemList;
    }

    public void setItemList(ArrayList<Product> itemList)
    {
        _itemList = itemList;
    }

    public String getHeading()
    {
        return _heading;
    }

    public void setHeading(String heading)
    {
        _heading = heading;
    }
}

Product.java

package com.ui.testbeans;


public class Product
{
    private Integer _id;
    private String _name;
    private String _description;
    
    Product(){}
    
    Product(Integer id, String name, String description)
    {
        _id = id;
        _name = name;
        _description = description;
    }   
    
    public Integer getId()
    {
        return _id;
    }
    public void setId(Integer id)
    {
        _id = id;
    }
    public String getName()
    {
        return _name;
    }
    public void setName(String name)
    {
        _name = name;
    }
    public String getDescription()
    {
        return _description;
    }
    public void setDescription(String description)
    {
        _description = description;
    }   
}

pom.xml

 <dependencies>
    <dependency>
        <groupId>jakarta.platform</groupId>
        <artifactId>jakarta.jakartaee-api</artifactId>
        <version>9.1.0</version>
        <scope>provided</scope>
    </dependency>   
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.2.2</version>
    </dependency>
    <dependency>
        <groupId>org.primefaces</groupId>
        <artifactId>primefaces</artifactId>
        <version>13.0.0</version>
        <classifier>jakarta</classifier>
    </dependency>
    <dependency>
        <groupId>org.omnifaces</groupId>
        <artifactId>omnifaces</artifactId>
        <version>4.2</version>
    </dependency>   
    <dependency>
        <groupId>org.apache.myfaces.core</groupId>
        <artifactId>myfaces-api</artifactId>
        <version>3.0.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.myfaces.core</groupId>
        <artifactId>myfaces-impl</artifactId>
        <version>3.0.2</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>jakarta.websocket</groupId>
        <artifactId>jakarta.websocket-client-api</artifactId>
        <version>2.1.1</version>
        <scope>provided</scope>
    </dependency>
</dependencies> 
0

There are 0 best solutions below