Scripting Java (1): execute scripts in Java

Source: Internet
Author: User

Scripting Java (1): execute scripts in Java

Extends implementations of scripting and dynamically typed extensions ages generate Java bytecodes so that programs can be run on the Java Platform, just as are actual Java programs. implementing a language in this way (or as a Java interpreter class for the scripting language) provides all the advantages of the Java platform: scripting implementations can take advantage of the Java platform's binary portability, security, and high performance bytecode execution.

The above section gives a good answer to why there are so many Java-based scripting languages. Anyway, today we just want to see how to execute the script language in our Java code. The following two languages are used to demonstrate Groovy 2.4.0 and Scala 2.11.5.

There are two ways to execute scripts in Java,

Java SE schemdes JSR 223: Scripting for the Java Platform API. this is a framework by which Java applications can host script engines. the scripting framework supports third-party script engines using the JAR service discovery mechanic. it is possible to drop any JSR-223 compliant script engine in the CLASSPATH and access the same from your Java applications (much like JDBC drivers, JNDI implementations are accessed ).

Therefore, we can use the JSR223 API to execute the script, or directly use the API provided by the script language. Next, let's take a look.

JSR-223

PassScriptEngineManager # getEngineByNameThis API we can get the implementation of the JSR-223 script engine, so how do we know what parameters to get Groovy and Scala engine? Rush in and check the code,

    public ScriptEngine getEngineByName(String shortName) {        if (shortName == null) throw new NullPointerException();        //look for registered name first        Object obj;        if (null != (obj = nameAssociations.get(shortName))) {            ScriptEngineFactory spi = (ScriptEngineFactory)obj;            try {                ScriptEngine engine = spi.getScriptEngine();                engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);                return engine;            } catch (Exception exp) {                if (DEBUG) exp.printStackTrace();            }        }        for (ScriptEngineFactory spi : engineSpis) {            List
 
   names = null;            try {                names = spi.getNames();            } catch (Exception exp) {                if (DEBUG) exp.printStackTrace();            }            if (names != null) {                for (String name : names) {                    if (shortName.equals(name)) {                        try {                            ScriptEngine engine = spi.getScriptEngine();                            engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);                            return engine;                        } catch (Exception exp) {                            if (DEBUG) exp.printStackTrace();                        }                    }                }            }        }        return null;    }
 
    /**     * Registers a ScriptEngineFactory to handle a language     * name.  Overrides any such association found using the Discovery mechanism.     * @param name The name to be associated with the ScriptEngineFactory.     * @param factory The class to associate with the given name.     * @throws NullPointerException if any of the parameters is null.     */    public void registerEngineName(String name, ScriptEngineFactory factory) {        if (name == null || factory == null) throw new NullPointerException();        nameAssociations.put(name, factory);    }

So we can see there are two ways to find ScriptEngine,

If ScriptEngineManager # registerEngineNameIf you have registered a name, you need to know the registered name. If not, you need to know the specific implementation of ScriptEngineFactory. GetNamesWhat is returned by the method;

ScriptEngineFactory is loaded through the ServiceLoader mechanism. Let's take a look at the implementation of Groovy and Scala,

The content of javax. script. ScriptEngineFactory is,

org.codehaus.groovy.jsr223.GroovyScriptEngineFactory
scala.tools.nsc.interpreter.IMain$Factory

If the registerEngineName method is not found, take a look at the respective getNames methods, of policyscriptenginefactory,

    private static final String SHORT_NAME = groovy;    private static final String LANGUAGE_NAME = Groovy;
    static {        List
 
   n = new ArrayList
  
   (2);        n.add(SHORT_NAME);        n.add(LANGUAGE_NAME);        NAMES = Collections.unmodifiableList(n);        n = new ArrayList
   
    (1);        n.add(groovy);        EXTENSIONS = Collections.unmodifiableList(n);        n = new ArrayList
    
     (1);        n.add(application/x-groovy);        MIME_TYPES = Collections.unmodifiableList(n);    }
    
   
  
 

So we can get groovy ScriptEngine through Groovy or Groovy. Take a look at IMain,

    @BeanProperty    val names: JList[String] = asJavaList(scala)

Alright, which is obtained through scala. The code is followed by two methods.

Shell

Both groovy. lang. policyshell and IMain can be used to directly execute scripts. These two are the APIS provided by the above scripting language.

We can try it in the shell environment provided by the script language,

$ sudo groovy/bin/groovysh[sudo] password for blues: Feb 3, 2015 12:36:43 AM org.codehaus.groovy.runtime.m12n.MetaInfExtensionModule newModuleWARNING: Module [groovy-nio] - Unable to load extension class [org.codehaus.groovy.runtime.NioGroovyMethods]Groovy Shell (2.4.0, JVM: 1.6.0_33)Type ':help' or ':h' for help.-----------------------------------------------------------------------------groovy:000> import groovy.lang.GroovyShell===> groovy.lang.GroovyShellgroovy:000> groovySh = new GroovyShell()===> groovy.lang.GroovyShell@1e74f8bgroovy:000> groovySh.evaluate(import java.util.Random; random = new Random(); random.nextInt();)===> -1378717507
$ scalaWelcome to Scala version 2.11.5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51).Type in expressions to have them evaluated.Type :help for more information.scala> import scala.tools.nsc.interpreter._import scala.tools.nsc.interpreter._scala> val iMain = new IMain()iMain: scala.tools.nsc.interpreter.IMain = scala.tools.nsc.interpreter.IMain@65adfc7bscala> iMain.eval(import java.util.Random; val random = new Random(); random.nextInt();)res0: Object = 1320282527

No problem.

Finally, let's go back to the initial question: How can I execute scripts in Java code? The following code is pasted together with the two methods,

import groovy.lang.GroovyShell;import scala.tools.nsc.interpreter.IMain;import javax.script.ScriptEngine;import javax.script.ScriptEngineManager;public class Main {    public static void main(String[] args) throws Exception {        ScriptEngineManager sem = new ScriptEngineManager();        String script_groovy =                import java.util.Random; random = new Random(); random.nextInt();;        ScriptEngine se_groovy = sem.getEngineByName(groovy);        System.out.println(se_groovy.eval(script_groovy));        GroovyShell groovyShell = new GroovyShell();        System.out.println(groovyShell.evaluate(script_groovy));        String script_scala =                import java.util.Random; val random = new Random(); random.nextInt();;        ScriptEngine se_scala = sem.getEngineByName(scala);        System.out.println(se_scala.eval(script_scala));        IMain iMain = new IMain();        System.out.println(iMain.eval(script_scala));    }}
142472532416912552974593273951109624277

I originally wanted to play the JDK's built-in JSR223 implementation, that is, Nashorn, which is an implementation of the ECMAScript Edition 5.1 Language Specification, but I have to go to jdk8. let's take a look at it another day.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.