Apache MyFaces: VariableMapperWrapper.resolveVariable, StackOverflowError: Could not Resolve Variable [Overflow] - jsf-2

I wonder what's the reason for this exception having created new Facelets containing some includes. There is obviously a recursion inside the EL resolution. The debugging of the VariableMapperWrapper.resolveVariable method doesn't show anything special: EL resolution is happening ...
14.03.2013 17:20:13 org.apache.catalina.core.StandardWrapperValve invoke
SCHWERWIEGEND: Servlet.service() for servlet Faces Servlet threw exception
java.lang.StackOverflowError
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:390)
at java.lang.StringBuilder.append(StringBuilder.java:119)
at org.apache.myfaces.view.facelets.el.VariableMapperWrapper.resolveVariable(VariableMapperWrapper.java:96)
at org.apache.myfaces.view.facelets.el.VariableMapperWrapper.resolveVariable(VariableMapperWrapper.java:89)
at org.apache.myfaces.view.facelets.el.VariableMapperWrapper.resolveVariable(VariableMapperWrapper.java:89)
... (recursion) ...
at org.apache.myfaces.view.facelets.el.VariableMapperWrapper.resolveVariable(VariableMapperWrapper.java:89)
at org.apache.myfaces.view.facelets.el.VariableMapperWrapper.resolveVariable(VariableMapperWrapper.java:89)
at org.apache.myfaces.view.facelets.el.VariableMapperWrapper.resolveVariable(VariableMapperWrapper.java:89)
at org.apache.myfaces.view.facelets.el.VariableMapperWrapper.resolveVariable(VariableMapperWrapper.java:89)
at com.sun.el.lang.VariableMapperFactory.resolveVariable(VariableMapperFactory.java:63)
at com.sun.el.lang.ExpressionBuilder.visit(ExpressionBuilder.java:234)
at com.sun.el.parser.SimpleNode.accept(SimpleNode.java:172)
at com.sun.el.parser.SimpleNode.accept(SimpleNode.java:175)
at com.sun.el.lang.ExpressionBuilder.prepare(ExpressionBuilder.java:186)
at com.sun.el.lang.ExpressionBuilder.build(ExpressionBuilder.java:197)
at com.sun.el.lang.ExpressionBuilder.createValueExpression(ExpressionBuilder.java:240)
at com.sun.el.ExpressionFactoryImpl.createValueExpression(ExpressionFactoryImpl.java:98)
at org.apache.myfaces.view.facelets.tag.TagAttributeImpl.getValueExpression(TagAttributeImpl.java:486)
at org.apache.myfaces.view.facelets.tag.jsf.ValueHolderRule$DynamicValueExpressionMetadata.applyMetadata(ValueHolderRule.java:99)
at org.apache.myfaces.view.facelets.tag.MetadataImpl.applyMetadata(MetadataImpl.java:45)
at javax.faces.view.facelets.MetaTagHandler.setAttributes(MetaTagHandler.java:66)
at javax.faces.view.facelets.DelegatingMetaTagHandler.setAttributes(DelegatingMetaTagHandler.java:93)
at org.apache.myfaces.view.facelets.tag.jsf.ComponentTagHandlerDelegate.apply(ComponentTagHandlerDelegate.java:237)
at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:53)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:49)
...

It has finally emerged there was a special type of recursion inside the Facelets XHTML code. I noticed other people created such a recursion by inclusion of snippet chains like a.xhtml includes b.xhtml includes a.xhtml
In my case an included snippet contained a copy&paste error from the main XHTML page, the snippet header section:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition template="xyz.xhtml">
...
--> template="xyz.xhtml" included the snippet above --> recursion.
The removal of the anyway wrong template attribute resolved the problem. In the end the exception above as the symptom of this problem was a bit far away from the error reason. The resolution was not at all obvious.

Related

Doctype in JSF Mojarra

What Doctype should I use in JSF pages? The other day I'm trying to migrate from Mojarra 2.1.13 to 2.1.18 and it seems that the way the doc types are interpreted changed. In the root template I have following DOC TYPE
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
Do I also have to include this?
<?xml version="1.0"?>
In composites (that use this template) I used to have following doctype
<!DOCTYPE composite PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
But it seems that Mojarra 2.1.18 doesn't really support that. Also I didn't find this in any JSF 2.0 reference, this we used to use in JSF 1.2. If I have this doctype in composite page, it will render composite doctype instead of html that is in the template. In the result, the css styles are messed up.
So what's the correct usage of doctypes in JSF 2.0. Or is this issues with Mojarra? I didn't find any reference regarding this.
I created a JIRA issue for this: http://java.net/jira/browse/JAVASERVERFACES-2820
and it has been closed as this is the expected behavior.
"The composite page is where you actually use the template. So it is the outer most file where you specified a doc type. As such it defines the doc type that will be rendered."
Just specify the doctype in a template and nowhere else
I also migrated Jboss 7.1 to JBoss EAP 6.1
I found not very nice workaround - to insert on each page (not template):
<!DOCTYPE html>
e. g.:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition 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" template="template.xhtml">
Is there any other way - for doctype to be read from master template?

ClassCastException:UIViewRoot cannot be cast to org.portletfaces.bridge.component.PortletNamingContainerUIViewRoot

