ICEfaces
  1. ICEfaces
  2. ICE-9404

RuntimeException: Cannot clone document

    Details

    • Salesforce Case Reference:
    • Workaround Exists:
      Yes
    • Workaround Description:
      Either include the required compat jars (icefaces-ee-compat.jar, commons-*.jar) or remove the compat namespace from the page.

      Description

      When declaring the ICEfaces compat component namespace in the xhtml page but not including the required Jar files the following error is thrown in EE 3.3.0 (The same setup is not an issue with EE 3.2.0):

      java.lang.RuntimeException: Cannot clone document
      at org.icefaces.impl.context.DOMResponseWriter.cloneDocument(DOMResponseWriter.java:494)
      at org.icefaces.impl.context.DOMResponseWriter.startSubtreeRendering(DOMResponseWriter.java:486)
      at org.icefaces.impl.context.DOMPartialViewContext.processPartial(DOMPartialViewContext.java:158)
      at javax.faces.component.UIViewRoot.encodeChildren(UIViewRoot.java:973)
      at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1779)
      at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:413)
      at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:124)
      at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
      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 com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1657)
      at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:939)
      at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:502)
      at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:181)
      at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:91)
      at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:864)
      at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1592)
      at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:186)
      at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:452)
      at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:511)
      at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:305)
      at com.ibm.ws.http.channel.inbound.impl.HttpICLReadCallback.complete(HttpICLReadCallback.java:83)
      at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)
      at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
      at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)
      at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)
      at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)
      at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775)
      at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905)
      at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1613)
      Caused by: java.lang.NullPointerException
      at org.icefaces.impl.fastinfoset.com.sun.xml.fastinfoset.util.NamespaceContextImplementation.declarePrefix(NamespaceContextImplementation.java:163)
      at org.icefaces.impl.fastinfoset.com.sun.xml.fastinfoset.dom.DOMDocumentSerializer.serializeElement(DOMDocumentSerializer.java:142)
      at org.icefaces.impl.fastinfoset.com.sun.xml.fastinfoset.dom.DOMDocumentSerializer.serialize(DOMDocumentSerializer.java:78)
      at org.icefaces.impl.context.DOMResponseWriter.serializeDocument(DOMResponseWriter.java:546)
      at org.icefaces.impl.context.DOMResponseWriter.cloneDocument(DOMResponseWriter.java:491)
      ... 30 more

        Issue Links

          Activity

          Hide
          Deryk Sinotte added a comment - - edited

          The customer's test page works fine if it is simply added to showcase and run in that application. Proper behaviour on both Tomcat 7 and WebSphere 7. Building and deploying their whole .war file, it fails on both WebSphere 7 and Tomcat 7. So it's not specific to WebSphere.

          It's a very simple app and once it started failing on Tomcat, it was a bit quicker and easier to track down. They declare these namespaces:

          <html xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:icecore="http://www.icefaces.org/icefaces/core"
                xmlns:ace="http://www.icefaces.org/icefaces/components"
                xmlns:ice="http://www.icesoft.com/icefaces/component">
          

          And these libraries:

          icefaces-ee-ace.jar
          icefaces-ee-ext.jar
          icefaces-ee.jar
          javax.faces.jar
          

          The difference is the compat namespace. Turns out that they don't actually use compat or include the necessary libraries but they have it declared and that's what's causing the problem. It doesn't happen in showcase because compat is declared AND the libraries are present.

          To "fix" it, they can do 1 of two things. Either add the following libs to their .war file:

          commons-logging.jar
          icefaces-ee-compat.jar
          

          or just remove the unused namespace declaration:

          xmlns:ice="http://www.icesoft.com/icefaces/component"
          

          and the problem goes away.

          Show
          Deryk Sinotte added a comment - - edited The customer's test page works fine if it is simply added to showcase and run in that application. Proper behaviour on both Tomcat 7 and WebSphere 7. Building and deploying their whole .war file, it fails on both WebSphere 7 and Tomcat 7. So it's not specific to WebSphere. It's a very simple app and once it started failing on Tomcat, it was a bit quicker and easier to track down. They declare these namespaces: <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:icecore="http://www.icefaces.org/icefaces/core" xmlns:ace="http://www.icefaces.org/icefaces/components" xmlns:ice="http://www.icesoft.com/icefaces/component"> And these libraries: icefaces-ee-ace.jar icefaces-ee-ext.jar icefaces-ee.jar javax.faces.jar The difference is the compat namespace. Turns out that they don't actually use compat or include the necessary libraries but they have it declared and that's what's causing the problem. It doesn't happen in showcase because compat is declared AND the libraries are present. To "fix" it, they can do 1 of two things. Either add the following libs to their .war file: commons-logging.jar icefaces-ee-compat.jar or just remove the unused namespace declaration: xmlns:ice="http://www.icesoft.com/icefaces/component" and the problem goes away.
          Hide
          Deryk Sinotte added a comment -

          In DOMDocumentSerializer.serializeElement method there is the following:

          final String namespaceURI = a.getNamespaceURI();
          if (namespaceURI != null && namespaceURI.equals("http://www.w3.org/2000/xmlns/")) {
              String attrPrefix = a.getLocalName();
              String attrNamespace = a.getNodeValue();
              if (attrPrefix == "xmlns" || attrPrefix.equals("xmlns")) {
                  attrPrefix = "";
              }
              _namespaceScopeContext.declarePrefix(attrPrefix, attrNamespace);
          } else {
              if (attributesSize == _attributes.length) {
                  final Node[] attributes = new Node[attributesSize * 3 / 2 + 1];
                  System.arraycopy(_attributes, 0, attributes, 0, attributesSize);
                  _attributes = attributes;
              }
              _attributes[attributesSize++] = a;
              
              String attrNamespaceURI = a.getNamespaceURI();
              String attrPrefix = a.getPrefix();
              if (attrPrefix != null && !_namespaceScopeContext.getNamespaceURI(attrPrefix).equals(attrNamespaceURI)) {
                  _namespaceScopeContext.declarePrefix(attrPrefix, attrNamespaceURI);
              }
          }
          

          It gets the namespaceURI of the current attribute then checks to see if it is null. If it is null, it falls through to the else block. At the end of the block it again gets the namespaceURI for the attribute but there is no check for null. Instead, it checks:

          attrPrefix != null && !_namespaceScopeContext.getNamespaceURI(attrPrefix).equals(attrNamespaceURI)
          

          So if the prefix is null, nothing happens. But if the prefix is non-null AND the namespaceURI for the prefix doesn't match the attribute namespaceURI it proceeds to call declarePrefix. However, if the namespace for the prefix is non-null AND the attribute namespace IS null, this condition will pass. So the code should probably just have an extra check for null:

          attrPrefix != null && attrNamespaceURI != null && !_namespaceScopeContext.getNamespaceURI(attrPrefix).equals(attrNamespaceURI)
          
          Show
          Deryk Sinotte added a comment - In DOMDocumentSerializer.serializeElement method there is the following: final String namespaceURI = a.getNamespaceURI(); if (namespaceURI != null && namespaceURI.equals( "http: //www.w3.org/2000/xmlns/" )) { String attrPrefix = a.getLocalName(); String attrNamespace = a.getNodeValue(); if (attrPrefix == "xmlns" || attrPrefix.equals( "xmlns" )) { attrPrefix = ""; } _namespaceScopeContext.declarePrefix(attrPrefix, attrNamespace); } else { if (attributesSize == _attributes.length) { final Node[] attributes = new Node[attributesSize * 3 / 2 + 1]; System .arraycopy(_attributes, 0, attributes, 0, attributesSize); _attributes = attributes; } _attributes[attributesSize++] = a; String attrNamespaceURI = a.getNamespaceURI(); String attrPrefix = a.getPrefix(); if (attrPrefix != null && !_namespaceScopeContext.getNamespaceURI(attrPrefix).equals(attrNamespaceURI)) { _namespaceScopeContext.declarePrefix(attrPrefix, attrNamespaceURI); } } It gets the namespaceURI of the current attribute then checks to see if it is null. If it is null, it falls through to the else block. At the end of the block it again gets the namespaceURI for the attribute but there is no check for null. Instead, it checks: attrPrefix != null && !_namespaceScopeContext.getNamespaceURI(attrPrefix).equals(attrNamespaceURI) So if the prefix is null, nothing happens. But if the prefix is non-null AND the namespaceURI for the prefix doesn't match the attribute namespaceURI it proceeds to call declarePrefix. However, if the namespace for the prefix is non-null AND the attribute namespace IS null, this condition will pass. So the code should probably just have an extra check for null: attrPrefix != null && attrNamespaceURI != null && !_namespaceScopeContext.getNamespaceURI(attrPrefix).equals(attrNamespaceURI)
          Hide
          Deryk Sinotte added a comment -

          Attaching test case that shows the issue. It only occurs with 3.3 EE libraries. 3.3 open source libraries are fine.

          Show
          Deryk Sinotte added a comment - Attaching test case that shows the issue. It only occurs with 3.3 EE libraries. 3.3 open source libraries are fine.
          Hide
          Deryk Sinotte added a comment -

          Further investigation shows that the root cause of the problem was related to the method we used to get a "clean" clone of the older DOM. Replacing the serialization algorithm in DOMResponseWriter with the import/set id algorithm that we currently use in the open source version (as per ICE-9398) solves the problem. As this change has already been applied to both icefaces3/trunk and icefaces-ee/tags/icefaces-ee-3.3.0.GA_P01 I am marking as fixed. Testing using the libraries on the current P01 tag shows that the libraries do not show the problem when run with the test case.

          Show
          Deryk Sinotte added a comment - Further investigation shows that the root cause of the problem was related to the method we used to get a "clean" clone of the older DOM. Replacing the serialization algorithm in DOMResponseWriter with the import/set id algorithm that we currently use in the open source version (as per ICE-9398 ) solves the problem. As this change has already been applied to both icefaces3/trunk and icefaces-ee/tags/icefaces-ee-3.3.0.GA_P01 I am marking as fixed. Testing using the libraries on the current P01 tag shows that the libraries do not show the problem when run with the test case.

            People

            • Assignee:
              Deryk Sinotte
              Reporter:
              Arran Mccullough
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: