UIInstructions cannot be cast

I f, like me, you are getting an error message along the lines of “UIInstructions cannot be cast to org.primefaces.model.menu.MenuElement” you are in luck because here’s the answer.

The menu model was largely re-written in the upgrade from PrimeFaces 3.5 to 4.0 and bring a host of changes. First of the exception:

WARNING: StandardWrapperValve[Faces Servlet]: Servlet.service() for servlet Faces Servlet threw exception
java.lang.ClassCastException: com.sun.faces.facelets.compiler.UIInstructions cannot be cast to org.primefaces.model.menu.MenuElement
 at org.primefaces.component.tieredmenu.TieredMenuRenderer.encodeElements(TieredMenuRenderer.java:97)
 at org.primefaces.component.tieredmenu.TieredMenuRenderer.encodeSubmenu(TieredMenuRenderer.java:162)
 at org.primefaces.component.tieredmenu.TieredMenuRenderer.encodeElements(TieredMenuRenderer.java:119)
 at org.primefaces.component.tieredmenu.TieredMenuRenderer.encodeMenu(TieredMenuRenderer.java:78)

I’ve only included the first few lines as there’s little point digging all the way back to the start for a class cast exception. This stack trace, like a lot in JSF and related technologies, doesn’t really tell you what the problem is. Essentially though it boils down to incorrect use of the menu model in one or more ways.

Firstly, remove all XML style comments from inside any p:menu element or it’s children if you can. Why, because JSF tags shouldn’t be commented in that way. EL expressions are not XML and will still be evaluated leading to problems and the comment will be added to the output tree which can cause unexpected results. The correct way to “comment out” a JSF tag is surround it with ui:remove (no, I don’t like this method either).

If there are comments you can’t remove then add this context parameter to your web.xml file:

<context-param>
 <param-name>facelets.SKIP_COMMENTS</param-name>
 <param-value>true</param-value>
</context-param>

Actually, I recommend just adding this context parameter all the time as it will strip out anything inside <!– –> tags and I can’t think of any situation where I want that content going to the client.

Finally, make sure you have removed all non-JSF tags in the menu. Tags such as <br/> and <hr/> will trigger the exception as they aren’t part of the menu model and therefore not understood.