Question

I have problems making Wildfly testing under NetBeans and Maven. I am able to launch application from IDE, I can even debug it with the Netbeans debugger, however as soon as I start unit tests, I get the following error:

No EJBContainer provider available: no provider names had been found.
javax.ejb.EJBException
    at javax.ejb.embeddable.EJBContainer.reportError(EJBContainer.java:216)
    at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:146)
    at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:102)
    at cz.interactsys.ejb.StatefulSessionBeanTest.setUp(StatefulSessionBeanTest.java:28)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)

The code is standard like the following:

    int numberA = 1;
    int numberB = 2;
    EJBContainer container = javax.ejb.embeddable.EJBContainer.createEJBContainer();
    MyBean instance = (MyBean) container.getContext().lookup("java:global/classes/MyBean");
    int expResult = 3;
    int result = instance.plusOne(1);
    assertEquals(expResult, result);
    container.close();

Thanks in advance.

Was it helpful?

Solution

The problem is that there is no EJBContainer in Wildfly at all. I am not sure how this is possible given that EJBContainer should be there according to the platform specification. nevertheless we need to use something different and it is Arquillian. This text was inspired by numerous other articles, maily this one, however the solution suggested here is using the same Wildfly installation for tests as for regular deployment which seems better to me.

It is necessary to follow the following hints carefully. Then it will work.

Step zero - preparation: Let's prepare something we can use for testing.

Let's have a regular Maven JavaEE project, i.e.:

demoproj
demoproj-ear
demoproj-ejb
demoproj-war

I am using NetBeans, however the following steps shouldn't be very different even for other IDEs. Let's create some stuff like entity beans, persistence unit, and session beans of course in order to have something to test. I have created a demo persistence unit using NetBeans, an entity using the database, and a session bean from the entity.

Step one: We add the following code into pom.xml od demoproj (i.e. the master project):

<properties>
    <junit-version>4.11</junit-version>
    <arquillian-version>1.1.4.Final</arquillian-version>
    <arquillian-wildfly-version>8.1.0.Final</arquillian-wildfly-version>
    <arquillian-transaction-version>1.0.1.Final</arquillian-transaction-version>  
    <javaee-server-home>/Java/wildfly-8.1.0.Final</javaee-server-home>
