Error deleting Jetty session using beans scope

I am trying to port my Tomcat application to JettyRunner 9.2. I want to port my application to Heroku, so I need to run it with either the built-in server or JettyRunner. I thought JettyRunner would be the easiest as I can keep the WAR format and simplify it if needed.

Any help would be much appreciated. If I can't get it to work anytime soon, I can try the built-in Tomcat, or look at hosting that doesn't require me to change my container.

If another way to use Jetty - maybe inline Jetty will be easier, please let me know and give me some details.

So, to the behavior of the application. It looks like the app is ported and starts fine, but I get an error when I log in. Here is an 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 dependencies on jetty and jsf:

    <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 plugin section for decorating 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>

      

mole-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>

      

+3


source to share


3 answers


This issue is caused by a bug in the JSF implementation 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 hasn't been released yet.

I tried going back to versions in the 2.2th hierarchy. 2.27 and before this error went away, but other errors occur in ViewScoped beans.



It looks like the View Scoped beans are mostly broken in jsf 2.2 (as far as I look), so as a stopgap, I changed my entire scope from beans to scope to request scope. This avoids the error.

+3


source


I just did the following workaround. I am using Jetty 9.2, CDI 1.2 (Weld) and Mojarra 2.28.

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

import javax.enterprise.inject.spi.CDI;
import javax.faces.FacesException;
import javax.faces.context.ExternalContext;
import javax.faces.context.ExternalContextFactory;
import javax.faces.context.ExternalContextWrapper;

import com.sun.faces.util.Util;

public class CDIViewScopeFixExternalContextFactory extends ExternalContextFactory{

private final ExternalContextFactory wrapped;

public CDIViewScopeFixExternalContextFactory(ExternalContextFactory wrapped){
    this.wrapped = wrapped;
}

@Override
public ExternalContext getExternalContext(Object context, Object request,
        Object response) throws FacesException {
    ExternalContext externalContext = getWrapped().getExternalContext(context, request, response);
    CDIViewScopeWorkaround wrapper = new CDIViewScopeWorkaround(externalContext);
    return wrapper;
}


@Override
public ExternalContextFactory getWrapped() {
    return this.wrapped;
}

private static class CDIViewScopeWorkaround extends ExternalContextWrapper{

    private static String CDI_KEY;
    static {
        try {
            Field f = Util.class.getDeclaredField("CDI_AVAILABLE_PER_APP_KEY");
            f.setAccessible(true);
            CDI_KEY  = (String) f.get(null);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    private final ExternalContext wrapped;

    public CDIViewScopeWorkaround(ExternalContext wrapped){
        this.wrapped = wrapped;
    }


    @Override
    public ExternalContext getWrapped() {
        return wrapped;
    }

    @Override
    public Map<String, Object> getApplicationMap() {
        MapFix mapFix = new MapFix(super.getApplicationMap());
        return mapFix;
    }
}

private static class MapFix extends MapWrapper<String,Object>{

    public MapFix(Map<String, Object> delegate) {
        super(delegate);
    }

    @Override
    public Object get(Object key) {
        if(CDIViewScopeWorkaround.CDI_KEY.equals(key)){
            return CDI.current().getBeanManager();
        }
        return super.get(key);
    }
}


private static class MapWrapper<K,V> implements Map<K,V>{

    private Map<K,V> delegate;

    public int size() {
        return delegate.size();
    }

    public boolean isEmpty() {
        return delegate.isEmpty();
    }

    public boolean containsKey(Object key) {
        return delegate.containsKey(key);
    }

    public boolean containsValue(Object value) {
        return delegate.containsValue(value);
    }

    public V get(Object key) {
        return delegate.get(key);
    }

    public V put(K key, V value) {
        return delegate.put(key, value);
    }

    public V remove(Object key) {
        return delegate.remove(key);
    }

    public void putAll(Map<? extends K, ? extends V> m) {
        delegate.putAll(m);
    }

    public void clear() {
        delegate.clear();
    }

    public Set<K> keySet() {
        return delegate.keySet();
    }

    public Collection<V> values() {
        return delegate.values();
    }

    public Set<java.util.Map.Entry<K, V>> entrySet() {
        return delegate.entrySet();
    }

    public boolean equals(Object o) {
        return delegate.equals(o);
    }

    public int hashCode() {
        return delegate.hashCode();
    }

    public MapWrapper(Map<K,V> delegate){
        this.delegate = delegate;
    }
}
}

      



person-config.xml

    <faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.ord/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_2.xsd"
    version="2.2">

    <application>
       …
    </application>

     <factory>
        <external-context-factory>your.package.CDIViewScopeFixExternalContextFactory</external-context-factory>
    </factory>
</faces-config>

      

+2


source


I have the same problem with tomcat 7.0.55 on a Linux system. For me JAVASERVERFACES-3450 is not a problem because this ticket refers to null scoped beans that are already destroyed.

Our exception in ViewScopeContextManager.destroyBeans (Unknown Source) is due to a null beanManager instance .

With Tomcat 7.0.55 on Windows system everything works ... :(

0


source







All Articles