Using The Glassfish EJBContainer in Netbeans.
As many already know, one of the features of Java EE 6 is the javax.ejb.embeddable packages that allows you to create an embedded EJB container through EJBContainer.createEJBContainer(). This is a useful feature when you want to write a unit test for your EJB's.
Sometimes you want a little bit more control over what is configured in the embedded EJBContainer. In this entry we will look at how we can specify a custom domain.xml to use with glassfish v3 implementation of this embedded container.
By default it searches your classpath for ejb-jar jarfiles or folders and deploys them. In netbeans this means
it will deploy the application you are working on. One of the problems is that most of the time you want to use
some specific JBDC resources and JDBC connection pools. I already showed you in one of my previous entries how
to set up the embedded-glassfish maven instance with a custom datasource. So all I'm going to explain is how to
start the embedded EJBContainer.createEJBContainer() with the needed properties to load your own custom domain.xml.
I'm also going to point you out to the source of my information, so you can help yourself in the case you want to
do more and specify a custom installation path or a custom instance path.
The first thing you need to keep in mind is that when you run your unit tests in netbeans it uses the project folder as the working directory for the virtual machine. This means that when we specify a relative path, it is a relative path starting from this working directory. You can of course use full paths by using Classloader.getResource or Class.getResource, but there is one problem you need to be aware: when you put your custom domain.xml in the test folder, it is not going to be copied to the build/test folder as so using XXXTest.class.getResource("../domain.xml") .getPath() will not yield the expected results. To solve this, I always make a folder "test-resource" in my projects that contains my domain.xml and embedded derby db. (Remember to add the needed database drivers to the "run test" classpath in the properties of you project.)
Once everything is in place, you can start the container with the following piece of code:
Map props = new HashMap();
props.put("org.glassfish.ejb.embedded.glassfish.configuration.file", "test-resources/domain.xml");
instance = javax.ejb.embeddable.EJBContainer.createEJBContainer(props);
The line that does the magic trick is the props.put line where I use a magic variable name. This is something I got from the glassfish sources itself. You can find the relevant class here. If you look into this file you see several other properties: org.glassfish.ejb.embedded.glassfish.installation.root and org.glassfish.ejb.embedded.glassfish.instance.root .
One more thing that might be usefull is the use of the embedded derby driver. A connection pool as follows
<jdbc-connection-pool is-isolation-level-guaranteed="false" name="4eo-identity-connection-pool" datasource-classname="org.apache.derby.jdbc.EmbeddedXADataSource" res-type="javax.sql.XADataSource">
<property value="test-resource/4eo-identity-test" name="databaseName" />
</jdbc-connection-pool>
will use a database file that is located in the same test-resource folder as your domain.xml. This allows you to use a precreated database with testdata.
And a last thing is, you can use the constant EJBContainer.MODULES via the properties you pass to the createEJBContainer method to specify which modules to load, thereby overriding the default (loading all ejb-jars in the classpath.) as follows:
Map props = new HashMap();
props.put("org.glassfish.ejb.embedded.glassfish.configuration.file", "test-resources/domain.xml");
props.put(EJBContainer.MODULES, new File[] { new File("dist.ejb.jar")})
instance = javax.ejb.embeddable.EJBContainer.createEJBContainer(props);
That is all.