jakarta-eejpaglassfishejbmaven-glassfish-plugin

How to define a test datasource for an embedded EJB container


I am trying to test my EJBs using an embedded EJB container. In production, I rely on a JTA datasource configured in the application server. However, during testing, I want to connect to a different DB (in-memory Derby).

The problem is that I can't see how to tell the EJB container to override the JTA datasource defined in my production persistence.xml (in src/main/resources/META-INF) with a connection to my in-memory derby DB. The JTA datasource is defined in the persistence.xml file like so:

<jta-data-source>jdbc/myDS</jta-data-source>

Attempt 1: Using a test persistence.xml

I tried creating a test persistence.xml file (in src/test/resources/META-INF) which defines:

<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:derby:memory:myDataBase;create=true;" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="password" /> 

This is moot though, because when I specify the EJB container to use the module under test with

Map properties = new HashMap();
properties.put(EJBContainer.MODULES, new File[] { new File("target/classes/") });
ec = EJBContainer.createEJBContainer(properties);

the container just uses the main persistence.xml file instead of my test one.

Attempt 2: Merging main and test classes into a single exploded module

The only way I can see to make this approach work is by using the approach described here - to copy the classes for the module under test to a separate location (eg target/ejb-testing-classes), then copy the test persistence.xml file over the top, then specify this new location to the EJB container:

Map properties = new HashMap();
properties.put(EJBContainer.MODULES, new File[] { new File("target/ejb-testing-classes/") });
ec = EJBContainer.createEJBContainer(properties);

But this seems needlessly clumsy. It might also be a problem in the future if I'm trying to deploy pre-packaged modules (ie dependencies) in the container since I would need to explode the jars before merging.

My Wish: Datasource override properties for the EJB container

I thought there might be additional properties that could be passed into the EJB container, but so far I can only find properties appropriate for openEJB or websphere. I am using embedded Glassfish to provide my embedded EJB container as that is the target platform. (I have now found the glassfish property - see Update #1, below)

Surely everyone who has tried testing EJBs with an embedded EJB container and a datasource different to that of the production DB has come across this problem. Even this guy just gave up at this point and used the default embedded DB, which is not an option for me.

Any help would be much appreciated.

Update 1: I have found the list of properties that the Glassfish EJB container accepts, and at first it appears that I could use the following property

org.glassfish.ejb.embedded.glassfish.configuration.file

to define a datasource in a domain.xml and point the container to it. However, according to the source code, this property is ignored unless the installation.root property is also set - and that would mean needing a pre-existing installation of glassfish just to run my tests. This would unacceptably lower the portability of my Maven project. :(

Update 2: I have create a JIRA issue for this problem and recommended that properties be introduced for the glassfish EJB container which allows configuration of a JTA datasource.


Solution

  • Can't be done with embedded Glassfish.

    As I noted in Update 1, in order to configure the embedded EJB container with a datasource, you must:

    1. configure a domain.xml file with the new datasource
    2. configure the embedded EJB container to use an existing Glassfish AS installation
    3. configure the embedded EJB container to use the domain.xml file from step 1.

    So (thanks to step 2) goodbye, portability. But this is the 'solution' I have to go with until the Glassfish devs address my request to configure datasources via a property (see the JIRA link above in the question).