Search code examples
mavenjsfherokujettycdi

Jetty scavenging sessions error with view-scoped beans


I am trying to port a Tomcat app to JettyRunner 9.2 I want to move my app to Heroku, so I need to start it with either an embedded server, or JettyRunner. I thought JettyRunner would be easiest, as I could keep a WAR format, and make it easy to port away if necessary.

Any help would be much appreciated. If I can't get it to work soon, I may try embedded Tomcat, or look at hosting which doesn't require me to change my container.

If a different method of using Jetty - maybe embedded Jetty would be easier, please let me know and point me to some details.

So, to the app behaviour. The app seems to be ported fine and starts ok, but I'm getting an error on login. Here is the exception

2014-12-26 05:18:21.189:WARN:oejs.session:org.eclipse.jetty.server.session.HashSessionManager@69f63d95Timer: Problem scavenging sessions
java.lang.NullPointerException
    at com.sun.faces.application.view.ViewScopeContextManager.destroyBeans(Unknown Source)
    at com.sun.faces.application.view.ViewScopeContextManager.sessionDestroyed(Unknown Source)
    at com.sun.faces.application.view.ViewScopeManager.sessionDestroyed(Unknown Source)
    at com.sun.faces.application.WebappLifecycleListener.sessionDestroyed(Unknown Source)
    at com.sun.faces.config.ConfigureListener.sessionDestroyed(Unknown Source)
    at org.eclipse.jetty.server.session.AbstractSessionManager.removeSession(AbstractSessionManager.java:772)
    at org.eclipse.jetty.server.session.AbstractSession.timeout(AbstractSession.java:302)
    at org.eclipse.jetty.server.session.HashSessionManager.scavenge(HashSessionManager.java:358)
    at org.eclipse.jetty.server.session.HashSessionManager$Scavenger.run(HashSessionManager.java:84)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Here are my jetty and jsf dependencies:

    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-server</artifactId>
        <version>9.2.6.v20141205</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-servlet</artifactId>
        <version>9.2.6.v20141205</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>javax.faces</artifactId>
        <version>2.2.9</version>
    </dependency>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>7.0</version>
        <scope>provided</scope>
    </dependency>

Here is my maven jetty plugin section of my pom:

        <plugin>
          <groupId>org.eclipse.jetty</groupId>
          <artifactId>jetty-maven-plugin</artifactId>
          <version>${org.eclipse.jetty.version}</version>
            <configuration>
                <webApp>
                    <overrideDescriptor>src/main/webapp/WEB-INF/jetty-web-override.xml</overrideDescriptor>
                </webApp>
                <contextXml>src/main/webapp/WEB-INF/jetty-context.xml</contextXml>
            </configuration>
        </plugin>

Listeners in my web.xml

<listener>
    <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>
<listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>

jetty-web-override.xml

<web-app version="3.0" 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-app_3_0.xsd">

<listener>
    <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>

<resource-env-ref>
    <resource-env-ref-name>BeanManager</resource-env-ref-name>
    <resource-env-ref-type>
        javax.enterprise.inject.spi.BeanManager
    </resource-env-ref-type>
</resource-env-ref>

jetty-env.xml

    <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure id="webAppCtx" class="org.eclipse.jetty.webapp.WebAppContext">
    <New id="BeanManager" class="org.eclipse.jetty.plus.jndi.Resource">

    <Arg>
        <Ref id="webAppCtx"/>
    </Arg>
    <Arg>BeanManager</Arg>
    <Arg>
        <New class="javax.naming.Reference">
            <Arg>javax.enterprise.inject.spi.BeanManager</Arg>
            <Arg>org.jboss.weld.resources.ManagerObjectFactory</Arg>
            <Arg/>
        </New>
    </Arg>
</New>
</Configure>

and finally, jetty.context:

<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" 

"http://www.eclipse.org/jetty/configure.dtd">

<Configure class="org.eclipse.jetty.webapp.WebAppContext">

<Set name="serverClasses">
    <Array type="java.lang.String">
        <Item>-org.eclipse.jetty.servlet.ServletContextHandler.Decorator</Item>
    </Array>
</Set>
</Configure>

Solution

  • This issue is caused by a bug in the JSF implementation to do with ViewScoped beans, which is described here The described bug is in JSF 2.29 and 2.28. The fix is in 2.30, which is not yet released.

    I tried going back versions in the 2.2 heirarchy. 2.27 and before this bug disappeared, but other bugs occur in ViewScoped beans.

    It looks like View Scoped beans are basically broken in jsf 2.2 (as far as I looked), so as a temporary measure, I have changed all my View Scoped beans to Request Scoped. This avoids the error.