For a simple jsf 2.0 and Tomcat 7 application I am getting following error:
Casting Error java.lang.ClassCastException:
javax.faces.component.UIViewRoot cannot be cast to
org.portletfaces.bridge.component.PortletNamingContainerUIViewRoot
Aug 24, 2012 11:55:40 AM com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
SEVERE: Error Rendering View[/hello.xhtml]
java.lang.ClassCastException: javax.faces.component.UIViewRoot cannot be cast to org.portletfaces.bridge.component.PortletNamingContainerUIViewRoot
at org.portletfaces.bridge.renderkit.html_basic.HeadRenderer.encodeBegin(HeadRenderer.java:62)
at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:823)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1611)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrateg y.java:380)
hello.xhtml is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:body>
<h:form>
<h:commandButton value="Welcome Me" action="welcome"></h:commandButton>
</h:form>
</h:body>
</html>
I also have the same problem. But once h:head or h:body is removed, page loads ok, except for javascripts and css, which require h:head. These will not be loaded.

Avoid multiple DOCTYPE and html tags when using ui:include

we are using several ui:include tags in the "main" page. The page that is to be included looks like this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns=".." xmlns:ui="..." ...>
<ui:fragment rendered="${foo}">
some html code
</ui:fragement>
<ui:fragment rendered="${!foo || bar}">
some more html code
</ui:fragement>
</html>
Using the ui:include for templating results in repeating the DOCTYPE and html tag several times in the source code, which is pretty ugly. (Sure, the user doesn't see, but I'm a fan of tidy html)
However, if I remove the DOCTYPE and html tag from the to-be-included-xhtml, the Faces Servlet throws an exception stating that the prefix ui for ui:fragment is not bound.
Does anybody know, how I can include another XHTML page without the multiple DOCTYPEs and htmls?
You should take a look at the ui:composition tag.
We also use ui:include to include jsf2 pages, and to solve the problem you have I believe you could alter your included page by adding the ui:composition tag as follows:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns=".." xmlns:ui="..." ...>
<ui:composition>
<ui:fragment rendered="${foo}">
some html code
</ui:fragement>
<ui:fragment rendered="${!foo || bar}">
some more html code
</ui:fragement>
</ui:composition>
</html>

Not getting 'Page Not Found' with JSF2.0

I'm trying with Javaee6 with GlassFish3.1.
I created a web project (with JSF2.0), with only one file, one.xhtml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<meta http-equiv="Content-Type"
content="text/html; charset=ISO-8859-1" />
<title>ONE</title>
</h:head>
<h:body>
<h:form id="oneForm">
<h:commandButton id="oneButton" value="To Two" action="two" />
</h:form>
</h:body>
</html>
I've not added web.xml, as it is optional for javaee6.
I added faces-config.xml, so that default servlet mapping works. (with only top element)
<faces-config version="2.0" .../>
When I hit command-button on the page, I'm expecting 'Page Not Found' error. But the page just reloads. If I actually put file two.xhtml, it works correctly, but in it's absence, does not give error, which I'm expecting.
Am I missing something, some config?
Thanks in advance.
This is expected. JSF works with so-called navigation cases. If it doesn't find a matching case, it will just postback to the same view. This is specified in the JSF 2.0 specification (pick the one for evaluation).
7.4.2 Default NavigationHandler Algorithm
...
The default NavigationHandler implementation must behave as if it were performing the following algorithm (although optimized implementation techniques may be utilized):
If no navigation case is matched by a call to the handleNavigation() method, this is an indication that the current view should be redisplayed. As of JSF 2.0, a null outcome does not unconditionally cause all navigation rules to be
skipped.
...
However, when you set the JSF project stage to Development by a context parameter in web.xml,
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
then clicking the button should then result in a development warning message in the postback,
Unable to find matching navigation case with from-view-id '/one.xhtml' for action 'two' with outcome 'two'
so that eventual developer mistakes are at least put in attention.

JSF2.0: EL are not resolved in a Composite Component taglib

I'm trying to create a custom composite component taglib in my office but i get a strange issue with EL. It seems expressions as #{cc.attrs.[var] } are already resolve as empty.
I try to create my taglib in a jar. In my jar i have my files ordered as following:
|_ /
.....|_ META-INF
..........|_ compo.taglib.xml
..........|_ resources
...............|_ components
....................|_ hello.xhtml
compo.taglib.xml contains:
<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0">
<namespace>http://www.example.com/jsf/compo</namespace>
<composite-library-name>compo</composite-library-name>
<tag>
<tag-name>hello</tag-name>
<source>./components/hello.xhtml</source>
</tag>
</facelet-taglib>
hello.xhtml contains:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface name="hello" displayName="hello">
<composite:attribute name="name" required="true" type="String"/>
</composite:interface>
<composite:implementation >
hello #{cc.attrs.name}!
</composite:implementation>
</html>
My web project contains in WEB-INF lib my taglib as a jar, jsf-impl.jar and jsf-api.jar (from Mojarra) my page is simply that:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:comp="http://www.example.com/jsf/compo" >
<body>
<comp:hello name="John"></comp:hello>
</body>
</html>
At rendering i see "hello !" but not "hello John!". Attributes values seems be lost somewhere. I try this sample on tomcat 6.0.29 and Websphere 7.
I made something wrong?
Have you tested your control in web application rather than from taglib (jar file)?
I can only guess but I think your attribute is not showing because you named it name. In some cases "name" attribute is beeing used by JSF (for example in f:attribute or f:param or even ui:param uses attribute name). Try to replace attribute name with oder word.
You need to look here and check if attribute name is available.
Yes this case appears also with other attributes.
I tried with the component in web application and issue doesn't appear.
I also tried with the component in a jar with default namespace: issue doesn't appear. I think there is bug when using composite component in a jar with custom namespace.

Resources