EmbeddedAndJavaSE

Setting up to use within Java SE Environments (plain java apps)

This section talks about using Embedded JBoss with a regular Java application.  The embedded distribution looks like this:

 

embedded-jboss/
               bootstrap/
                        conf/
                        deploy/
                        deployers/
                        jndi.properties
                        log4j.xml
               lib/

 

To be able to use embedded JBoss you must have all the files in embedded-jboss/lib/ in your classpath.  The main org.jboss.embedded.Bootstrap class uses the classpath to find configuration files so the embedded-jboss/bootstrap/ directory needs to be in your classpath to. 

 

If you are familiar with JBoss Application Server, you'll notice that the bootstrap directory contents look very similar to the JBoss Application Server directory structure.  This is on purpose.  It was designed to be as close as possible to JBoss AS configuration and uses as many of the same exact configuration files.

 

Bootstraping Embedded JBoss

 

There are 2 ways to startup Embedded JBoss in your application.  The first way is by bootstrapping it explicitly using the org.jboss.embedded.Bootstrap class.

 

myapp.java

import org.jboss.embedded.Bootstrap;

public class MyApp 
{
   public static void main(String[] args) throws Exception 
   {
       Bootstrap.getInstance().bootstrap();
       ...
       // your app code here

       Bootstrap.getInstance().shutdown();
   }
}

 

Embedded JBoss also has a JNDI InitialContextFactory that bootstraps the kernel:

 

java.naming.factory.initial=org.jboss.embedded.jndi.KernelInitializingContextFactory

 

If you are using JBoss Security, this InitialContextFactory makes use of these jndi/system properties:

 

  • javax.naming.Context.SECURITY_PRINCIPAL

  • javax.naming.Context.SECURITY_CREDENTIALS

  • javax.naming.Context.SECURITY_PROTOCOL

 

If Context.SECURITY_PRINCIPAL and Context.SECURITY_CREDENTIALS are set,

this InitialContextFactory implementation combines the

authentication phase with the InitialContext creation. During the

getInitialContext callback from the JNDI naming, layer security context

identity is populated with the username obtained from the

Context.SECURITY_PRINCIPAL env property and the credentials from the

Context.SECURITY_CREDENTIALS env property. There is no actual authentication

of this information. It is merely made available to the jboss transport

layer for incorporation into subsequent invocations. Authentication and

authorization will occur on the server.

 

If Context.SECURITY_PROTOCOL is provided as well as the principal and credentials,

then a JAAS login will be performed instead using the security domain provided with the

SECURITY_PROTOCOL variable.

 

 

 

Deploying JBoss components and user applications

 

There are a few ways you can deploy JBoss services and things like EJBs and JPA archives.

 

Using the deploy/ directory

 

Just like JBoss AS, you can place files within the deploy/ directory and they will be automatically deployed by the bootstrapping mechanism of Embedded JBoss.  JARS ARE NOT ADDED TO CLASSPATH.  It is important to remember that Embedded JBoss gives total control over classloading and the classpath to you, the application developer.  Embedded JBoss will try and deploy jar file types within the deploy/ directory but unless you have added that jar file to your classpath manually, Embedded JBoss will not add the jar automatically to your classpath.  Again, this is because it is up to the app developer to decide this.

 

For example, lets say we had a EJB jar file named titan-ejbs.jar.  WE could put it in the bootstrap/deploy/ directory but we would also have to add the jar to our classpath:

 

set CLASSPATH=%CLASSPATH%;embedded-jboss\bootstrap\deploy\titan-ejbs.jar

 

Deploying a JCA resource archive (.rar) file

 

Embedded JBoss does support deploying .rar files, but it will not add nested jars into your application's classpath.  So, what you have to do is unpackage the .rar and move any nested jar files into your classpath.  For example, unjar the embedded-jboss/bootstrap/deploy/jboss-xa-jdbc.rar file.  You will see that it just contains a META-INF/ra.xml file.  The nested jars that contain the classes for the implementation of this rar are in your classpath via the embedded-jboss/lib/jboss-embedded-all.jar file.

 

Deploying other file types

 

Any non-jar file type, like a ds.xml file, -server.xml file, etc. can be added to the deploy/ directory just as JBoss AS and deployed.  No additonal CLASSPATH configurations are required.

 

Manual deployment

 

The org.jboss.embedded.Bootstrap class has a number of methods that allow you to deploy individual files programmatically.  Check the javadoc of this class for more details, but here are some of the more interesting ones:

 

bootstrap.deployResourceBases("META-INF/persistence.xml");

 

This method will do a ClassLoader.getResources() to find all the root jars or classpath diretories a resource of that path and name is located.  All these base jars and directories will be deployed.

 

bootstrap.deployResourceBase(Foo.class);

 

This method find what jar or classpath directory the .class file for Foo is located and deploys that jar or classpath directory root.

 

Virtual Archives

 

The JBoss 5 kernel uses an archive abstraction to represent a deployable unit (a directory or .jar file).  This is called the VFS.  VFS has one particularly interesting plugin that allows you to define a virtual jar that contains any arbitrary resource or bytes within it.  Once you have programmatically defined this archive, you can deploy it via Bootstrap methods.  Here's an example:

 

import org.jboss.virtual.plugins.context.vfs.AssembledContextFactory;
import org.jboss.virtual.plugins.context.vfs.AssembledDirectory;

...

      AssembledDirectory jar = AssembledContextFactory.getInstance().create("ejbTestCase.jar");
      jar.addClass(Customer.class);
      jar.addClass(CustomerDAOBean.class);
      jar.addClass(CustomerDAOLocal.class);
      jar.addClass(CustomerDAORemote.class);
      jar.mkdir("META-INF").addResource("tutorial-persistence.xml", "persistence.xml");

      Bootstrap.getInstance().deploy(jar);

 

In this example, we're programmatically creating a virtual .jar file named "ejbTestCase.jar".  We use the AssembledContextFactory class to create the base of the virtual archive, then programmatically add classes to the archive using the addClass() methods.  We create a META-INF directory in the virtual archive using the mkdir() method, then add an aliased resource to the virtual META-INF directory.  The addResource() in this method is looking for the file "tutorial-persistence.xml" in your classpath.  It adds it to the virtual META-INF directory under the name "persistence.xml".

 

Why is this useful?

 

This is particularly useful in unit testing from your IDE.    When writing code in your IDE you may not want to have to add specific .jar files to your classpath, or even to create those .jar files so that you are able to deploy.

 

Here's yet another interesting use of the AssembledDirectory API:

 

      AssembledDirectory jar = AssembledContextFactory.getInstance().create("tutorial.jar");
      String[] includes = {"**/beans/*.class"};
      jar.addResources(Customer.class, includes, null);
      // Get tutorial-persistence.xml from classloader and alias it within the archive.
      jar.mkdir("META-INF").addResource("tutorial-persistence.xml", "persistence.xml");

 

Here we're using a different method AssembledDirectory.addResources() to build the virtual archive.  The addResources method allows you to define Ant expressions to match resources in a specific .jar or classpath directory.  So, in the example, the .jar file that contains Customer.class will be scanned for any files that match the "/beans/.class" pattern and those files will be added to the virtual archive.