Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ID of composite component gets initialized early without parent IDs when it's referenced in f:ajax execute attribute #5415

Closed
Hurz opened this issue Mar 7, 2024 · 1 comment
Milestone

Comments

@Hurz
Copy link

Hurz commented Mar 7, 2024

Accessing the clientId of a composite component can be initialized early in its lifecycle when referencing it in a f:ajax execute. This early initialization will prevent the component to being aware of its parents and can therefore cause duplicate ID errors.

To Reproduce

I've attached a sample application DemoDuplicateComponentBug.zip. Here is the code of the involved components of the sample application:

index.xhtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:b="http://xmlns.jcp.org/jsf/composite/base-components"
      xmlns:h="http://xmlns.jcp.org/jsf/html">

<body>

  <h:form id="contentForm">
    <b:outerComponent id="firstInstanceOfOuterComponent" />
    <b:outerComponent id="secondInstanceOfOuterComponent" />
  </h:form>

</body>
</html>

outerComponent.xhtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:b="http://xmlns.jcp.org/jsf/composite/base-components"
      xmlns:composite="http://xmlns.jcp.org/jsf/composite">

<composite:interface>
</composite:interface>

<composite:implementation>

        <b:middleComponent id="middleComponentInOuterComponent"/>

</composite:implementation>
</html>

middleComponent.xhtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:b="http://xmlns.jcp.org/jsf/composite/base-components"
      xmlns:composite="http://xmlns.jcp.org/jsf/composite">

<composite:interface>
</composite:interface>

<composite:implementation>
    <b:innerComponent>
      <!--
       this will fail as long as the clientId is referenced in the execute attribute.
       Any other references to the clientId (e.g. in the render tag) works.
      -->
      <f:ajax execute="#{cc.clientId}" event="change"/>
      <!-- This works and will not cause a duplicate ID error:
      <f:ajax render="#{cc.clientId}" event="change"/>
      -->
    </b:innerComponent>
</composite:implementation>
</html>

innerComponent.xhtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:composite="http://xmlns.jcp.org/jsf/composite"
>

<composite:interface>
  <composite:clientBehavior name="change"
                            event="change"
                            targets="input"/>
</composite:interface>

<composite:implementation>
      <h:selectOneMenu id="input"/>
</composite:implementation>
</html>

Running this on the newest Wildfly 31.0.1.Final and opening http://localhost:8080/web-application/ will result in a duplicate component ID error of "middleComponentInOuterComponent". Referencing the cc.clientId in any other way will not cause this error. Here is the Stacktrace (sorry for the german error output):

