| /* |
| * 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. |
| * |
| * <a name="tutorial"> |
| * <h1>Polyglot Scripting Tutorial</h1> |
| * </a> |
| * |
| * 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 |
| * <a href="http://graalvm.org">GraalVM</a> based |
| * <em>guest languages</em> via <em>foreign objects</em> and <em>foreign functions</em>. |
| * 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. |
| * <p> |
| * This tutorial helps you get started, starting with setup instructions, followed by descriptions of |
| * different interoperation scenarios with (working) code examples. |
| * |
| * |
| * <h2>Contents</h2> |
| * |
| * <div id="toc"></div> |
| * <div id="contents"> |
| * |
| * <h2>Setup</h2> |
| * |
| * The most advanced features that this API provides work in cooperation with |
| * <a href="http://graalvm.org">GraalVM</a>. |
| * Downloading |
| * <a href="http://graalvm.org">GraalVM</a> and running your (NetBeans) application on |
| * <a href="http://graalvm.org">GraalVM</a> will give you access to the |
| * polyglot features highlighted in this tutorial. |
| * <p> |
| * NetBeans modules are <a href="https://search.maven.org/search?q=org.netbeans.api"> |
| * uploaded to Maven central</a>. You can use them from your <em>pom.xml</em> |
| * file as: |
| * <p> |
| * <pre> |
| <dependency> |
| <groupId><b>org.netbeans.api</b></groupId> |
| <artifactId><b>scripting</b></artifactId> |
| <version>11</version> <em><!-- or any later version --></em> |
| </dependency> |
| * </pre> |
| * |
| * <h2>Get started</h2> |
| * |
| * <h3>Guest language "Hello World!"</h3> |
| * |
| * 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. |
| * <p> |
| * The following example evaluates a Python source, let it print a message, |
| * returns it, and then "casts" the result to a Java string. |
| * |
| * {@snippet file="org/netbeans/libs/graalsdk/ScriptingTutorial.java" region="testHelloWorld"} |
| * |
| * <h3>It's a polyglot world</h3> |
| * |
| * How to list all available languages? To obtain all registered engine |
| * factories in the system use: |
| * <p> |
| * {@snippet file="org/netbeans/libs/graalsdk/ScriptingTutorial.java" region="listAll"} |
| * <p> |
| * When the above code snippet is executed on <a href="http://graalvm.org">GraalVM</a> it may print: |
| * <pre> |
| Found Oracle Nashorn |
| Found Graal.js |
| Found GraalVM:js |
| Found GraalVM:llvm |
| Found GraalVM:python |
| * </pre> |
| * e.g. a mixture of standard script engines in the JDK with additional ones |
| * provided as <a href="http://graalvm.org">GraalVM</a> languages located |
| * via dedicated implementation of {@link org.netbeans.spi.scripting.EngineProvider} |
| * interface |
| * |
| * <h3>Add a language</h3> |
| * |
| * <a href="http://graalvm.org">GraalVM</a> |
| * download comes with highly efficient implementations of <em>JavaScript</em>. |
| * Additional languages like |
| * <a href="https://github.com/graalvm/truffleruby/">Ruby</a>, |
| * the <a href="https://github.com/graalvm/fastr/">R</a> and |
| * <a href="https://github.com/graalvm/graalpython/">Python</a> |
| * can be installed via the <code>bin/gu</code> <em>Graal Updater</em> tool: |
| * <p> |
| * <pre> |
| * $ /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 |
| * </pre> |
| * |
| * After invoking this command and downloading the bits, the JVM will be |
| * ready to execute Python scripts. |
| * |
| * <h3>Hello World in Python and JavaScript</h3> |
| * |
| * 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: |
| * <p> |
| * {@snippet file="org/netbeans/libs/graalsdk/ScriptingTutorial.java" region="testHelloWorldInPythonAndJavaScript"} |
| * <p> |
| * Languages provided by <a href="http://graalvm.org">GraalVM</a> 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. |
| * |
| * <h3>Cast Array to List</h3> |
| * |
| * 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: |
| * <p> |
| * {@snippet file="org/netbeans/libs/graalsdk/ScriptingTutorial.java" region="testCastJsArray"} |
| * |
| * |
| * <h2>Call guest language functions from Java</h2> |
| * |
| * {@link org.netbeans.libs.graalsdk.Scripting} interoperation lets Java call |
| * <em>foreign functions</em> that guest language code <em>exports</em> |
| * (details vary across languages). |
| * This section presents a few examples. |
| * |
| * <h3>Define and call a JavaScript function</h3> |
| * |
| * A function exported from a dynamic language becomes a callable <em>foreign function</em> |
| * by giving it a Java type, for example the Java interface {@code Multiplier} in the following code. |
| * <p> |
| * {@snippet file="org/netbeans/libs/graalsdk/ScriptingTutorial.java" region="callJavaScriptFunctionFromJava"} |
| * |
| * Notes: |
| * <ul> |
| * <li>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 <em>foreign function</em> with a Java type.</li> |
| * <li>Parentheses around the JS function definition keep it out of JavaScript's |
| * global scope, so the Java object holds the only reference to it.</li> |
| * </ul> |
| * |
| * <h3>Define and call a Python function</h3> |
| * |
| * The same example can be rewritten to Python: |
| * <p> |
| * |
| * {@snippet file="org/netbeans/libs/graalsdk/ScriptingTutorial.java" region="testPythonFunctionFromJava"} |
| * |
| * Notes: |
| * <ul> |
| * <li>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 <em>foreign function</em> with a given Java type.</li> |
| * </ul> |
| * |
| * <h3>Call an existing R function</h3> |
| * |
| * In this sample we use a reference to existing R function {@code qbinom} from the built-in <em>stats</em> package. |
| * <p> |
| * |
| * {@snippet file="org/netbeans/libs/graalsdk/ScriptingTutorial.java" region="callRFunctionFromJava"} |
| * |
| * Don't forget to install support for the R language into your <a href="http://graalvm.org">GraalVM</a> |
| * instance: |
| * <p> |
| * <pre> |
| * $ /graalvm/bin/gu install |
| * </pre> |
| * |
| * <h2>Call multiple guest language functions with shared state from Java</h2> |
| * |
| * 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. |
| * <p> |
| * {@snippet file="org/netbeans/libs/graalsdk/ScriptingTutorial.java" region="callJavaScriptFunctionsWithSharedStateFromJava"} |
| * |
| * Notes: |
| * <ul> |
| * <li>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.</li> |
| * <li>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 <em>foreign object</em> with a Java type.</li> |
| * <li>Parentheses around the JS function definition keep it out of JavaScript's |
| * global scope, so the Java object holds the only reference to it.</li> |
| * </ul> |
| * |
| * <h2>Access guest language classes from Java</h2> |
| * |
| * <h3>Access a JavaScript class</h3> |
| * |
| * 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 <em>foreign function</em> factory and class given the Java type |
| * {@code Incrementor} in the following code. |
| * <p> |
| * {@snippet file="org/netbeans/libs/graalsdk/ScriptingTutorial.java" region="callJavaScriptClassFactoryFromJava"} |
| * |
| * Notes: |
| * <ul> |
| * <li>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.</li> |
| * <li>Executing {@code jsFunction} returns a JS factory method for class |
| * {@code JSIncrementor} that can also be executed directly.</li> |
| * <li>Executing the JS factory returns a JS object that can |
| * be {@linkplain javax.script.Invocable#getInterface "cast"} |
| * to a <em>foreign object</em> with the Java type {@code Incrementor}.</li> |
| * <li>Parentheses around the JS function definition keep it out of JavaScript's |
| * global scope, so the Java object holds the only reference to it.</li> |
| * </ul> |
| * |
| * <h2>Access guest language data structures from Java</h2> |
| * |
| * 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. |
| * |
| * <h3>Access a JavaScript Array</h3> |
| * |
| * 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}. |
| * <p> |
| * {@snippet file="org/netbeans/libs/graalsdk/ScriptingTutorial.java" region="accessJavaScriptArrayWithTypedElementsFromJava"} |
| * |
| * Notes: |
| * <ul> |
| * <li>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 <em>foreign function</em> with Java type {@code PointProvider}.</li> |
| * <li>Invoking the foreign function (assigned to {@code pointProvider}) creates |
| * a JS array, which is returned as a <em>foreign object</em> |
| * with Java type {@code List<Point>}.</li> |
| * <li>Parentheses around the JS function definition keep it out of JavaScript's |
| * global scope, so the Java object holds the only reference to it.</li> |
| * </ul> |
| * |
| * <h3>Access a JavaScript JSON structure</h3> |
| * |
| * 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. |
| * <p> |
| * The following Java code is able to inspect a JavaScript JSON data structure |
| * generated by "mock parser" in a type-safe way. |
| * <p> |
| * {@snippet file="org/netbeans/libs/graalsdk/ScriptingTutorial.java" region="accessJavaScriptJSONObjectFromJava"} |
| * |
| * Notes: |
| * <ul> |
| * <li>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.</li> |
| * <li>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 <em>foreign function</em> with Java type {@code ParseJSON}.</li> |
| * <li>Calling the Java-typed mock parser creates a JS data structure, which is |
| * returned as a <em>foreign object</em> with Java type {@code List<Repository>}. |
| * <li>Parentheses around the JS function definition keep it out of JavaScript's |
| * global scope, so the Java object holds the only reference to it.</li> |
| * </ul> |
| * |
| * <h3>View any Object as Map</h3> |
| * |
| * Each dynamic object coming from a <a href="http://graalvm.org">GraalVM</a> |
| * language can be "cast" to a {@link java.util.Map}. Here is an example: |
| * |
| * <p> |
| * {@snippet file="org/netbeans/libs/graalsdk/ScriptingTutorial.java" region="testCastPythonObj"} |
| * |
| * While not type-safe, it is a generic approach able to inspect objects |
| * of unknown structure. |
| * |
| * <h2>Access Java from guest languages</h2> |
| * |
| * Just like Java can access guest language objects, the guest languages may |
| * access Java objects, their fields and call their methods. Few examples |
| * follow. |
| * |
| * <h3>Access Java fields and methods from JavaScript</h3> |
| * |
| * <em>Public</em> members of Java objects can be exposed to guest language code |
| * as <em>foreign objects</em>, for example Java objects of type {@code Moment} in |
| * the following example. |
| * <p> |
| * {@snippet file="org/netbeans/libs/graalsdk/ScriptingTutorial.java" region="accessFieldsOfJavaObject"} |
| * |
| * Notes: |
| * <ul> |
| * <li>Evaluating the JS source returns an anonymous JS function of one argument |
| * assigned to {@code jsFunction} that can be executed directly with one argument.</li> |
| * <li>The Java argument {@code javaMoment} is seen by the JS function as a |
| * <em>foreign object</em> whose public fields are visible.</em> |
| * <li>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}.</li> |
| * <li>Parentheses around the JS function definition keep it out of JavaScript's |
| * global scope, so the Java object holds the only reference to it.</li> |
| * </ul> |
| * <p> |
| * 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. |
| * <p> |
| * {@snippet file="org/netbeans/libs/graalsdk/ScriptingTutorial.java" region="accessFieldsOfJavaObjectWithConverter"} |
| * |
| * <h3>Access Java constructors and static methods from JavaScript</h3> |
| * |
| * Dynamic languages can also access the <em>public constructors</em> and <em>public static methods</em> |
| * 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. |
| * <p> |
| * {@snippet file="org/netbeans/libs/graalsdk/ScriptingTutorial.java" region="createJavaScriptFactoryForJavaClass"} |
| * |
| * Notes: |
| * <ul> |
| * <li>Evaluating the JS source returns an anonymous JS function of one argument |
| * assigned to {@code jsFunction} that can be executed directly with one argument.</li> |
| * <li>The Java class argument {@code Moment.class} is seen by the JS function as a |
| * <em>foreign class</em> whose public constructor is visible.</em> |
| * <li>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}).</li> |
| * <li>Parentheses around the JS function definition keep it out of JavaScript's |
| * global scope, so the Java object holds the only reference to it.</li> |
| * </ul> |
| * |
| * <h2>Exception handling</h2> |
| * Exceptions are thrown in different way, depending on whether <b>the script</b> |
| * (guest language) raised the error, or the error came from the host language, e.g. |
| * a java object called from the script. |
| * <ul> |
| * <li>Exceptions from the script code are always |
| * reported as {@link javax.script.ScriptException} that provides the appropriate details. |
| * <li>Checked exceptions from host (java) code, unhandled by the script are raised as |
| * some {@link java.lang.RuntimeException} subclasses; the {@link java.lang.Throwable#getCause} then indicates |
| * the original cause for the exception. |
| * <li>Unchecked exceptions are directly propagated. |
| * {@snippet file="org/netbeans/libs/graalsdk/ScriptingTutorial.java" region="handleScriptExceptions"} |
| * </ul> |
| * |
| * </div> |
| * <script src="doc-files/tutorial.js"></script> |
| */ |
| package org.netbeans.libs.graalsdk; |