Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Note

Disclaimer that we do tweak and change this code frequently, without notice. It is the very heart of OpenEJB. To keep things tight and clean, we reserve the right to change it at anytime. Do not consider it a stable public API.

Overview in Code

First a glimpse of how OpenEJB looks internally. Here's a test that builds OpenEJB using it's internal API. This is somewhat similar to how you might see people constructing Jetty in code. All our internal tests look like this.

This usage involves no xml parsing or classpath scanning. If you don't give it to OpenEJB, OpenEJB doesn't know about it. This is OpenEJB with all the magic stripped away. Disclaimer that we do tweak and change this code frequently. It is the very heart of OpenEJB and we need to keep the flexibility to change it at anytime, so do not consider it a stable public API. If you are fine with some instability, you are welcome to use it. It is no doubt very powerfulAt a high level:

  1. You build your app in code using the JAXB tree in code and hand it to the ConfigurationFactory.
    1. The org.apache.openejb.jee package contains JAXB trees for ejb-jar.xml, beans.xml and all the Java EE deployment descriptors.
  2. The ConfigurationFactory will produce a fully canonical version of the app called the Info tree by:
    1. Merging all sources of meta-data – xml and annotations
    2. Resolving all ejb, persistence unit, datasource and other references
    3. Validating the app and looking for mistakes
  3. The Info tree is
    1. The singular source of information about the application from this point forward.
    2. Pure data with no smarts or logic of any kind.
    3. The instruction set of what would be built by the assembler.
  4. The Assembler will build and start the application exactly as described in the Info tree.
    1. When this step completes, you have a running application.
    2. Any failures prior to this point require no cleanup. Only the assembler builds "live" objects.
Code Block
titleStatefulTest.java
import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.naming.InitialContext;

import junit.framework.TestCase;
import org.apache.openejb.assembler.classic.Assembler;
import org.apache.openejb.assembler.classic.SecurityServiceInfo;
import org.apache.openejb.assembler.classic.TransactionServiceInfo;
import org.apache.openejb.client.LocalInitialContextFactory;
import org.apache.openejb.config.ConfigurationFactory;
import org.apache.openejb.jee.EjbJar;
import org.apache.openejb.jee.StatefulBean;

/**
 * This test case serves as a nice tiny template for other test cases
 * and purposely doesn't do anything very complicated.
 *
 * @version $Rev$ $Date$
 */
public class StatefulTest extends TestCase {

    @Override
    protected void setUp() throws Exception {

        System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName());

        ConfigurationFactory config = new ConfigurationFactory();
        Assembler assembler = new Assembler();

        assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
        assembler.createSecurityService(config.configureService(SecurityServiceInfo.class));

        EjbJar ejbJar = new EjbJar();
        ejbJar.addEnterpriseBean(new StatefulBean(MyBean.class));

        assembler.createApplication(config.configureApplication(ejbJar));
    }

    public void test() throws Exception {
        InitialContext context = new InitialContext();
        MyBean myBean = (MyBean) context.lookup("MyBeanLocalBean");

        assertEquals("pan", myBean.echo("nap"));
    }

    @Stateful
    @LocalBean
    public static class MyBean {

        public String echo(String string) {
            StringBuilder sb = new StringBuilder(string);
            return sb.reverse().toString();
        }
    }
}

Logical Overview

Slightly more detailed account of the above. Our startup and deploy world is broken into two phases:

...

The listings above aren't necesarrily complete or perfectly ordered, but generally show the nature of the work done in each phase.

Configuration Phase

A goal is that nothing gets through configuration and into assembly if it can't actually be built. The configuration phase is where we're supposed to wipe away any ambiguity, fully normalize the app, make sure it's internally consistent, spec compliant and generally good to go. If it's not, no worries as we actually haven't built anything permanent yet. Everything in the configuration phase is temporary. If it fails the configuration phase we just issue an error and say "App will not be loaded" and that's it, there's nothing to undo.

...