adam bien's blog

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.