【问题标题】:JSF - MyFaces - Stack Overflow ErrorJSF - MyFaces - 堆栈内存溢出
【发布时间】:2012-03-24 03:06:28
【问题描述】:

我在渲染 JSF 页面时收到了StackOverflowError。它发生在加载一组特定数据(成功发生)然后在页面上执行任何其他操作之后。请注意,如果在错误发生后刷新页面,页面将正常加载。该页面可以正常工作,并且能够加载比错误情况下加载的更多的记录。

根据所采取的步骤,错误消息可能会略有不同,但错误总是会出现。

我使用的是 MyFaces 1.2(此时无法升级)。

这是解决方案的常见问题吗?

示例 1:

java.lang.StackOverflowError
at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:947)
at java.lang.ClassLoader.loadClass(ClassLoader.java:291)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:295)
at java.lang.ClassLoader.loadClass(ClassLoader.java:295)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at weblogic.utils.classloaders.GenericClassLoader.loadClass(GenericClassLoader.java:179)
at weblogic.utils.classloaders.FilteringClassLoader.findClass(FilteringClassLoader.java:101)
at weblogic.utils.classloaders.FilteringClassLoader.loadClass(FilteringClassLoader.java:86)
at java.lang.ClassLoader.loadClass(ClassLoader.java:295)
at java.lang.ClassLoader.loadClass(ClassLoader.java:295)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at weblogic.utils.classloaders.GenericClassLoader.loadClass(GenericClassLoader.java:179)
at weblogic.utils.classloaders.ChangeAwareClassLoader.loadClass(ChangeAwareClassLoader.java:45)
at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
at com.sun.el.parser.AstIdentifier.getValue(Unknown Source)
at com.sun.el.parser.AstDeferredExpression.getValue(Unknown Source)
at com.sun.el.parser.AstCompositeExpression.getValue(Unknown Source)
at com.sun.el.ValueExpressionImpl.getValue(Unknown Source)
at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
     ...

示例2:

java.lang.StackOverflowError
at javax.el.ELContext.(ELContext.java:222)
at com.sun.el.lang.EvaluationContext.(Unknown Source)
at com.sun.el.ValueExpressionImpl.getValue(Unknown Source)
at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
at com.sun.el.parser.AstIdentifier.getValue(Unknown Source)
at com.sun.el.parser.AstDeferredExpression.getValue(Unknown Source)
at com.sun.el.parser.AstCompositeExpression.getValue(Unknown Source)
at com.sun.el.ValueExpressionImpl.getValue(Unknown Source)
at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
     ...

更新:我已经解决了这个问题。标准头代码中存在问题 - 它不喜欢所有参数。我没有在下面编写失败的代码,但我必须修复它。 检查 Eclipse 中的堆栈(当 StackOverflowError 断点被命中时),它在 (a) 行和 (b) 行(两者都命中TagValueExpression.getValue(..))之间循环。

<c:forEach var="attr" items="#{request.parameterMap}">
                            <c:if test="#{empty flag}">
                            (a)    <c:set var="parameters" value="#{parameters}&amp;"/>
                            </c:if>
                            <c:set var="flag" value=""/>
                            (b)<c:set var="parameters" value="#{parameters}#{attr.key}=#{attr.value[0]}"/>
                        </c:forEach>

【问题讨论】:

    标签: jsf myfaces


    【解决方案1】:
    java.lang.StackOverflowError
        ...
        at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
        at com.sun.el.parser.AstIdentifier.getValue(Unknown Source)
        at com.sun.el.parser.AstDeferredExpression.getValue(Unknown Source)
        at com.sun.el.parser.AstCompositeExpression.getValue(Unknown Source)
        at com.sun.el.ValueExpressionImpl.getValue(Unknown Source)
        at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
        ...
    

    因此,某些 EL 表达式引用了自身,因此在无限递归循环中运行,导致堆栈溢出。

    这是最常见的原因之一,应该足够简单以理解问题:

    <h:inputText binding="#{input}" value="#{input.value}" />
    

    在上面的例子中,#{input} 指的是组件本身。 #{input.value} 指的是value 属性。但是,如果您在 value 属性本身中使用它,那么这会在无限递归循环中继续反向引用 value 属性。在这种情况下,您需要通过将值绑定到一个完全有价值的托管 bean 属性来修复它。

    检查您的网页是否存在此类逻辑错误。顺便说一句,组件是否绑定到托管 bean 并不重要,它会失败:

    <h:inputText binding="#{bean.input}" value="#{bean.input.value}" />
    

    你应该使用

    <h:inputText binding="#{bean.input}" value="#{bean.value}" />
    

    或者也许只是这个

    <h:inputText binding="#{bean.input}" />
    

    或者甚至只是这个,取决于具体的功能需求

    <h:inputText value="#{bean.value}" />
    

    【讨论】:

    • 感谢您的快速回复。不幸的是,我只有基于value 的绑定——页面上没有binding 参数。我只使用value="#{bean.param}"value="#{tableLoopItem.param}" 以及一些rendered=#{tableLoopItem.booleanParam}
    • 这只是最常见原因的一个示例,以便更好地理解问题。现在您需要在页面中寻找自引用表达式。我们不能这样做,因为我们不知道你们都有什么代码。
    • 我已将修复详细信息添加到问题中。您的答案接近正确的解决方案,希望将来能帮助其他一些可怜的人。
    猜你喜欢
    • 1970-01-01
    • 2019-05-18
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 2017-07-02
    • 2014-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多