How To Use Scripting with Java EE 5/EJB 3.0 - sample app

Java SE 6 comes with really good and lean integration of scripting engines. It is already shipped with JavaScript - so no additional libraries or jars are required. The scripting capabilitiy can be used in Java EE 5 / EJB 3 context as well. Especially not really stable "glue" logic or dynamic interpretation of formulas can be very easy implemented. I built a sample of this "Fluid Kernel" pattern and checked it in to p4j5. It is a simple webapp, which computes mathematical formula dynamically.

The integration with the scripting engine is realized in a wrapper class:

package com.abien.javaee5patterns.fluidkernel.facade.scripting;
import com.abien.javaee5patterns.fluidkernel.facade.Calculator;
import java.util.logging.Logger;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class JSScripting implements Calculator{
    private final static Logger logger = Logger.getLogger(JSScripting.class.getName());
    private static final String ENGINE_NAME = "JavaScript";
    private ScriptEngine scriptEngine = null;;

        public JSScripting(){
        ScriptEngineManager engineManager = new ScriptEngineManager();
        this.scriptEngine  = engineManager.getEngineByName(ENGINE_NAME);
        if(this.scriptEngine==null)
            throw new IllegalStateException("Cannot create ScriptEngine: " + ENGINE_NAME);
    }
    public double calculate(String formula){
        Object retVal = null;
        try {
            logger.info("Trying to executing script engine with formula: " +formula);
            long start = System.nanoTime();
            retVal = this.scriptEngine.eval(formula);
            System.out.println("Executed in: " + (System.nanoTime() - start));
            logger.info("Formula: " +formula+ " executed !");
        } catch (Exception e) {
            throw new IllegalStateException("Exception during evaluating script: " +e,e);
        }
        return (Double) retVal;
    }
}

 

The class is used by an EBJ3 which just delegates the calls to the JSScripting:

@Stateless
@Remote(Calculator.class)
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class CalculatorBean implements Calculator {

    private JSScripting scripting;
   
    @PostConstruct
    private void init(){
        this.scripting = new JSScripting();
    }
    public double calculate(String expression) {
        return this.scripting.calculate(expression);
    }
}
 

The CalculatorBean is used from a servlet:

public class CalculatorView extends HttpServlet {
    @EJB
    private Calculator calculatorBean;
 

which is responsible for the rendering. This simplistic example demonstrates how easy it is to use the JSR-223 capabilities (scripting)  in EJB 3.0 context. The ready to deploy ear (with ear and war) can be downloaded from p4j5. It is described in the Java EE 5 Architekturen book as well. 

The funny story here: I named this "pattern" Fluid Kernel, however at last year JavaOne I had a nice conversation with Dierk Koenig, the author of the great book "Groovy In Action". He named the same pattern "Soft Heart" which is somehow similar.

Comments:

Nice -- I'm interested in using this kind of pattern for integration between layers, like in the Facade (a la Chris Richardson's "POJO's in Action", not the 'traditional' EJB facade), or as JSF Managed Beans... haven't had a chance to experiment yet, but I think it has potential...

M

Posted by Matt Corey on September 30, 2007 at 11:45 PM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
...the last 150 posts
...the last 10 comments
License