Buscar..


Introducción

Nashorn es un motor de JavaScript desarrollado en Java por Oracle, y se ha lanzado con Java 8. Nashorn permite integrar Javascript en aplicaciones Java a través de JSR-223 y permite desarrollar aplicaciones de JavaScript independientes, y proporciona un mejor rendimiento en tiempo de ejecución y un mejor cumplimiento con el ECMA Especificación de Javascript normalizada.

Sintaxis

  • ScriptEngineManager // Proporciona un mecanismo de descubrimiento e instalación para las clases de ScriptEngine; utiliza un SPI (Interfaz de Proveedor de Servicios)
  • ScriptEngineManager.ScriptEngineManager () // constructor recomendado
  • ScriptEngine // Proporciona la interfaz para el lenguaje de scripting
  • ScriptEngine ScriptEngineManager.getEngineByName (String shortName) // Método de fábrica para la implementación dada
  • Object ScriptEngine.eval (String script) // Ejecuta el script especificado
  • Object ScriptEngine.eval (Reader Reader) // Carga y luego ejecuta un script desde la fuente especificada
  • ScriptContext ScriptEngine.getContext () // Devuelve el proveedor predeterminado de enlaces, lectores y escritores
  • void ScriptContext.setWriter (escritor escritor) // Establece el destino para enviar la salida del script a

Observaciones

Nashorn es un motor de JavaScript escrito en Java e incluido en Java 8. Todo lo que necesita está incluido en el paquete javax.script .

Tenga en cuenta que ScriptEngineManager proporciona una API genérica que le permite obtener motores de secuencias de comandos para varios lenguajes de secuencias de comandos (es decir, no solo Nashorn, no solo JavaScript).

Establecer variables globales

// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

// Define a global variable
engine.put("textToPrint", "Data defined in Java.");

// Print the global variable
try {
    engine.eval("print(textToPrint);");
} catch (ScriptException ex) {
    ex.printStackTrace();
}

// Outcome:
// 'Data defined in Java.' printed on standard output

Hola Nashorn

// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

// Execute an hardcoded script
try {
    engine.eval("print('Hello Nashorn!');");
} catch (ScriptException ex) {
    // This is the generic Exception subclass for the Scripting API
    ex.printStackTrace();
}

// Outcome:
// 'Hello Nashorn!' printed on standard output

Ejecutar archivo JavaScript

// Required imports
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import java.io.FileReader;
import java.io.FileNotFoundException;

// Obtain an instance of the JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

// Load and execute a script from the file 'demo.js'
try {
    engine.eval(new FileReader("demo.js"));
} catch (FileNotFoundException ex) {
    ex.printStackTrace();
} catch (ScriptException ex) {
    // This is the generic Exception subclass for the Scripting API
    ex.printStackTrace();
}

// Outcome:
// 'Script from file!' printed on standard output

demo.js :

print('Script from file!');

Salida de script de intercepción

// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

// Setup a custom writer
StringWriter stringWriter = new StringWriter();
// Modify the engine context so that the custom writer is now the default
// output writer of the engine
engine.getContext().setWriter(stringWriter);

// Execute some script
try {
    engine.eval("print('Redirected text!');");
} catch (ScriptException ex) {
    ex.printStackTrace();
}

// Outcome:
// Nothing printed on standard output, but
// stringWriter.toString() contains 'Redirected text!'

Evaluar cadenas aritméticas

// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");

//String to be evaluated
String str = "3+2*4+5";
//Value after doing Arithmetic operation with operator precedence will be 16

//Printing the value
try {
    System.out.println(engine.eval(str));
} catch (ScriptException ex) {
    ex.printStackTrace();
}

//Outcome:
//Value of the string after arithmetic evaluation is printed on standard output.
//In this case '16.0' will be printed on standard output.

Uso de objetos Java en JavaScript en Nashorn

Es posible pasar objetos Java al motor Nashorn para ser procesados ​​en código Java. Al mismo tiempo, hay algunas construcciones específicas de JavaScript (y Nashorn), y no siempre está claro cómo funcionan con los objetos java.

A continuación hay una tabla que describe el comportamiento de los objetos Java nativos dentro de las construcciones de JavaScript.

Construcciones probadas:

  1. Expresión en cláusula if. En la expresión JS, la cláusula if no tiene que ser booleana a diferencia de Java. Se evalúa como falso para los llamados valores falsos (nulo, indefinido, 0, cadenas vacías, etc.)
  2. Para cada declaración, Nashorn tiene un tipo especial de bucle, para cada una, que puede iterar sobre diferentes objetos JS y Java.
  3. Obtención del tamaño del objeto. En JS, los objetos tienen una longitud de propiedad, que devuelve el tamaño de una matriz o una cadena.

Resultados:

Tipo Si para cada .longitud
Java nulo falso Sin iteraciones Excepción
Java cadena vacía falso Sin iteraciones 0
Cadena de Java cierto Iteriza sobre caracteres de cadena Longitud de la cuerda
Java Integer / Long valor! = 0 Sin iteraciones indefinido
Java ArrayList cierto Itera sobre los elementos Longitud de la lista
Java HashMap cierto Iteriza sobre los valores. nulo
Java HashSet cierto Iterar sobre elementos indefinido

Recomendaciones:

  • Es recomendable usar if (some_string) para verificar si una cadena no es nula y no está vacía
  • for each puede usar de forma segura para iterar sobre cualquier colección, y no genera excepciones si la colección no es iterable, nula o indefinida
  • Antes de obtener la longitud de un objeto, debe comprobarse si está nulo o no definido (lo mismo se aplica a cualquier intento de llamar a un método u obtener una propiedad del objeto Java)

Implementando una interfaz desde script

import java.io.FileReader;
import java.io.IOException;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class InterfaceImplementationExample {
    public static interface Pet {
        public void eat();
    }

    public static void main(String[] args) throws IOException {
        // Obtain an instance of JavaScript engine
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("nashorn");

        try {
            //evaluate a script
            /* pet.js */
            /*
                var Pet = Java.type("InterfaceImplementationExample.Pet");
                
                new Pet() {
                    eat: function() { print("eat"); }
                }            
            */
            
            Pet pet = (Pet) engine.eval(new FileReader("pet.js"));
            
            pet.eat();
        } catch (ScriptException ex) {
            ex.printStackTrace();
        }

        // Outcome:
        // 'eat' printed on standard output
    }
}

Establecer y obtener variables globales.

// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

try {
    // Set value in the global name space of the engine
    engine.put("name","Nashorn");
    // Execute an hardcoded script
    engine.eval("var value='Hello '+name+'!';");
    // Get value
    String value=(String)engine.get("value");
    System.out.println(value);
} catch (ScriptException ex) {
    // This is the generic Exception subclass for the Scripting API
    ex.printStackTrace();
}

// Outcome:
// 'Hello Nashorn!' printed on standard output


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow