ICEfaces
  1. ICEfaces
  2. ICE-8458

Exception thrown when dropdown option contains the $ character in h:selectOneMenu with f:ajax

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.1, EE-3.3.0.GA_P01
    • Fix Version/s: 4.0.BETA, EE-3.3.0.GA_P02, 4.0
    • Component/s: ICE-Components
    • Labels:
      None
    • Environment:
      ICEFaces 3.1, Apache 6.0.18, Java 6
    • Assignee Priority:
      P2
    • Salesforce Case Reference:

      Description

      In process of attempting to upgrade a working application from ICEFaces 2.0.2 to ICEFace 3.1, I encountered the exception similar to the exception below. The exception below is generated by the example code I am rpoviding.

      I found that the presence of the $ character in one or more of the option values in the selectOneMenu that uses f:ajax will cause the exception when DOMPartialViewContext.applyBrowserChanges() calls appendReplacement().
      In our application the data used to build the options is stored in a relational database and in some cases are entered by the application users.
      I have built a stripped down example of code that will trigger the exception. I built it as an addition to the ICEFaces showcase samples.

      The example by default (tTrigger Exception = No) does not create an exception and allows you to exercise the drop down without a option containing the character $.
      You can then use the radio button to select a list of available options that do contain the character $ and see the exception generated.


      selectOneMenu.xhtml

      <?xml version="1.0"?>
      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:c="http://java.sun.com/jsp/jstl/core"
          xmlns:ace="http://www.icefaces.org/icefaces/components"
          xmlns:ice="http://www.icesoft.com/icefaces/component"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          template="/resources/templates/content-template.xhtml">
          
          <ui:param name="title" value="#{msgs[selectOneMenu.title]}"/>
          <ui:param name="description" value="#{msgs[selectOneMenu.description]}"/>
          <ui:param name="resourceValue" value="#{selectOneMenu.exampleResource}"/>
          
          <ui:param name="wikiResources" value="#{compatComponentsResources.wikiResources}"/>
          <ui:param name="tldResources" value="#{compatComponentsResources.tldResources}"/>
          
          <ui:define name="example">
           <h:form>
           <h:panelGroup>
               <h:outputLabel for="triggerException" value="Trigger Exception?"/>
                   <h:selectOneRadio id="triggerException" styleClass="radioButtons" value="#{selectOneMenu.triggerException}">
                       <f:selectItem itemValue="true" itemLabel="Yes"/>
                       <f:selectItem itemValue="false" itemLabel="No"/>
                       <f:ajax execute="@this" render="@all"/>
                   </h:selectOneRadio>
                   <h:message for="triggerException"/>
      </h:panelGroup>
          
                  <h:panelGroup>
                      <h:outputLabel for="currency" value="Select Currency:"/>
                      <h:selectOneMenu id="currency" value="#{selectOneMenu.currency}"
                                       required="true">
                           <f:selectItems value="#{selectOneMenu.availableCurrencies}"/>
                           <f:ajax execute="@this" render="@all"/>
                      </h:selectOneMenu>
                      <h:message for="currency"/>
                  </h:panelGroup>
              </h:form>
          </ui:define>
      </ui:composition>

      selectOneMenu.java


      package org.icefaces.samples.showcase.example.compat.selectOneMenu;

      import java.io.Serializable;

      import javax.annotation.PostConstruct;
      import javax.faces.bean.CustomScoped;
      import javax.faces.bean.ManagedBean;
      import javax.faces.event.ActionEvent;
      import javax.faces.context.FacesContext;
      import javax.servlet.http.HttpSession;
      import javax.faces.model.SelectItem;

      import org.icefaces.samples.showcase.metadata.annotation.ComponentExample;
      import org.icefaces.samples.showcase.metadata.annotation.ExampleResource;
      import org.icefaces.samples.showcase.metadata.annotation.ExampleResources;
      import org.icefaces.samples.showcase.metadata.annotation.Menu;
      import org.icefaces.samples.showcase.metadata.annotation.MenuLink;
      import org.icefaces.samples.showcase.metadata.annotation.ResourceType;
      import org.icefaces.samples.showcase.metadata.context.ComponentExampleImpl;

      @ComponentExample(
              title = "example.compat.selectOneMenu.title",
              description = "example.compat.selectOneMenu.description",
              example = "/resources/examples/compat/selectOneMenu/selectOneMenu.xhtml"
      )
      @ExampleResources(
              resources ={
                  // xhtml
                  @ExampleResource(type = ResourceType.xhtml,
                          title="selectOneMenu.xhtml",
                          resource = "/resources/examples/compat/"+
                                     "selectOneMenu/selectOneMenu.xhtml"),
                  // Java Source
                  @ExampleResource(type = ResourceType.java,
                          title="SelectOneMenu.java",
                          resource = "/WEB-INF/classes/org/icefaces/samples/"+
                                     "showcase/example/compat/selectOneMenu/SelectOneMenu.java")
              }
      )
      @Menu(
      title = "menu.compat.selectOneMenu.subMenu.title",
      menuLinks = {
                  @MenuLink(title = "menu.compat.selectOneMenu.subMenu.main", isDefault = true, exampleBeanName = SelectOneMenu.BEAN_NAME)
      })
      @ManagedBean(name= SelectOneMenu.BEAN_NAME)
      @CustomScoped(value = "#{window}")
      public class SelectOneMenu extends ComponentExampleImpl<SelectOneMenu> implements Serializable {

      public static final String BEAN_NAME = "selectOneMenu";

          private SelectItem[] availableCurrencies = new SelectItem[] {
                  new SelectItem("USD"),
                  new SelectItem("CAD")
          };
          
          private SelectItem[] availableCurrenciesTriggerException = new SelectItem[] {
                  new SelectItem("USD$"),
                  new SelectItem("CAD$")
          };
          
          private String currency = availableCurrencies[0].getValue().toString();
          private Boolean triggerException = false;
          
          public SelectItem[] getAvailableCurrencies() {
           if( triggerException ){
           return availableCurrenciesTriggerException;
           }
           return availableCurrencies;
          }
          
          public String getCurrency() { return currency; }
          public void setCurrency(String currency) { this.currency = currency; }
          public void setTriggerException(Boolean triggerException){ this.triggerException = triggerException; }
          public Boolean getTriggerException(){ return this.triggerException; }
          

      public SelectOneMenu() {
      super(SelectOneMenu.class);
      }

          @PostConstruct
          public void initMetaData() {
              super.initMetaData();
          }

      }




      SEVERE: Error Rendering View[/showcase.xhtml]
      java.lang.IllegalArgumentException: Illegal group reference
      at java.util.regex.Matcher.appendReplacement(Matcher.java:713)
      at org.icefaces.impl.context.DOMPartialViewContext.applyBrowserChanges(DOMPartialViewContext.java:531)
      at org.icefaces.impl.context.DOMPartialViewContext.processPartial(DOMPartialViewContext.java:130)
      at javax.faces.component.UIViewRoot.encodeChildren(UIViewRoot.java:981)
      at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1757)
      at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:391)
      at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
      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)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
      at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:568)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
      at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
      at java.lang.Thread.run(Thread.java:619)

        Activity

        Hide
        Ken Fyten added a comment -
        Show
        Ken Fyten added a comment - Looks like this could be a solution: http://tech.soronthar.com/2007/12/javalangillegalargumentexcepti.html
        Hide
        Mircea Toma added a comment -

        Escape the content of the text node that contains the options markup (using http://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html#quoteReplacement(java.lang.String) ) to avoid regex matching confusion.

        Show
        Mircea Toma added a comment - Escape the content of the text node that contains the options markup (using http://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html#quoteReplacement(java.lang.String ) ) to avoid regex matching confusion.
        Hide
        Mircea Toma added a comment -

        Back-ported fix.

        Show
        Mircea Toma added a comment - Back-ported fix.

          People

          • Assignee:
            Mircea Toma
            Reporter:
            Chuck Reese
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: