Question

I tried to add OmniFaces HTML5 support to a project without success. ICEFaces throws an severity error:

ICEfaces rendering required by icefaces-compat.jar components. Enable via <icecore:config render="true" />.
Error Renter code hereendering View[/index.xhtml]

So I added icecore:config render="true" but it didn't work, throws same error.

Not sure if it's a configuration mistake. What I've done is add to web.xml:

<context-param>
    <param-name>org.omnifaces.HTML5_RENDER_KIT_PASSTHROUGH_ATTRIBUTES</param-name>
    <param-value>
        javax.faces.component.UIInput=x-webkit-speech,x-webkit-grammar;
        javax.faces.component.UIComponent=contenteditable,draggable
    </param-value>
</context-param>

And in faces-config:

<factory>
    <render-kit-factory>org.omnifaces.renderkit.Html5RenderKitFactory</render-kit-factory>
</factory>

If "factory" is removed from faces-config, the project works but without HTML5 support. It seems that HTML5 render kit overrides the icefaces's kit.

One other thing that makes me think it's a config mistake is that NetBeans underlines "placeholder" attribute in an h:inputText.

Was it helpful?

Solution

Indeed, as I suspected, ICEfaces thinks it's being the only JSF library in the webapp and is performing an immediate instanceof check on the FacesContext#getResponseWriter() without inspecting the wrapped ones. Here's an extract from ICEfaces' DOMContext class:

85         ResponseWriter responseWriter = facesContext.getResponseWriter();
86         DOMResponseWriter domWriter;
87         if (responseWriter instanceof DOMResponseWriter) {
88             domWriter = (DOMResponseWriter) responseWriter;
89         } else {
90 //            domWriter = createTemporaryDOMResponseWriter(responseWriter, facesContext);
91             log.severe("ICEfaces rendering required by icefaces-compat.jar " +
92                       "components. Enable via <icecore:config render=\"true\" />.");
93             throw new UnsupportedOperationException("ICEfaces rendering required.");
94         }

(note: starting at line 222 there's a similar block)

In theory, you could workaround this by explicitly registering the ICEfaces renderkit factory after the OmniFaces one in faces-config.xml. However, I couldn't find a RenderKitFactory in the ICEfaces source code who's responsible for creating the DOMRenderKit. It appears that ICEfaces thinks it's a JSF implementation by itself and altogether overriding the default JSF implementation's HTML_BASIC renderkit as follows in its /META-INF/faces-config.xml:

<render-kit>
    <render-kit-id>HTML_BASIC</render-kit-id>
    <render-kit-class>org.icefaces.impl.renderkit.DOMRenderKit</render-kit-class>
</render-kit>

All in all, ICEfaces doesn't make it possible anymore to wrap the render kits via a factory. This is not so nice. Note that the extracted source contains an outcommented line referencing createTemporaryDOMResponseWriter() which does its job -almost- right. Perhaps they couldn't figure why it didn't always work and left it for what it was. Too bad.

The workaround would be to copy the DOMContext class into your webapp, in its original package (once deployed, classes in /WEB-INF/classes have precedence over the ones in /WEB-INF/lib, so the custom copy would be loaded instead of the ICEfaces one) and change the code starting at line 85 as follows and remove the entire if-else block thereafter:

85         ResponseWriter responseWriter = facesContext.getResponseWriter();
86         DOMResponseWriter domWriter = findDOMResponseWriter(responseWriter);

(do the same for the block starting at line 222)

And add the following method:

private static DOMResponseWriter findDOMResponseWriter(ResponseWriter responseWriter) {
    while (!(responseWriter instanceof DOMResponseWriter) && responseWriter instanceof ResponseWriterWrapper) {
        responseWriter = ((ResponseWriterWrapper) responseWriter).getWrapped();
    }

    if (responseWriter instanceof DOMResponseWriter) {
        return (DOMResponseWriter) responseWriter;
    }
    else {
        throw new UnsupportedOperationException("ICEfaces rendering required");
    }
}

That should do it for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top