Question

We're in the process of moving our project to Java EE 7 targeting JBoss Wildfly.

We have a few dozen @ManagedBean @javax.faces.bean.ViewScoped (the old non-CDI ViewScoped) controllers that we're converting to @Named @javax.faces.view.ViewScoped (new CDI version).

We are encountering this exception now when testing using Arquillian against a remote Wildfly (beta2 nightly) server:

org.jboss.arquillian.test.spi.ArquillianProxyException: org.jboss.weld.context.ContextNotActiveException : WELD-001303: No active contexts for scope type javax.faces.view.ViewScoped [Proxied because : Original exception not deserilizable, ClassNotFoundException]  
    at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:680)  
    at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:79)  
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:78)  
    at controller.ViewScopedEE7Controller$Proxy$_$$_WeldClientProxy.getNumber(Unknown Source)  
    at controller.ViewScopedEE7ControllerTest.test(ViewScopedEE7ControllerTest.java:47)  

There are a few things that stand out to me with this:

No active contexts for scope type javax.faces.view.ViewScoped

and

[Proxied because : Original exception not deserilizable, ClassNotFoundException]  

I sort of understand the first part, though this was never a problem for us with the old non-CDI ViewScoped, but I don't understand the second part, what class can't be found? Or is this a red herring?

Here is a complete working example:

ViewScopedEE7Controller.java

    package controller;  

import javax.faces.view.ViewScoped;  
import javax.inject.Named;  

@ViewScoped  
@Named  
public class ViewScopedEE7Controller {  

    private int number = 10;  

    public int getNumber() {  
        return number;  
    }  

    public void setNumber(int number) {  
        this.number = number;  
    }  
}

Should be noted that this test works in its entirety if the old @ViewScoped is using along with @ManagedBean instead of @Named.

ViewScopedEE7ControllerTest.java

    package controller;  

import javax.inject.Inject;  

import org.jboss.arquillian.container.test.api.Deployment;  
import org.jboss.arquillian.junit.Arquillian;  
import org.jboss.shrinkwrap.api.ShrinkWrap;  
import org.jboss.shrinkwrap.api.asset.EmptyAsset;  
import org.jboss.shrinkwrap.api.spec.JavaArchive;  
import org.jboss.shrinkwrap.api.spec.WebArchive;  
import org.jboss.shrinkwrap.resolver.api.maven.Maven;  
import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;  
import org.junit.Assert;  
import org.junit.Test;  
import org.junit.runner.RunWith;  

@RunWith(Arquillian.class)  
public class ViewScopedEE7ControllerTest {  

    @Deployment  
    public static WebArchive deployment() {  
        PomEquippedResolveStage resolver = Maven.resolver().loadPomFromFile("pom.xml");  
        WebArchive war = ShrinkWrap.create(WebArchive.class, "view-scoped.war");  
        war.addClass(ViewScopedEE7Controller.class);  
        war.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");  
        war.addAsLibraries(resolver.resolve("org.jboss.spec:jboss-javaee-all-7.0").withTransitivity().asFile());  
        System.out.println(war.toString(true));  
        return war;  
    }  

//    @Deployment  
//    public static JavaArchive deployment() {  
//        JavaArchive war = ShrinkWrap.create(JavaArchive.class, "view-scoped.jar");  
//        war.addClass(ViewScopedEE7Controller.class);  
//        war.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");  
//        System.out.println(war.toString(true));  
//        return war;  
//    }  

    @Inject ViewScopedEE7Controller controller;  

    @Test  
    public void test() {  
        Assert.assertNotNull(controller);  
        Assert.assertEquals(10, controller.getNumber());  
        controller.setNumber(100);  
        Assert.assertEquals(100, controller.getNumber());  
    }  
}  

Also should be noted that this test works if I build using a JavaArchive instead of a WebArchive, the only problem is if I add anything like a FacesContext import to the controller, deployment fails in the JavaArchive. However, I don't understand why this simple test works with a jar and not a war. If I don't include that jboss-javaee-all-7.0 resolve then the @Inject does not work.

pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
    <modelVersion>4.0.0</modelVersion>  
    <groupId>test</groupId>  
    <artifactId>view-scoped</artifactId>  
    <version>0.0.1-SNAPSHOT</version>  
    <packaging>war</packaging>  
    <name>view-scoped</name>  

    <dependencyManagement>  
        <dependencies>  
            <dependency>  
                <groupId>org.jboss.arquillian</groupId>  
                <artifactId>arquillian-bom</artifactId>  
                <version>1.1.2.Final</version>  
                <scope>import</scope>  
                <type>pom</type>  
            </dependency>  
        </dependencies>  
    </dependencyManagement>  

    <dependencies>  
        <dependency>  
            <groupId>org.jboss.spec</groupId>  
            <artifactId>jboss-javaee-all-7.0</artifactId>  
            <version>1.0.0.Beta2</version>  
        </dependency>  

        <dependency>  
            <groupId>org.wildfly</groupId>  
            <artifactId>wildfly-arquillian-container-remote</artifactId>  
            <version>8.0.0.Beta1</version>  
            <scope>test</scope>  
        </dependency>  

        <dependency>  
            <groupId>junit</groupId>  
            <artifactId>junit</artifactId>  
            <version>4.11</version>  
            <scope>test</scope>  
        </dependency>  

        <dependency>  
            <groupId>org.jboss.arquillian.junit</groupId>  
            <artifactId>arquillian-junit-container</artifactId>  
            <scope>test</scope>  
        </dependency>  

        <dependency>  
            <groupId>org.jboss.shrinkwrap.resolver</groupId>  
            <artifactId>shrinkwrap-resolver-impl-maven</artifactId>  
            <scope>test</scope>  
        </dependency>  
    </dependencies>  
