Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to test CDI ViewScoped beans like we used to test JSF ViewScoped managed bean

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.

like image 959
Greg Noe Avatar asked Nov 23 '22 09:11

Greg Noe


1 Answers

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);
}
like image 129
Greg Noe Avatar answered Jan 17 '23 13:01

Greg Noe