StackOverflowError dans L'Application Seam / Spring WebFlow

nous sommes en train de remplacer progressivement les composants de joint par ressort-MVC et ressort-Webflow.

Running JMeter-tests les journaux sont encombrés de StackOverFlowErrors après une couple d'heures:

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)

ainsi la méthode getMessageBundle est appelée par deux instances: SeamApplication et FlowApplication.

en regardant le javax.face.application.Classe d'Application il est écrit:

" parce que cette instance est partagé, il doit être mis en œuvre d'une manière sûre."

peut-être que les deux instances de l'application essaient d'accéder au même paquet qui cause des conditions de course?

EDIT: Après que l'application n'ait plus répondu, Nous avons redémarré le serveur et maintenant l'erreur apparaît dans un autre endroit:

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)

Les 2 dernières lignes sont répétées des milliers de fois dans le fichier journal.

nous travaillons avec les suivants component-versions:

JSF-1.2

Couture-2.2.0

Spring WebFlow 2.3.4

printemps MVC 3.0.5

mettre à jour l'un des composants n'est pas une option.

3
demandé sur recalcitrant 2014-08-15 20:51:58

1 réponses

les deux SeamApplication et FlowApplication présentent des anomalies quant à la délégation appropriée à l'application enveloppée. Une façon de le réparer est par l'intermédiaire de la FlowApplicationFactory .

prenez D'abord son code source brut et déposez-le dans le dossier Java source de votre projet webapp, en maintenant son paquet original. Vous n'avez pas nécessairement besoin de manipuler des pots. Classes dans /WEB-INF/classes ont une priorité de chargement supérieure à celles des bocaux.

puis manipuler la classe comme suit (basé sur 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);
    }

}

ainsi, lors de la création de FlowApplication , il inspectera d'abord les applications enveloppées si elle n'est pas déjà créée avant et si oui, puis la réutiliser à la place.

notez que la dépendance SeamApplication est un peu étrange, mais c'est juste pour correction. JSF2 a rendu plus facile par la nouvelle classe ApplicationWrapper que vous pourriez utiliser au lieu de SeamApplication dans le bloc createFlowApplication() .

si tout cela ne fonctionne toujours pas, alors peut-être que le SeamApplicationFactory est initialisé après le FlowApplicationFactory . Vous pouvez forcer l'ordre en sélectionnant explicitement les entrées <application-factory> dans le propre faces-config.xml de webapp dans l'ordre désiré (le erreurs un dernier):

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

sinon, vous pourriez vouloir faire la même chose que ci-dessus pour SeamApplicationFactory (évidemment avec FlowApplication et SeamApplication échangés dans le code).

1
répondu BalusC 2014-08-19 08:57:34