All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.libs.graalsdk.package-info Maven / Gradle / Ivy

There is a newer version: RELEASE230
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/** Polyglot scripting tutorial.
 *
 * 
 * 

Polyglot Scripting Tutorial

*
* * This tutorial shows how to embed the various languages in a * NetBeans or even plain Java application via {@link org.netbeans.api.scripting.Scripting} helper methods. This * environment lets Java interoperate with standard as well as * GraalVM based * guest languages via foreign objects and foreign functions. * For example Java code * can directly access guest language methods, objects, classes, * and some complex data structures * with Java-typed accessors. In the reverse direction, guest language code can access Java objects, * classes, and constructors. *

* This tutorial helps you get started, starting with setup instructions, followed by descriptions of * different interoperation scenarios with (working) code examples. * * *

Contents

* *
*
* *

Setup

* * The most advanced features that this API provides work in cooperation with * GraalVM. * Downloading * GraalVM and running your (NetBeans) application on * GraalVM will give you access to the * polyglot features highlighted in this tutorial. *

* NetBeans modules are * uploaded to Maven central. You can use them from your pom.xml * file as: *

*

<dependency>
    <groupId>org.netbeans.api</groupId>
    <artifactId>scripting</artifactId>
    <version>11</version> <!-- or any later version -->
</dependency>
 * 
* *

Get started

* *

Guest language "Hello World!"

* * Integrating scripting into your Java application starts with building * an instance of {@link javax.script.ScriptEngineManager} via * {@link org.netbeans.api.scripting.Scripting#createManager()} helper method. * You can then use the engine to * {@link javax.script.ScriptEngine#eval evaluate} * guest language source code. *

* The following example evaluates a Python source, let it print a message, * returns it, and then "casts" the result to a Java string. * * {@codesnippet org.netbeans.libs.graalsdk.ScriptingTutorial#testHelloWorld} * *

It's a polyglot world

* * How to list all available languages? To obtain all registered engine * factories in the system use: *

* {@codesnippet org.netbeans.libs.graalsdk.ScriptingTutorial#listAll} *

* When the above code snippet is executed on GraalVM it may print: *

Found Oracle Nashorn
Found Graal.js
Found GraalVM:js
Found GraalVM:llvm
Found GraalVM:python
 * 
* e.g. a mixture of standard script engines in the JDK with additional ones * provided as GraalVM languages located * via dedicated implementation of {@link org.netbeans.spi.scripting.EngineProvider} * interface * *

Add a language

* * GraalVM * download comes with highly efficient implementations of JavaScript. * Additional languages like * Ruby, * the R and * Python * can be installed via the bin/gu Graal Updater tool: *

*

 * $ /graalvm/bin/gu available
 * Downloading: Component catalog
 * ComponentId              Version             Component name
 * ----------------------------------------------------------------
 * python                   1.0.0-rc9           Graal.Python
 * R                        1.0.0-rc9           FastR
 * ruby                     1.0.0-rc9           TruffleRuby
 * $ /graalvm/bin/gu install python
 * Downloading: Component catalog
 * Processing component archive: Component python
 * 
* * After invoking this command and downloading the bits, the JVM will be * ready to execute Python scripts. * *

Hello World in Python and JavaScript

* * The {@link org.netbeans.libs.graalsdk.Scripting Scripting.createManager()} method * is your gateway to polyglot world! Just create a manager and it can serve * as a hub where various language engines connect together. Following example * shows JavaScript and Python interacting with each other: *

* {@codesnippet org.netbeans.libs.graalsdk.ScriptingTutorial#testHelloWorldInPythonAndJavaScript} *

* Languages provided by GraalVM use the * {@link javax.script.ScriptEngineManager} created by * {@link org.netbeans.libs.graalsdk.Scripting#createManager()} factory * method as a connection point to talk to each other and mutually share * and use its objects, functions and other services. * *

Cast Array to List

* * Dynamic languages may represent array in their own special ways. * However the * {@link org.netbeans.libs.graalsdk.Scripting} interoperation let's you * view each array-like object as {@link java.util.List}. Just * "{@linkplain javax.script.Invocable#getInterface(java.lang.Object, java.lang.Class) cast it}" * like in following example: *

* {@codesnippet org.netbeans.libs.graalsdk.ScriptingTutorial#testCastJsArray} * * *

Call guest language functions from Java

* * {@link org.netbeans.libs.graalsdk.Scripting} interoperation lets Java call * foreign functions that guest language code exports * (details vary across languages). * This section presents a few examples. * *

Define and call a JavaScript function

* * A function exported from a dynamic language becomes a callable foreign function * by giving it a Java type, for example the Java interface {@code Multiplier} in the following code. *

* {@codesnippet org.netbeans.libs.graalsdk.ScriptingTutorial#callJavaScriptFunctionFromJava} * * Notes: *

    *
  • Evaluating the JS source returns an anonymous JS function of two arguments * represented as {@link java.lang.Object} that can be * {@linkplain javax.script.Invocable#getInterface(java.lang.Object, java.lang.Class) "cast"} * to a foreign function with a Java type.
  • *
  • Parentheses around the JS function definition keep it out of JavaScript's * global scope, so the Java object holds the only reference to it.
  • *
* *

Define and call a Python function

* * The same example can be rewritten to Python: *

* * {@codesnippet org.netbeans.libs.graalsdk.ScriptingTutorial#testPythonFunctionFromJava} * * Notes: *

    *
  • Evaluating the Python source defines a {@code mul} function and also * returns it as a value to the Java code that can * {@linkplain javax.script.Invocable#getInterface(Class) "cast"} * it to a foreign function with a given Java type.
  • *
* *

Call an existing R function

* * In this sample we use a reference to existing R function {@code qbinom} from the built-in stats package. *

* * {@codesnippet org.netbeans.libs.graalsdk.ScriptingTutorial#callRFunctionFromJava} * * Don't forget to install support for the R language into your GraalVM * instance: *

*

 * $ /graalvm/bin/gu install
 * 
* *

Call multiple guest language functions with shared state from Java

* * Often it is necessary to export multiple dynamic language functions that work * together, for example by sharing variables. This can be done by giving * an exported group of functions a Java type with more than a single method, * for example the Java interface {@code Counter} in the following code. *

* {@codesnippet org.netbeans.libs.graalsdk.ScriptingTutorial#callJavaScriptFunctionsWithSharedStateFromJava} * * Notes: *

    *
  • Evaluating the JS source returns an anonymous JS function of no arguments * assigned to {@code jsFunction}) that can be * {@linkplain javax.script.Invocable#invokeMethod executed directly}, * without giving it a Java type.
  • *
  • Executing {@code jsFunction} returns a JS dynamic object (containing two methods * and a shared variable) * that can be {@linkplain javax.script.Invocable#getInterface "cast"} * to a foreign object with a Java type.
  • *
  • Parentheses around the JS function definition keep it out of JavaScript's * global scope, so the Java object holds the only reference to it.
  • *
* *

Access guest language classes from Java

* *

Access a JavaScript class

* * The ECMAScript 6 specification adds the concept of typeless classes to JavaScript. * NetBeans {@link org.netbeans.libs.graalsdk.Scripting} * interoperation allows Java to access fields and functions of a JavaScript class, * for example the foreign function factory and class given the Java type * {@code Incrementor} in the following code. *

* {@codesnippet org.netbeans.libs.graalsdk.ScriptingTutorial#callJavaScriptClassFactoryFromJava} * * Notes: *

    *
  • Evaluating the JS source returns an anonymous JS function of no arguments assigned * to {@code jsFunction} that can be * {@linkplain javax.script.Invocable#invokeMethod executed directly}, * without giving it a Java type.
  • *
  • Executing {@code jsFunction} returns a JS factory method for class * {@code JSIncrementor} that can also be executed directly.
  • *
  • Executing the JS factory returns a JS object that can * be {@linkplain javax.script.Invocable#getInterface "cast"} * to a foreign object with the Java type {@code Incrementor}.
  • *
  • Parentheses around the JS function definition keep it out of JavaScript's * global scope, so the Java object holds the only reference to it.
  • *
* *

Access guest language data structures from Java

* * The method {@link javax.script.Invocable#getInterface invocable.getInterface(Class)} * plays an essential role supporting interoperation between Java and guest language data * structures. * This section presents a few examples. * *

Access a JavaScript Array

* * The following example demonstrates type-safe Java foreign access * to members of a JavaScript array with members of a known type, * accessed as a Java {@link java.util.List} of objects with type given by interface {@code Point}. *

* {@codesnippet org.netbeans.libs.graalsdk.ScriptingTutorial#accessJavaScriptArrayWithTypedElementsFromJava} * * Notes: *

    *
  • Evaluating the JS source returns an anonymous JS function of no arguments * assigned to {@code jsFunction}) that can be * {@linkplain javax.script.Invocable#getInterface "cast"} * to a foreign function with Java type {@code PointProvider}.
  • *
  • Invoking the foreign function (assigned to {@code pointProvider}) creates * a JS array, which is returned as a foreign object * with Java type {@code List}.
  • *
  • Parentheses around the JS function definition keep it out of JavaScript's * global scope, so the Java object holds the only reference to it.
  • *
* *

Access a JavaScript JSON structure

* * This example demonstrates type-safe Java foreign access to a JavaScript JSON-like * structure, based on JSON data returned by a GitHub API. * The GitHub response contains a list of repository objects. Each repository has an id, * name, list of URLs, and a nested structure describing its owner. Java interfaces * {@code Repository} and {@code Owner} define the structure as Java types. *

* The following Java code is able to inspect a JavaScript JSON data structure * generated by "mock parser" in a type-safe way. *

* {@codesnippet org.netbeans.libs.graalsdk.ScriptingTutorial#accessJavaScriptJSONObjectFromJava} * * Notes: *

    *
  • Evaluating the JS source returns an anonymous JS function of no arguments assigned * to {@code jsFunction} that can be * {@linkplain javax.script.Invocable#invokeMethod executed directly}, * without giving it a Java type.
  • *
  • Executing {@code jsFunction} returns a JS mock JSON parser function * (assigned to {@code jsMockParser}), that can be * {@linkplain javax.script.Invocable#getInterface "cast"} * to a foreign function with Java type {@code ParseJSON}.
  • *
  • Calling the Java-typed mock parser creates a JS data structure, which is * returned as a foreign object with Java type {@code List}. *
  • Parentheses around the JS function definition keep it out of JavaScript's * global scope, so the Java object holds the only reference to it.
  • *
* *

View any Object as Map

* * Each dynamic object coming from a GraalVM * language can be "cast" to a {@link java.util.Map}. Here is an example: * *

* {@codesnippet org.netbeans.libs.graalsdk.ScriptingTutorial#testCastPythonObj} * * While not type-safe, it is a generic approach able to inspect objects * of unknown structure. * *

Access Java from guest languages

* * Just like Java can access guest language objects, the guest languages may * access Java objects, their fields and call their methods. Few examples * follow. * *

Access Java fields and methods from JavaScript

* * Public members of Java objects can be exposed to guest language code * as foreign objects, for example Java objects of type {@code Moment} in * the following example. *

* {@codesnippet org.netbeans.libs.graalsdk.ScriptingTutorial#accessFieldsOfJavaObject} * * Notes: *

    *
  • Evaluating the JS source returns an anonymous JS function of one argument * assigned to {@code jsFunction} that can be executed directly with one argument.
  • *
  • The Java argument {@code javaMoment} is seen by the JS function as a * foreign object whose public fields are visible. *
  • Executing {@code jsFunction} returns a JS number * that can be * {@linkplain javax.script.Invocable#getInterface "cast"} * to a Java {@link java.lang.Number} and then to a Java {@code int}.
  • *
  • Parentheses around the JS function definition keep it out of JavaScript's * global scope, so the Java object holds the only reference to it.
  • *
*

* The multiple steps needed to convert the result in the above example * produces awkward code that can be simplified. * Instead of invoking the JS function directly, and "casting" the wrapped JS result, * we can instead * {@linkplain javax.script.Invocable#getInterface "cast"} * the JS function to a Java foreign function (of type {@code MomentConverter}) that * returns the desired Java type directly, as shown in the following variation. *

* {@codesnippet org.netbeans.libs.graalsdk.ScriptingTutorial#accessFieldsOfJavaObjectWithConverter} * *

Access Java constructors and static methods from JavaScript

* * Dynamic languages can also access the public constructors and public static methods * of any Java class for which they are provided a reference. * The following example shows JavaScript access to the public constructor of a Java * class. *

* {@codesnippet org.netbeans.libs.graalsdk.ScriptingTutorial#createJavaScriptFactoryForJavaClass} * * Notes: *

    *
  • Evaluating the JS source returns an anonymous JS function of one argument * assigned to {@code jsFunction} that can be executed directly with one argument.
  • *
  • The Java class argument {@code Moment.class} is seen by the JS function as a * foreign class whose public constructor is visible. *
  • Executing {@code jsFunction} with the Java class argument returns * a JS "factory" function (for the Java class) that can be * {@linkplain javax.script.Invocable#getInterface "cast"} * to the desired Java function type ({@code MomentFactory}).
  • *
  • Parentheses around the JS function definition keep it out of JavaScript's * global scope, so the Java object holds the only reference to it.
  • *
* *
* */ package org.netbeans.libs.graalsdk;




© 2015 - 2025 Weber Informatics LLC | Privacy Policy