0

I have searched through Stackoverflow to find an answer for my problem, found some very similar problems, but no answer.

What I am trying to do: Create a simple junit test, where a Glassfish 4.1 embedded container is started, and a simple operation of an EJB is tested.

Sample EJB:

@Stateless
@LocalBean
public class ExampleBean {

    public int meaningOfLife() {
        return 42;
    }
}

Pretty simple. Here is my unit test:

public class BasicTest {
    @EJB
    private ExampleBean examplebean;

    private static Context context;

    private static EJBContainer container;

    @BeforeClass
    public static void init() {

        Map<String,Object> props = new HashMap<String,Object>();
        //props.put(EJBContainer.MODULES, new File("target/classes"));
        props.put(EJBContainer.MODULES, new File("D:\\Development\\IDE\\workspace-templates\\jee7-template\\template-service\\target"));

        try {
            container = EJBContainer.createEJBContainer(props);//.getContext().bind("inject", this);
            context = container.getContext();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

My pom.xml dependencies:

    <dependency>
        <groupId>org.glassfish.main.extras</groupId>
        <artifactId>glassfish-embedded-static-shell</artifactId>
        <version>4.1</version>
        <scope>system</scope>
        <systemPath>D:\\Development\\Servers\\glassfish4.1-activiti\\glassfish\\lib\\embedded\\glassfish-embedded-static-shell.jar</systemPath>
    </dependency>

I have also tried with adding the following dependencies:

    <dependency>
        <groupId>org.glassfish.main.ejb</groupId>
        <artifactId>ejb-container</artifactId>
        <version>4.1</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>javax.ejb</groupId>
        <artifactId>javax.ejb-api</artifactId>
        <version>3.2</version>
        <scope>test</scope>
    </dependency>

And the results: The embedded GF 4.1 container couldn't load that simple EJB (it is there in the target/classes folder, after a maven compile).

I get the following errors, based on the different code changes (like using properties to pass to the container or not):

GF 4.1 Embedded UnsatisfiedDependencyException

GF 4.1 Embedded Can't deploy

GF 4.1 Embedded Can't deploy EJB classes

The code I have pasted is giving the last error message linked.

And I don't understand. Everywhere I look for information, says this should work.

Also, if I try this, with OpenEJB container (sadly it is just jee6), it works fine.

<dependency>
    <groupId>org.apache.openejb</groupId>
    <artifactId>openejb-core</artifactId>
    <version>4.7.3</version>
    <scope>test</scope>
    </dependency>
    <dependency>
    <groupId>org.apache.openejb</groupId>
    <artifactId>javaee-api</artifactId>
    <version>6.0-6</version>
    <scope>test</scope>
    </dependency>

Thanks for the help!

Alexander Rühl
  • 6,769
  • 9
  • 53
  • 96
csabee
  • 217
  • 2
  • 12
  • Strange thing, I get a slightly different output when running the same test from IntelliJ Idea (first run was from eclipse). See output here: http://pastebin.com/DBxwRjCm – csabee Jan 11 '16 at 13:51

2 Answers2

0

Presumably not quite the answer to the question, but some more general thoughts to unit testing EJBs:

A unit test as the name says, should only test the unit itself, nothing more. And since EJB 3.x beans are POJOs, you can just write a plain JUnit test without having the need of an (embedded) container. And concerning the references to other beans, use a framework like Mockito to mock them away.

When doing integration testing, where you want several EJBs to interact, maybe in collaboration with a database, then you'll need the container, e.g. for having dependency injection. You might use an embedded container here, but you can also use a framework like Arquillian, since there you have the possibility to use a real container.

Alexander Rühl
  • 6,769
  • 9
  • 53
  • 96
  • As you can see, I was starting from a very simple test. We don't use arquillian, since it misses functions we would require. Also I find mockito useless. So please try to be helpful, I would like a solution to my problem, on why the embedded container is failing. – csabee Jan 09 '16 at 15:47
  • Also: for a product development, we would like to use the embedded shell of an app server, so a unit test is a very good starting point for this. – csabee Jan 09 '16 at 15:49
  • @csabee Well, as I said, it was a bit off-topic, but I did try to be helpful. Because many people try to use much more in a unit test as there ought to be, e.g. embedded containers, instead of using mocking which was designed for that. – Alexander Rühl Jan 09 '16 at 16:39
0

I think I have found a solution to my problem (currently it seems working, but I am not sure, if this is the real one).

Dependencies corrected:

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>7.0</version>
    <scope>provided</scope>
</dependency>

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

<dependency>
    <groupId>org.glassfish.main.common</groupId>
    <artifactId>simple-glassfish-api</artifactId>
    <version>4.1</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.glassfish.main.extras</groupId>
    <artifactId>glassfish-embedded-static-shell</artifactId>
    <version>4.1</version>
    <scope>system</scope>
    <systemPath>D:\\Development\\Servers\\glassfish4.1-activiti\\glassfish\\lib\\embedded\\glassfish-embedded-static-shell.jar</systemPath>
</dependency>

So what was really missing is the org.glassfish.main.common / simple-glassfish-api jar (not really sure why this is the solution to my problem).

And here is the fixed code:

public class BasicTest {
@EJB
private ExampleBean examplebean;
private Context context;
private EJBContainer container;

@Before
public void init(){
    try {
        container = EJBContainer.createEJBContainer();
        context = container.getContext();
        context.bind("inject", this);
    } catch (NamingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

@Test
public void testmeaning() throws NamingException{
    if(examplebean == null){
        examplebean = (ExampleBean) context.lookup("java:global/classes/ExampleBean");
    }

    assertEquals(42, examplebean.meaningOfLife());
}
}

Or using static members with @BeforeClass

public class BasicTest {

@EJB
private ExampleBean examplebean;
private static Context context;
private static EJBContainer container;

@BeforeClass
public static void init() {
    container = EJBContainer.createEJBContainer();
    context = container.getContext();
}

@Test
public void testmeaning() throws NamingException {
    if (examplebean == null) {
        examplebean = (ExampleBean) context.lookup("java:global/classes/ExampleBean");
    }
    assertEquals(42, examplebean.meaningOfLife());
}

}
csabee
  • 217
  • 2
  • 12