Seam/Spring WebFlow应用程序中的StackOverflowError [英] StackOverflowError in Seam / Spring WebFlow Application

查看:125
本文介绍了Seam/Spring WebFlow应用程序中的StackOverflowError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在逐步用Spring-MVC和Spring-Webflow替换Seam组件.

We are gradually replacing Seam components with Spring-MVC and Spring-Webflow.

运行JMeter-测试几个小时后,日志会出现StackOverFlowErrors混乱的情况:

Running JMeter-tests the logs get cluttered with StackOverFlowErrors after a couple of hours:

javax.servlet.ServletException: Servlet execution threw an exception
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:313)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:341)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:530)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
...
Caused by: java.lang.StackOverflowError
    at org.jboss.seam.jsf.SeamApplication.getMessageBundle(SeamApplication.java:264)
    at org.springframework.faces.webflow.FlowApplication.getMessageBundle(FlowApplication.java:214)
    at org.jboss.seam.jsf.SeamApplication.getMessageBundle(SeamApplication.java:264)
    at org.springframework.faces.webflow.FlowApplication.getMessageBundle(FlowApplication.java:214)
    at org.jboss.seam.jsf.SeamApplication.getMessageBundle(SeamApplication.java:264)
    at org.springframework.faces.webflow.FlowApplication.getMessageBundle(FlowApplication.java:214)
    at org.jboss.seam.jsf.SeamApplication.getMessageBundle(SeamApplication.java:264)

因此,getMessageBundle方法由两个实例调用:SeamApplication和FlowApplication.

So the getMessageBundle method is called by two instances: SeamApplication and FlowApplication.

查看javax.faces.application.Application类,它显示:

Looking at the javax.faces.application.Application class it says:

因为该实例是共享的,所以必须以线程安全的方式实现."

"Because this instance is shared, it must be implemented in a thread-safe manner."

也许这两个应用程序实例正在尝试访问导致竞争情况的同一个捆绑软件?

Maybe the two app instances are trying to access the same bundle which causes race conditions?

应用不再响应后,我们重新启动了服务器,现在错误显示在另一个位置:

After the app did not respond anymore we restarted the server and now the error shows up in another place:

Caused by: java.lang.StackOverflowError
at org.jboss.seam.contexts.BasicContext.get(BasicContext.java:49)
at org.jboss.seam.contexts.BasicContext.get(BasicContext.java:44)
at org.jboss.seam.core.Init.instance(Init.java:117)
at org.jboss.seam.jsf.SeamApplication$ConverterLocator.<init>(SeamApplication.java:140)
at org.jboss.seam.jsf.SeamApplication.createConverter(SeamApplication.java:122)
at org.springframework.faces.webflow.FlowApplication.createConverter(FlowApplication.java:161)
at org.jboss.seam.jsf.SeamApplication.createConverter(SeamApplication.java:126)
at org.springframework.faces.webflow.FlowApplication.createConverter(FlowApplication.java:161)
at org.jboss.seam.jsf.SeamApplication.createConverter(SeamApplication.java:126)

最后两行在日志文件中重复了数千次.

The last 2 lines are repeated thousands of times in the log file.

我们正在处理以下组件版本:

We are working with the following component-versions:

JSF-1.2

Seam-2.2.0

Seam-2.2.0

Spring WebFlow 2.3.4

Spring WebFlow 2.3.4

Spring MVC 3.0.5

Spring MVC 3.0.5

不能更新任何组件.

推荐答案

FlowApplication 具有一些错误,无法正确委派给包装的应用程序.解决此问题的一种方法是通过首先获取其

First grab its raw source code and drop it in the Java source folder of your webapp project, maintaining its original package. You don't necessarily need to manipulate JARs. Classes in /WEB-INF/classes have higher classloading precedence over those in JARs.

然后按以下方式操作该类(基于 OmniFaces

Then manipulate the class as follows (based off from OmniFaces OmniApplicationFactory):

public class FlowApplicationFactory extends ApplicationFactory {

    private final ApplicationFactory wrapped;
    private volatile Application application;

    public FlowApplicationFactory(ApplicationFactory wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public Application getApplication() {
        return (application == null) ? createFlowApplication(wrapped.getApplication()) : application;
    }

    @Override
    public synchronized void setApplication(Application application) {
        wrapped.setApplication(createFlowApplication(application));
    }

    private Application createFlowApplication(final Application application) {
        Application newApplication = application;

        while (!(newApplication instanceof FlowApplication) && newApplication instanceof SeamApplication) {
            newApplication = ((SeamApplication) application).getDelegate();
        }

        if (!(newApplication instanceof FlowApplication)) {
            newApplication =  new FlowApplication(application);
        }

        return (this.application = newApplication);
    }

}

因此,在创建FlowApplication时,它将首先检查已包装的应用程序(如果之前尚未创建),如果已创建,则将其重新使用.

Thus, when creating FlowApplication, it will first inspect the wrapped applications if it isn't already created before and if so, then reuse it instead.

请注意,SeamApplication依赖项很尴尬,但这只是为了对其进行错误修复.通过新的 ApplicationWrapper 类,您可以使用它代替createFlowApplication()块中的SeamApplication.

Note that the SeamApplication dependency is awkward, but that's just to bugfix it. JSF2 has made it easier by new ApplicationWrapper class which you could use instead of SeamApplication in the createFlowApplication() block.

如果这一切仍然不起作用,那么SeamApplicationFactory可能会在FlowApplicationFactory之后之后初始化.您可以通过按所需顺序显式重新声明webapp自己的faces-config.xml中的<application-factory>条目来强制排序(错误修正为最后一个):

If this all still doesn't work, then perhaps the SeamApplicationFactory is initialized after the FlowApplicationFactory. You could force the ordering by explicitly redeclaring the <application-factory> entries in webapp's own faces-config.xml in the desired order (the bugfixed one as last one):

<factory>
    <application-factory>org.jboss.seam.jsf.SeamApplicationFactory</application-factory>
    <application-factory>org.springframework.faces.webflow.FlowApplicationFactory</application-factory>
</factory>

否则,您可能想要对

Otherwise, you might want to do the same as above for SeamApplicationFactory (obviously with FlowApplication and SeamApplication swapped in the code).

这篇关于Seam/Spring WebFlow应用程序中的StackOverflowError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