JSF - MyFaces - Ошибка переполнения стека - PullRequest
1 голос
/ 06 марта 2012

Я получаю StackOverflowError при рендеринге страницы JSF.Это происходит после загрузки определенного набора данных (что происходит успешно), а затем выполнения каких-либо действий на странице.Обратите внимание, что страница будет загружаться правильно, если она обновляется после возникновения ошибки.Страница работает совершенно иначе и может загрузить больше записей, чем загружено в состоянии ошибки.

В зависимости от предпринятых шагов, сообщение об ошибке может незначительно отличаться, но ошибка всегда будет отображаться.

Я использую 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>

1 Ответ

3 голосов
/ 06 марта 2012
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 в бесконечном цикле рекурсии.В таком случае вам нужно исправить это, привязав значение к полноценному свойству управляемого компонента.

Проверьте свои страницы на наличие логических ошибок такого рода.Между прочим, не имеет значения, привязан ли компонент к управляемому компоненту или нет, он не сможет работать так же хорошо:

<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}" />
...