</project>  

Also have an empty arquillian.xml.

This is what the deployed war looks like:

    view-scoped.war:  
/META-INF/  
/META-INF/beans.xml  
/WEB-INF/  
/WEB-INF/lib/  
/WEB-INF/lib/jboss-websocket-api_1.0_spec-1.0.0.Final.jar  
/WEB-INF/lib/hibernate-jpa-2.1-api-1.0.0.Final.jar  
/WEB-INF/lib/jboss-annotations-api_1.2_spec-1.0.0.Final.jar  
/WEB-INF/lib/jboss-ejb-api_3.2_spec-1.0.0.Final.jar  
/WEB-INF/lib/jboss-json-api_1.0_spec-1.0.0.Final.jar  
/WEB-INF/lib/jboss-jsf-api_2.2_spec-2.2.3.jar  
/WEB-INF/lib/jboss-jms-api_2.0_spec-1.0.0.Final.jar  
/WEB-INF/lib/jsr181-api-1.0-MR1.jar  
/WEB-INF/lib/jboss-j2eemgmt-api_1.1_spec-1.0.1.Final.jar  
/WEB-INF/lib/jboss-servlet-api_3.1_spec-1.0.0.Final.jar  
/WEB-INF/lib/jboss-jacc-api_1.5_spec-1.0.0.Beta1.jar  
/WEB-INF/lib/activation-1.1.1.jar  
/WEB-INF/lib/jboss-jaxb-api_2.2_spec-1.0.4.Final.jar  
/WEB-INF/lib/javax.inject-1.jar  
/WEB-INF/lib/jboss-javaee-all-7.0-1.0.0.Beta2.jar  
/WEB-INF/lib/jboss-el-api_3.0_spec-1.0.0.Beta1.jar  
/WEB-INF/lib/jboss-jaxws-api_2.2_spec-2.0.2.Final.jar  
/WEB-INF/lib/validation-api-1.1.0.Final.jar  
/WEB-INF/lib/jboss-jaspi-api_1.1_spec-1.0.0.Beta1.jar  
/WEB-INF/lib/jboss-rmi-api_1.0_spec-1.0.4.Final.jar  
/WEB-INF/lib/jboss-saaj-api_1.3_spec-1.0.3.Final.jar  
/WEB-INF/lib/jboss-connector-api_1.7_spec-1.0.0.Final.jar  
/WEB-INF/lib/cdi-api-1.1.jar  
/WEB-INF/lib/jboss-interceptors-api_1.2_spec-1.0.0.Final.jar  
/WEB-INF/lib/jboss-transaction-api_1.2_spec-1.0.0.Final.jar  
/WEB-INF/lib/jboss-jstl-api_1.2_spec-1.0.4.Beta1.jar  
/WEB-INF/lib/jboss-batch-api_1.0_spec-1.0.0.Final.jar  
/WEB-INF/lib/jaxrs-api-3.0.4.Final.jar  
/WEB-INF/lib/jboss-concurrency-api_1.0_spec-1.0.0.Final.jar  
/WEB-INF/lib/mail-1.5.0-b01.jar  
/WEB-INF/lib/jboss-jsp-api_2.3_spec-1.0.0.Beta1.jar  
/WEB-INF/classes/  
/WEB-INF/classes/controller/  
/WEB-INF/classes/controller/ViewScopedEE7Controller.class  

Any help would be extremely helpful, this is currently creating a huge block for us. Our server works as expected but we're currently @Ignore'ing hundreds of controller tests.

Thank you in advance.

Was it helpful?

Solution

What we ended up doing was not @Inject'ing the controller in the test, and instead construct the controller by hand. So in my example above, get rid of the @Inject and in a @Before method, we construct the object and set all the fields that controller @Inject's and @EJB's. So like:

ControllerToTest controller;
@Inject SessionController sessionController; //this works
@EJB SomeEJB someEJB; //this works too
@Before
public void before() {
  controller.setSessionController(sessionController);
  controller.setSomeEJB(someEJB);
}

OTHER TIPS

It's a bad idea to mix CDI and JSF annotations.

javax.faces.view.ViewScoped will make JSF take care of the bean but CDI doesn't know aboout that.

If ViewScopedEE7Controller is recognized by CDI, which depends on packaging and beans.xml config, it will assume @Dependent pseudo-scope (I don't think that's what you want here).

I would stick to either "all JSF" or "all CDI" approach. If you want CDI's counterpart of javax.faces.view.ViewScoped check out Apache Deltaspike extensions.

The issue is simple here. CDI is not aware of any context called

javax.faces.view.ViewScoped

Your WELD implementation reads and parses that this ViewScoped Bean as a CDI container managed bean, but CDI does not play too well with the JSF scopes. Infact CDI spec does not state how the CDI managed beans would behave with JSF scopes as opposed to CDI scopes.

The other exception line

Original exception not deserilizable

is caused by Arquillian but I dont have too much detail on it but it seems like your Arquillian test is using a different Classpath as opposed to what is running on the Server.

I hope this helps

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top