</properties>        
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>${javaee-api-version}</version>
        </dependency>
        <!-- -JUNIT-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit-version}</version>
        </dependency>
        <!-- rquillian itself-->
        <dependency>
            <groupId>org.jboss.arquillian</groupId>
            <artifactId>arquillian-bom</artifactId>
            <version>${arquillian-version}</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
        <!-- this is in an extention to arquillian it is optional-->
        <dependency>
            <groupId>org.jboss.arquillian.extension</groupId>
            <artifactId>arquillian-transaction-bom</artifactId>
            <version>${arquillian-transaction-version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!-- this is container adapter for wildfly-->
        <dependency>
            <groupId>org.wildfly</groupId>
            <artifactId>wildfly-arquillian-container-embedded</artifactId>
            <version>${arquillian-wildfly-version}</version>
        </dependency>
        <!-- this is the wildfly emb.container - BUT eventually it is not a fully blown emb.container-->
        <dependency>
            <groupId>org.wildfly</groupId>
            <artifactId>wildfly-embedded</artifactId>
            <version>${arquillian-wildfly-version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>
<build>
    <pluginManagement>
        <plugins>
            <!-- compiler plugin -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${compiler-plugin-version}</version>
                <configuration>
                    <source>${java-version}</source>
                    <target>${java-version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <!-- maven ear plugin -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ear-plugin</artifactId>
                <version>${ear-plugin-version}</version>
                <configuration>
                    <generateModuleId>true</generateModuleId>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <!-- ejb plugin -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ejb-plugin</artifactId>
                <version>${ejb-plugin-version}</version>
                <configuration>
                    <ejbVersion>${ejb-spec-version}</ejbVersion>
                </configuration>
            </plugin>
            <!-- war plugin -skinny wars mode! -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>${war-plugin-version}</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                    <packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                        </manifest>
                    </archive>
                    <webResources>
                        <resource>
                            <filtering>true</filtering>
                            <directory>src/main/webapp</directory>
                            <includes>
                                <include>**/web.xml</include>
                            </includes>
                        </resource>
                    </webResources>
                </configuration>
            </plugin>
            <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.17</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.8</version>
            </plugin>
        </plugins>
    </pluginManagement>
</build>    

Step two: We add the following into dependencies section of pom.xml of demoproj-ejb:

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <scope>test</scope>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>org.jboss.arquillian.junit</groupId>
        <artifactId>arquillian-junit-container</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.wildfly</groupId>
        <artifactId>wildfly-arquillian-container-embedded</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.wildfly</groupId>
        <artifactId>wildfly-embedded</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.jboss.arquillian.extension</groupId>
        <artifactId>arquillian-transaction-jta</artifactId>
        <scope>test</scope>
    </dependency>        

Add this into plugins section of demoproj-ejb:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <argLine>-Dfile.encoding=UTF-8</argLine>
                <forkCount>1C</forkCount>
                <systemPropertyVariables>
                    <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                    <jboss.home>${javaee-server-home}</jboss.home>
                </systemPropertyVariables>
                <redirectTestOutputToFile>false</redirectTestOutputToFile>
            </configuration>
        </plugin> 

Step three: Let's create the test unit. If we use a normal IDE function, we get something like the following:

package com.demopack.demoproj;

import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

public class DemoBeanLocalTest {

    public DemoBeanLocalTest() {
    }

    @Before
    public void setUp() {
    }

    @Test
    public void testBusinessMethod() {
    }

}

Now we need to add @RunWith(Arquillian.class) just before the header of the class, you should remove the default constructor and add the following code inside the testing class:

@EJB
DemoBeanLocal demoBean;

@Deployment
public static JavaArchive createDeployment() {

    JavaArchive jar = ShrinkWrap.create(JavaArchive.class);
    jar.addAsResource("test-persistence.xml", "META-INF/persistence.xml");
    jar.addPackage("com.demopack.demoproj");
    jar.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");

    return jar;
}

Then you could add some testing methods as usual. The whole test class could look like the following:

package com.demopack.demoproj;

import javax.ejb.EJB;
import junit.framework.Assert;
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.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(Arquillian.class)
public class DemoBeanLocalTest {

    @EJB
    DemoBeanLocal demoBean;

    @Deployment
    public static JavaArchive createDeployment() {

        JavaArchive jar = ShrinkWrap.create(JavaArchive.class);
        jar.addAsResource("test-persistence.xml", "META-INF/persistence.xml");
        jar.addPackage("com.demopack.demoproj");
        jar.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");

        return jar;
    }

    @Before
    public void setUp() {
    }

    @Test
    public void testBusinessMethod() {

        Assert.assertEquals("test test", demoBean.businessMethod("test"));
    }

}

Step four: Almost done, but one more very important thing is left: under demoproj-ejb create src/test/resources folder and copy there persistence.xml from src/main/resources/META-INF and rename it to test-persistence.xml.

Make sure that database is running, a valid driver is installed, correct data source is used, etc. In my case most of troubles was caused by problems of this kind.

That's it! Now you should make clean and build on demoproj and if everything will be OK, you can use normal NetBeans testing function as you are used to. Enjoy!

UPDATE If you prefer using a remote instance (either on a remote server or a running instance on the same machine), what I recommend due to certain performance gain, you should change the following parts of the code:

In pom.xml in the master project:

Exchange:

`<artifactId>wildfly-arquillian-container-embedded</artifactId>` for
`<artifactId>wildfly-arquillian-container-remote</artifactId>`.

Remove:

<dependency>
    <groupId>org.wildfly</groupId>
    <artifactId>wildfly-embedded</artifactId>
    <version>${arquillian-wildfly-version}</version>
</dependency>

Then do the same in pom.xml of demoproj-ejb.

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