Entries tagged [newfeatures]

Thursday April 29, 2010

Several new features for Stateless Beans

As OpenEJB is deployed into more and more production environments we've been hard at work filling out the system to meet demands. The latest overhaul has been around the @Stateless bean pooling options.

At a high level, the new features provide:

  • Availability: guarantee a minimum number of instance in a pool, from startup and through the entire life of the pool.
  • Shrinking: aggressively shrink pools via an inactive bean timeout and/or gracefully shrink pools via VM garbage collection when memory is needed.
  • Freshness: aggressively flush a pool via the bean's SessionContext and/or gracefully expire, and possibly replace, beans via a max age.
  • Using the above features it's possible to build a pool to fit your exact needs. The pool shrinking functionality allows a pool that has reached its maximum size to shrink down over time to its minimum size (which can be zero!) either aggressively or gracefully, keeping resources consumed at a minimum. The freshness functionality allows the entire pool, even the minimum, to be purged and renewed either aggressively or gracefully over time, preventing leaky state from building up over the long life of the pool.

    The new options are: PoolMin, IdleTimeout, PollInterval, MaxAge, ReplaceAged, MaxAgeOffset, and CallbackThreads. Garbage collection functionality is achieved internally through java.lang.SoftReference(s) and nothing is required to enable it, though it can be tuned at the VM level. Pool flushing can be done via the javax.ejb.SessionContext object of Stateless beans which now can be cast to java.io.Flushable.

    All of the above functionality is of course thread-safe. Instances cannot be garbage collected, expired via MaxAge, or flushed while in use. Calling flush() on a "hot" pool will not affect instances in use till they return to the pool. The same applies for any instances that reach their MaxAge while in use -- they are only expired once returned to the pool.

    The above options are properly tuned and balanced as well and will not compete. For example, flushing a pool will not cause any instances created to refill the pool to have the same creation time and therefore expire together in one, very ungraceful, drop. Creation times will be skewed to keep MaxAge expiration spread out. As well MaxAge and IdleTimeout are enforced together such that MaxAge is enforced, instances are transitioned into the "minimum side" of the pool as needed, and the remainder is subject to IdleTimeout. The pool will not timeout a perfectly good instance that could be used to keep the pool at it's minimum.

    Friday June 05, 2009

    Apache OpenEJB 3.1.1 Released

    The Apache OpenEJB team is excited to announce the release of OpenEJB 3.1.1.

    This release includes some great enhancements for the embedded testing scenarios and general EJB programming. Notable improvements include:

    - Dependency injection for test cases and clients of the embedded ejb container via new @LocalClient annotation.
    - Support for annotating the same interface as @Local, @Remote and @WebService making it possible to exposing all possible EJB views with a single interface.
    - Web Service views securable with @RolesAllowed, @PermitAll and @DenyAll annotations.
    - Ability to easily use alternate sets of deployment descriptors for some or all tests via new 'openejb.altdd.prefix' property.
    - Global lookups from any context simplified via new "openejb:" jndi namespace.

    The release also contains several new examples including Applets invoking EJBs in webapps, Struts with JPA and EJB, secured web services and web services with Perl SOAP::Lite clients and more.

    Monday May 04, 2009

    Mapped name with OpenEJB

    Recently we added the facility to use the mappedName attribute from a @Stateful, @Stateless or @Singleton annotation to add a global JNDI name for your bean. This is pretty simple to use, simply add the mapped name to your bean like so:

    @Stateless(mappedName="MyCalculatorBean")
    public class CalculatorImpl implements CalculatorRemote, CalculatorLocal {
    
    	public int sum(int add1, int add2) {
    		return add1+add2;
    	}
    
    	public int multiply(int mul1, int mul2) {
    		return mul1*mul2;
    	}
    }
    
    When this is deployed you will see:
    Apache OpenEJB 3.1.1-SNAPSHOT    build: 20090425-09:05
    http://openejb.apache.org/
    INFO - openejb.home = /home/jgallimore/Sync/OpenEJB/src/openejb3/examples/simple-stateless
    INFO - openejb.base = /home/jgallimore/Sync/OpenEJB/src/openejb3/examples/simple-stateless
    INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service)
    INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager)
    INFO - Found EjbModule in classpath: /home/jgallimore/Sync/OpenEJB/src/openejb3/examples/simple-stateless/target/classes
    INFO - Beginning load: /home/jgallimore/Sync/OpenEJB/src/openejb3/examples/simple-stateless/target/classes
    INFO - Configuring enterprise application: classpath.ear
    INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container)
    INFO - Auto-creating a container for bean CalculatorImpl: Container(type=STATELESS, id=Default Stateless Container)
    INFO - Enterprise application "classpath.ear" loaded.
    INFO - Assembling app: classpath.ear
    INFO - Jndi(name=CalculatorImplLocal) --> Ejb(deployment-id=CalculatorImpl)
    INFO - Jndi(name=MyCalculatorBean) --> Ejb(deployment-id=CalculatorImpl)
    INFO - Jndi(name=MyCalculatorBean) --> Ejb(deployment-id=CalculatorImpl)
    INFO - Created Ejb(deployment-id=CalculatorImpl, ejb-name=CalculatorImpl, container=Default Stateless Container)
    INFO - Deployed Application(path=classpath.ear)
    
    You will now be able to lookup your bean by doing:
    Properties properties = new Properties();
    properties.setProperty (Context.INITIAL_CONTEXT_FACTORY,"org.apache.openejb.client.LocalInitialContextFactory");
    
    InitialContext initialContext = new InitialContext(properties);
    Calculator calc = initialContext.lookup("MyCalculatorBean");
    
    You might also be aware that with OpenEJB you can also specify how global JNDI names are assigned by the container (when you haven't specified a mappedName). You do this by setting a property with a template: For example, setting the following system property (for an embedded OpenEJB instance in a unit test)
    System.setProperty("openejb.jndiname.format", "{deploymentId}/{interfaceClass}");
    
    Would result in these JNDI names:
    INFO - Jndi(name=CalculatorImpl/org.superbiz.calculator.CalculatorLocal) --> Ejb(deployment-id=CalculatorImpl)
    INFO - Jndi(name=CalculatorImpl/org.superbiz.calculator.CalculatorRemote) --> Ejb(deployment-id=CalculatorImpl)
    
    You can see more details on these templates and the variables available at: http://openejb.apache.org/3.0/jndi-names.html

    We can also use this template mechanism with the @Stateful/@Stateless/@Singleton mappedName attribute. So this code:

    @Stateless(mappedName="{deploymentId}/{interfaceClass}")
    public class CalculatorImpl implements CalculatorRemote, CalculatorLocal {
    
    	public int sum(int add1, int add2) {
    		return add1+add2;
    	}
    
    	public int multiply(int mul1, int mul2) {
    		return mul1*mul2;
    	}
    
    }
    
    would yield the following JNDI names being set up:
    INFO - Enterprise application "classpath.ear" loaded.
    INFO - Assembling app: classpath.ear
    INFO - Jndi(name=CalculatorImplLocal) --> Ejb(deployment-id=CalculatorImpl)
    INFO - Jndi(name=CalculatorImpl/org.superbiz.calculator.CalculatorRemote) --> Ejb(deployment-id=CalculatorImpl)
    INFO - Jndi(name=CalculatorImpl/org.superbiz.calculator.CalculatorRemote) --> Ejb(deployment-id=CalculatorImpl)
    

    Wednesday April 29, 2009

    Lookups into the openejb namespace

    To ease the burden in looking up things from OpenEJB's internal JNDI tree, we've added a new "openejb" JNDI URL prefix which can be used in any context to do lookups.

    The following will work in a TestCase or EJB or any code running in the same VM as the EJB Container.

    InitialContext context = new InitialContext();
    
    TransactionManager tm = (TransactionManager) context.lookup("openejb:TransactionManager");
    DataSource dataSource = (DataSource) context.lookup("openejb:Resource/MyDataSource");
    

    Tuesday April 28, 2009

    Alternate descriptors for testing

    Inspired by some user blog posts, we've added a new feature so support for altDD (alternative deployment descriptors) can be done in a test or other environment without much work.

    Basically, just set the new "openejb.altdd.prefix" system property or initialcontext property to something like "test", then any descriptors in your META-INF/ directory that start with "test." will override the regular descriptor. So for example with an app like this:

  • META-INF/ejb-jar.xml
  • META-INF/test.ejb-jar.xml
  • META-INF/persistence.xml
  • META-INF/test.env-entry.properties

    Just initialize your test case like so:

     Properties properties = new Properties();
     properties.setProperty(Context.INITIAL_CONTEXT_FACTORY,
          "org.apache.openejb.client.LocalInitialContextFactory");
     properties.setProperty("openejb.altdd.prefix", "test");
    
     InitialContext initialContext = new InitialContext(properties);
    
    The logical result will be:

  • META-INF/ejb-jar.xml (via test.ejb-jar.xml)
  • META-INF/persistence.xml
  • META-INF/env-entry.properties (via test.env-entry.properties)

    This will work in any environment in which OpenEJB works (embedded, standalone, tomcat, geronimo, etc.).

  • Calendar

    Search

    Hot Blogs (today's hits)

    Tag Cloud

    Categories

    Feeds

    Links

    Navigation