jakarta.servlet.ServletException: Komponenten-ID middleComponentInOuterComponent wurde bereits in der Ansicht gefunden.
	at jakarta.faces.impl@4.0.5//jakarta.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:709)
	at jakarta.faces.impl@4.0.5//jakarta.faces.webapp.FacesServlet.service(FacesServlet.java:449)
	at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
	at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
	at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
	at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
	at org.wildfly.security.elytron-web.undertow-server@4.0.0.Final//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.lambda$handleRequest$1(ElytronRunAsHandler.java:68)
	at org.wildfly.security.elytron-base@2.2.3.Final//org.wildfly.security.auth.server.FlexibleIdentityAssociation.runAsFunctionEx(FlexibleIdentityAssociation.java:103)
	at org.wildfly.security.elytron-base@2.2.3.Final//org.wildfly.security.auth.server.Scoped.runAsFunctionEx(Scoped.java:161)
	at org.wildfly.security.elytron-base@2.2.3.Final//org.wildfly.security.auth.server.Scoped.runAs(Scoped.java:73)
	at org.wildfly.security.elytron-web.undertow-server@4.0.0.Final//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.handleRequest(ElytronRunAsHandler.java:67)
	at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
	at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117)
	at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
	at io.undertow.core@2.3.12.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.core@2.3.12.Final//io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
	at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
	at io.undertow.core@2.3.12.Final//io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
	at org.wildfly.security.elytron-web.undertow-server-servlet@4.0.0.Final//org.wildfly.elytron.web.undertow.server.servlet.CleanUpHandler.handleRequest(CleanUpHandler.java:38)
	at io.undertow.core@2.3.12.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at org.wildfly.extension.undertow@31.0.1.Final//org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:44)
	at io.undertow.core@2.3.12.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at org.wildfly.extension.undertow@31.0.1.Final//org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:51)
	at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52)
	at io.undertow.core@2.3.12.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:276)
	at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
	at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:132)
	at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
	at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
	at org.wildfly.extension.undertow@31.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1413)
	at org.wildfly.extension.undertow@31.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1413)
	at org.wildfly.extension.undertow@31.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1413)
	at org.wildfly.extension.undertow@31.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1413)
	at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:256)
	at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:101)
	at io.undertow.core@2.3.12.Final//io.undertow.server.Connectors.executeRootHandler(Connectors.java:393)
	at io.undertow.core@2.3.12.Final//io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:859)
	at org.jboss.threads@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
	at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
	at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
	at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1348)
	at org.jboss.xnio@3.8.13.Final//org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282)
	at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.IllegalStateException: Komponenten-ID middleComponentInOuterComponent wurde bereits in der Ansicht gefunden.
	at jakarta.faces.impl@4.0.5//com.sun.faces.util.Util.checkIdUniqueness(Util.java:1197)
	at jakarta.faces.impl@4.0.5//com.sun.faces.util.Util.checkIdUniqueness(Util.java:1186)
	at jakarta.faces.impl@4.0.5//com.sun.faces.util.Util.checkIdUniqueness(Util.java:1186)
	at jakarta.faces.impl@4.0.5//com.sun.faces.util.Util.checkIdUniqueness(Util.java:1186)
	at jakarta.faces.impl@4.0.5//com.sun.faces.application.view.FaceletPartialStateManagementStrategy.saveView(FaceletPartialStateManagementStrategy.java:434)
	at jakarta.faces.impl@4.0.5//com.sun.faces.application.view.WriteBehindStateWriter.getState(WriteBehindStateWriter.java:290)
	at jakarta.faces.impl@4.0.5//com.sun.faces.application.view.WriteBehindStateWriter.flushToWriter(WriteBehindStateWriter.java:188)
	at jakarta.faces.impl@4.0.5//com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:463)
	at jakarta.faces.impl@4.0.5//com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:163)
	at jakarta.faces.impl@4.0.5//jakarta.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:125)
	at jakarta.faces.impl@4.0.5//com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:93)
	at jakarta.faces.impl@4.0.5//com.sun.faces.lifecycle.Phase.doPhase(Phase.java:72)
	at jakarta.faces.impl@4.0.5//com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:150)
	at jakarta.faces.impl@4.0.5//jakarta.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:692)
	... 43 more

Expected behavior

Expected behavior is the rendering of two components with the IDs contentForm:firstInstanceOfOuterComponent:middleComponentInOuterComponent:j_idt2:input and contentForm:firstInstanceOfOuterComponent:middleComponentInOuterComponent:j_idt5:input or similar chained IDs.

Environment:

  • Error validated with Wildfly Version 26.0.1.Final to 31.0.1.Final (Mojarra JSF 2.3.17.SP01 to Mojarra Jakarta Faces 4.0.5)
  • Worked with Wildfly 25.0.1.Final with Mojarra JSF 2.3.14.SP04

To modify the attached reproducer for Wildfly versions before 27 simply replace the jakarta with javax of the Faces Servlet in the web.xml.

@BalusC
Copy link
Contributor

BalusC commented Mar 16, 2024

OK, this is regression of jakartaee/faces#1567

Work around for now, use execute="@this" instead of execute="#{cc.clientId}". Removing execute attribute should also work as that should default to @this nonetheless.

BalusC added a commit to jakartaee/faces that referenced this issue Mar 16, 2024
arjantijms added a commit that referenced this issue Mar 17, 2024
#5415: move retargeted client ID calculation from AjaxHandler to AjaxBehaviorRenderer so it doesn't fail when cc.clientId happens to be referenced in f:ajax execute
arjantijms added a commit to jakartaee/faces that referenced this issue Mar 17, 2024
BalusC added a commit that referenced this issue Mar 18, 2024
@BalusC BalusC closed this as completed in 51a688b Mar 18, 2024
BalusC added a commit that referenced this issue Mar 18, 2024
@BalusC BalusC added this to the 4.0.7 milestone Mar 18, 2024
pizzi80 added a commit to pizzi80/mojarra that referenced this issue Mar 25, 2024
+ eclipse-ee4j#5415: move retargeted client ID calculation from AjaxHandler to AjaxBehaviorRenderer so it doesn't fail when cc.clientId happens to be referenced in f:ajax execute

Signed-off-by: pizzi80 <paolo@given2.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants