docs/JavaScriptingProgrammersGuide.html

Wed, 22 May 2013 16:39:48 +0530

author
sundar
date
Wed, 22 May 2013 16:39:48 +0530
changeset 283
07cefc062032
parent 279
1fd18f40ab52
child 377
26a345c26e62
permissions
-rw-r--r--

8008947: ScriptEnvironment ctor should be public
Reviewed-by: lagergren, attila

     1 <!--
     2  Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
     3  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5  This code is free software; you can redistribute it and/or modify it
     6  under the terms of the GNU General Public License version 2 only, as
     7  published by the Free Software Foundation.  Oracle designates this
     8  particular file as subject to the "Classpath" exception as provided
     9  by Oracle in the LICENSE file that accompanied this code.
    11  This code is distributed in the hope that it will be useful, but WITHOUT
    12  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  version 2 for more details (a copy is included in the LICENSE file that
    15  accompanied this code).
    17  You should have received a copy of the GNU General Public License version
    18  2 along with this work; if not, write to the Free Software Foundation,
    19  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    21  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  or visit www.oracle.com if you need additional information or have any
    23  questions.
    24 -->
    25 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    26 <html class=" regenabled  gecko radius jsenabled regloaded" xmlns="http://www.w3.org/1999/xhtml"><head>
    27 <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
    28 <title>Java Scripting Programmer's Guide</title>
    30 <!-- ============ -->
    31 <!-- MAIN CONTENT -->
    32 <!-- ============ -->
    33 <table summary="layout" border="0" width="100%">
    34 <tbody><tr>
    35 <td>
    37 <div id="sharepage" class="smallpagetitle"><h1>Java Scripting Programmer's Guide</h1><div class="sharepage">		<div class="sharepagew1 share-mailto">		<table summary="" cellpadding="0" cellspacing="0"><tbody><tr>		<td id="share-mailto"><a href="mailto:?subject=Java%20Documentation%20Page:%20Java%20Scripting%20Programmer%27s%20Guide&amp;body=Check%20out%20this%20page:%20%0A%0Ahttp%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Ftechnotes%2Fguides%2Fscripting%2Fprogrammer_guide%2Findex.html" class="sharelink mailto" title="Email this page to a friend"></a></td>		<td id="share-technorati"><a href="http://technorati.com/search/http%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Ftechnotes%2Fguides%2Fscripting%2Fprogrammer_guide%2Findex.html" class="sharelink technorati" title="See who links to this page on Technorati"></a></td>		<td id="share-delicious"><a href="http://del.icio.us/post?v=4;url=http%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Ftechnotes%2Fguides%2Fscripting%2Fprogrammer_guide%2Findex.html;title=Java%20Scripting%20Programmer%27s%20Guide" class="sharelink delicious" title="Bookmark this page in del.icio.us"></a></td>		<td id="share-digg"><a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Ftechnotes%2Fguides%2Fscripting%2Fprogrammer_guide%2Findex.html&amp;title=Java%20Scripting%20Programmer%27s%20Guide" class="sharelink digg" title="Submit this page to Digg"></a></td>		<td id="share-slashdot"><a href="http://slashdot.org/bookmark.pl?title=Java%20Scripting%20Programmer%27s%20Guide&amp;url=http%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Ftechnotes%2Fguides%2Fscripting%2Fprogrammer_guide%2Findex.html" class="sharelink slashdot" title="Submit this page to Slashdot"></a></td>		<td id="share-blank"> </td></tr></tbody></table></div></div></div>
    39 </td>
    40 </tr>
    41 </tbody></table>
    42 <!-- Body text begins here -->
    43 <ul>
    44 <li><span><a href="#who">Who is the Java Scripting API
    45 For?</a></span></li>
    46 <li><span><a href="#package">Scripting Package</a></span></li>
    47 <li><span><a href="#examples">Examples</a></span>
    48 <ul>
    49 <li><span><a href="#helloworld">"Hello, World"</a></span></li>
    50 <li><span><a href="#evalfile">Evaluating a Script
    51 File</a></span></li>
    52 <li><span><a href="#scriptvars">Script Variables</a></span></li>
    53 <li><span><a href="#invoke">Invoking Script Functions and
    54 Methods</a></span></li>
    55 <li><span><a href="#interfaces">Implementing Java Interfaces by
    56 Scripts</a></span></li>
    57 <li><span><a href="#scopes">Multiple Scopes for
    58 Scripts</a></span></li>
    59 </ul>
    60 </li>
    61 <li><span><a href="#jsengine">JavaScript Script
    62 Engine</a></span></li>
    63 <li><span><a href="#jstojava">JavaScript to Java
    64 Communication</a></span>
    65 <ul>
    66 <li><span><a href="#jsjavaclass">Accessing Java
    67 Classes</a></span></li>
    68 <li><span><a href="#jsimport">Importing Java Packages,
    69 Classes</a></span></li>
    70 <li><span><a href="#jsarrays">Creating, Converting and Using Java
    71 Arrays</a></span></li>
    72 <li><span><a href="#jsimplement">Implementing Java
    73 Interfaces</a></span></li>
    74 <li><span><a href="#jsextendabstract">Extending Abstract Java Classes
    75 </a></span></li>
    76 <li><span><a href="#jsextendconcrete">Extending Concrete Java Classes
    77 </a></span></li>
    78 <li><span><a href="#jsimplementmultiple">Implementing Multiple Java Interfaces
    79 </a></span></li>
    80 <li><span><a href="#classBoundImplementations">Class-Bound Implementations
    81 </a></span></li>
    82 <li><span><a href="#jsoverload">Overload Resolution</a></span></li>
    83 <li><span><a href="#dataTypeMapping">Mapping of Data Types Between Java
    84 and JavaScript</a></span></li>
    88 </ul>
    89 </li>
    90 <li><span><a href="#engineimpl">Implementing Your Own Script
    91 Engine</a></span></li>
    92 <li><span><a href="#refs">References</a></span></li>
    93 </ul>
    94 <span><a name="who" id="who"></a></span>
    95 <h2><span>Who is the Java Scripting API For?</span></h2>
    96 <span>Some useful characteristics of scripting languages
    97 are:</span>
    98 <ul>
    99 <li><span><b>Convenience</b>: Most scripting languages are
   100 dynamically typed. You can usually create new variables without
   101 declaring the variable type, and you can reuse variables to store
   102 objects of different types. Also, scripting languages tend to
   103 perform many type conversions automatically, for example,
   104 converting the number 10 to the text "10" as necessary.</span></li>
   105 <li><span><b>Developing rapid prototypes</b>: You can avoid the
   106 edit-compile-run cycle and just use edit-run!</span></li>
   107 <li><span><b>Application extension/customization</b>: You can
   108 "externalize" parts of your application - like configuration
   109 scripts, business logic/rules and math expressions for financial
   110 applications.</span></li>
   111 <li><span><b>"Command line" shells for applications</b> -for
   112 debugging, runtime/deploy time configuration etc. Most applications
   113 have a web-based GUI configuaration tool these days. But
   114 sysadmins/deployers frequently prefer command line tools. Instead
   115 of inventing ad-hoc scripting language for that purpose, a
   116 "standard" scripting language can be used.</span></li>
   117 </ul>
   118 <p><span>The Java<font size="-1"><sup>TM</sup></font> Scripting API
   119 is a scripting language indepedent framework for using script
   120 engines from Java code. With the Java Scripting API, it is possible
   121 to write customizable/extendable applications in the Java language
   122 and leave the customization scripting language choice to the end
   123 user. The Java application developer need not choose the extension
   124 language during development. If you write your application with
   125 JSR-223 API, then your users can use any JSR-223 compliant
   126 scripting language.</span></p>
   127 <hr>
   128 <span><a name="package" id="package"></a></span>
   129 <h2><span>Scripting Package</span></h2>
   130 <p><span>The Java Scripting functionality is in the <code><a href="http://docs.oracle.com/javase/6/docs/api/javax/script/package-summary.html">javax.script</a></code>
   131 package. This is a relatively small, simple API. The starting point
   132 of the scripting API is the <code>ScriptEngineManager</code> class.
   133 A ScriptEngineManager object can discover script engines through
   134 the jar file service discovery mechanism. It can also instantiate
   135 ScriptEngine objects that interpret scripts written in a specific
   136 scripting language. The simplest way to use the scripting API is as
   137 follows:</span></p>
   138 <ol>
   139 <li><span>Create a <code>ScriptEngineManager</code>
   140 object.</span></li>
   141 <li><span>Get a <code>ScriptEngine</code> object from the
   142 manager.</span></li>
   143 <li><span>Evaluate script using the <code>ScriptEngine</code>'s
   144 <code>eval</code> methods.</span></li>
   145 </ol>
   146 <p><span>Now, it is time to look at some sample code. While it is
   147 not mandatory, it may be useful to know a bit of JavaScript to read
   148 these examples.</span></p>
   149 <hr>
   150 <span><a name="examples" id="examples"></a></span>
   151 <h2><span>Examples</span></h2>
   152 <span><a name="helloworld" id="helloworld"></a></span>
   153 <h3><span>"Hello, World"</span></h3>
   154 <p><span>From the <code>ScriptEngineManager</code> instance, we
   155 request a JavaScript engine instance using
   156 <code>getEngineByName</code> method. On the script engine, the
   157 <code>eval</code> method is called to execute a given String as
   158 JavaScript code! For brevity, in this as well as in subsequent
   159 examples, we have not shown exception handling. There are checked
   160 and runtime exceptions thrown from <code>javax.script</code> API.
   161 Needless to say, you have to handle the exceptions
   162 appropriately.</span></p>
   163 <pre>
   164 <span><code>
   165 // <a href="source/EvalScript.java">EvalScript.java</a>
   167 import javax.script.*;
   168 public class EvalScript {
   169     public static void main(String[] args) throws Exception {
   170         // create a script engine manager
   171         <span class="classref">ScriptEngineManager</span> factory = new ScriptEngineManager();
   172         // create a JavaScript engine
   173         <span class="classref">ScriptEngine</span> engine = factory.<span class="methodref">getEngineByName</span>("nashorn");
   174         // evaluate JavaScript code from String
   175         engine.<span class="methodref">eval</span>("print('Hello, World')");
   176     }
   177 }
   178 </code></span>
   179 </pre>
   180 <hr>
   181 <a name="evalfile" id="evalfile"></a>
   182 <h3>Evaluating a Script File</h3>
   183 <p>In this example, we call the <code>eval</code> method that
   184 accepts <code>java.io.Reader</code> for the input source. The
   185 script read by the given reader is executed. This way it is
   186 possible to execute scripts from files, URLs and resources by
   187 wrapping the relevant input stream objects as readers.</p>
   188 <pre>
   189 <code>
   190 // <a href="source/EvalFile.java">EvalFile.java</a>
   192 import javax.script.*;
   194 public class EvalFile {
   195     public static void main(String[] args) throws Exception {
   196         // create a script engine manager
   197         <span class="classref">ScriptEngineManager</span> factory = new ScriptEngineManager();
   198         // create JavaScript engine
   199         <span class="classref">ScriptEngine</span> engine = factory.<span class="methodref">getEngineByName</span>("nashorn");
   200         // evaluate JavaScript code from given file - specified by first argument
   201         engine.<span class="methodref">eval</span>(new java.io.FileReader(args[0]));
   202     }
   203 }
   204 </code>
   205 </pre>
   206 Let us assume that we have the file named <a href="source/test.js">test.js</a> with the
   207 following text:
   208 <pre><code>
   209 print("This is hello from test.js");
   210 </code>
   211 </pre>
   212 We can run the above Java as
   213 <pre><code>
   214 java EvalFile test.js
   215 </code>
   216 </pre>
   217 <hr>
   218 <a name="scriptvars" id="scriptvars"></a>
   219 <h3>Script Variables</h3>
   220 <p>When you embed script engines and scripts with your Java
   221 application, you may want to expose your application objects as
   222 global variables to scripts. This example demonstrates how you can
   223 expose your application objects as global variables to a script. We
   224 create a <code>java.io.File</code> in the application and expose
   225 the same as a global variable with the name "file". The script can
   226 access the variable - for example, it can call public methods on
   227 it. Note that the syntax to access Java objects, methods and fields
   228 is dependent on the scripting language. JavaScript supports the
   229 most "natural" Java-like syntax.</p>
   230 <pre><code>
   231 // <a href="source/ScriptVars.java">ScriptVars.java</a>
   233 import javax.script.*;
   234 import java.io.*;
   236 public class ScriptVars { 
   237     public static void main(String[] args) throws Exception {
   238         ScriptEngineManager manager = new ScriptEngineManager();
   239         ScriptEngine engine = manager.getEngineByName("nashorn");
   241         File f = new File("test.txt");
   242         // expose File object as variable to script
   243         engine.<span class="methodref">put</span>("file", f);
   245         // evaluate a script string. The script accesses "file" 
   246         // variable and calls method on it
   247         engine.eval("print(file.getAbsolutePath())");
   248     }
   249 }
   251 </code>
   252 </pre>
   253 <hr>
   254 <a name="invoke" id="invoke"></a>
   255 <h3>Invoking Script Functions and Methods</h3>
   256 <p>Sometimes you may want to call a specific scripting function
   257 repeatedly - for example, your application menu functionality might
   258 be implemented by a script. In your menu's action event handler you
   259 may want to call a specific script function. The following example
   260 demonstrates invoking a specific script function from Java
   261 code.</p>
   262 <pre><code>
   263 // <a href="source/InvokeScriptFunction.java">InvokeScriptFunction.java</a>
   265 import javax.script.*;
   267 public class InvokeScriptFunction {
   268     public static void main(String[] args) throws Exception {
   269         ScriptEngineManager manager = new ScriptEngineManager();
   270         ScriptEngine engine = manager.getEngineByName("nashorn");
   272         // JavaScript code in a String
   273         String script = "function hello(name) { print('Hello, ' + name); }";
   274         // evaluate script
   275         engine.eval(script);
   277         // <code>javax.script.Invocable</code> is an optional interface.
   278         // Check whether your script engine implements it or not!
   279         // Note that the JavaScript engine implements Invocable interface.
   280         <span class="classref">Invocable</span> inv = (Invocable) engine;
   282         // invoke the global function named "hello"
   283         inv.<span class="methodref">invokeFunction</span>("hello", "Scripting!!" );
   284     }
   285 }
   287 </code>
   288 </pre>
   289 <p>If your scripting language is object based (like JavaScript) or
   290 object-oriented, then you can invoke a script method on a script
   291 object.</p>
   292 <pre><code>
   293 // <a href="source/InvokeScriptMethod.java">InvokeScriptMethod.java</a>
   295 import javax.script.*;
   297 public class InvokeScriptMethod {
   298     public static void main(String[] args) throws Exception {
   299         ScriptEngineManager manager = new ScriptEngineManager();
   300         ScriptEngine engine = manager.getEngineByName("nashorn");
   302         // JavaScript code in a String. This code defines a script object 'obj'
   303         // with one method called 'hello'.        
   304         String script = "var obj = new Object(); obj.hello = function(name) { print('Hello, ' + name); }";
   305         // evaluate script
   306         engine.eval(script);
   308         // <code>javax.script.Invocable</code> is an optional interface.
   309         // Check whether your script engine implements or not!
   310         // Note that the JavaScript engine implements Invocable interface.
   311         <span class="classref">Invocable</span> inv = (Invocable) engine;
   313         // get script object on which we want to call the method
   314         Object obj = engine.<span class="methodref">get</span>("obj");
   316         // invoke the method named "hello" on the script object "obj"
   317         inv.<span class="methodref">invokeMethod</span>(obj, "hello", "Script Method !!" );
   318     }
   319 }
   321 </code>
   322 </pre>
   323 <hr>
   324 <a name="interfaces" id="interfaces"></a>
   325 <h3>Implementing Java Interfaces by Scripts</h3>
   326 <p>Instead of calling specific script functions from Java,
   327 sometimes it is convenient to implement a Java interface by script
   328 functions or methods. Also, by using interfaces we can avoid having
   329 to use the <code>javax.script</code> API in many places. We can get
   330 an interface implementor object and pass it to various Java APIs.
   331 The following example demonstrates implementing the
   332 <code>java.lang.Runnable</code> interface with a script.</p>
   333 <pre><code>
   334 // <a href="source/RunnableImpl.java">RunnableImpl.java</a>
   336 import javax.script.*;
   338 public class RunnableImpl {
   339     public static void main(String[] args) throws Exception {
   340         ScriptEngineManager manager = new ScriptEngineManager();
   341         ScriptEngine engine = manager.getEngineByName("nashorn");
   343         // JavaScript code in a String
   344         String script = "function run() { print('run called'); }";
   346         // evaluate script
   347         engine.eval(script);
   349         <span class="classref">Invocable</span> inv = (Invocable) engine;
   351         // get Runnable interface object from engine. This interface methods
   352         // are implemented by script functions with the matching name.
   353         Runnable r = inv.<span class="methodref">getInterface</span>(Runnable.class);
   355         // start a new thread that runs the script implemented
   356         // runnable interface
   357         Thread th = new Thread(r);
   358         th.start();
   359         th.join();
   360     }
   361 }
   362 </code>
   363 </pre>
   364 <p>If your scripting language is object-based or object-oriented,
   365 it is possible to implement a Java interface by script methods on
   366 script objects. This avoids having to call script global functions
   367 for interface methods. The script object can store the "state"
   368 associated with the interface implementor.</p>
   369 <pre><code>
   370 // <a href="source/RunnableImplObject.java">RunnableImplObject.java</a>
   372 import javax.script.*;
   374 public class RunnableImplObject {
   375     public static void main(String[] args) throws Exception {
   376         ScriptEngineManager manager = new ScriptEngineManager();
   377         ScriptEngine engine = manager.getEngineByName("nashorn");
   379         // JavaScript code in a String
   380         String script = "var obj = new Object(); obj.run = function() { print('run method called'); }";
   382         // evaluate script
   383         engine.eval(script);
   385         // get script object on which we want to implement the interface with
   386         Object obj = engine.<span class="methodref">get</span>("obj");
   388         <span class="classref">Invocable</span> inv = (Invocable) engine;
   390         // get Runnable interface object from engine. This interface methods
   391         // are implemented by script methods of object 'obj'
   392         Runnable r = inv.<span class="methodref">getInterface</span>(obj, Runnable.class);
   394         // start a new thread that runs the script implemented
   395         // runnable interface
   396         Thread th = new Thread(r);
   397         th.start();
   398         th.join();
   399     }
   400 }
   401 </code>
   402 </pre>
   403 <hr>
   404 <a name="scopes" id="scopes"></a>
   405 <h3>Multiple Scopes for Scripts</h3>
   406 <p>In the <a href="#scriptvars">script variables</a> example, we
   407 saw how to expose application objects as script global variables.
   408 It is possible to expose multiple global "scopes" for scripts. A
   409 single scope is an instance of <code>javax.script.Bindings</code>.
   410 This interface is derived from <code>java.util.Map&lt;String,
   411 Object&gt;</code>. A scope a set of name-value pairs where name is
   412 any non-empty, non-null String.
   413 <code>javax.script.ScriptContext</code> interface supports multiple
   414 scopes with associated Bindings for each
   415 scope. By default, every script engine has a default script
   416 context. The default script context has atleast one scope called
   417 "ENGINE_SCOPE". Various scopes supported by a script context are
   418 available through <code>getScopes</code> method.</p>
   419 <pre><code>
   420 // <a href="source/MultiScopes.java">MultiScopes.java</a>
   422 import javax.script.*;
   424 public class MultiScopes {
   425     public static void main(String[] args) throws Exception {
   426         ScriptEngineManager manager = new ScriptEngineManager();
   427         ScriptEngine engine = manager.getEngineByName("nashorn");
   429         engine.put("x", "hello");
   430         // print global variable "x"
   431         engine.eval("print(x);");
   432         // the above line prints "hello"
   434         // Now, pass a different script context
   435         <span class="classref">ScriptContext</span> newContext = new <span class="classref">SimpleScriptContext</span>();
   436         newContext.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
   437         <span class="classref">Bindings</span> engineScope = newContext.<span class="methodref">getBindings</span>(ScriptContext.ENGINE_SCOPE);
   439         // add new variable "x" to the new engineScope        
   440         engineScope.<span class="methodref">put</span>("x", "world");
   442         // execute the same script - but this time pass a different script context
   443         engine.eval("print(x);", newContext);
   444         // the above line prints "world"
   445     }
   446 }
   448 </code>
   449 </pre>
   450 <hr>
   451 <a name="jsengine" id="jsengine"></a>
   452 <h2>JavaScript Script Engine</h2>
   453 <p>Oracle's implementation of JDK 8 is co-bundled with the Nashorn ECMAScript
   454 script engine.
   455 <hr>
   456 <a name="jstojava" id="jstojava"></a>
   457 <h2>JavaScript to Java Communication</h2>
   458 <p>For the most part, accessing Java classes, objects and methods
   459 is straightforward. In particular field and method access from
   460 JavaScript is the same as it is from Java. We highlight important
   461 aspects of JavaScript Java access here. 
   462 The following examples are JavaScript snippets accessing Java. This
   463 section requires knowledge of JavaScript. This section can be
   464 skipped if you are planning to use some other JSR-223 scripting
   465 language rather than JavaScript.</p>
   466 <hr>
   467 <a name="jsjavaclass" id=jsjavalass"></a>
   468 <h3>Accessing Java Classes</h3>
   469 <pre>
   470 <code>
   471 // <a href="source/javatypes.js">javatypes.js</a>
   473  var arrayListType = Java.type("java.util.ArrayList")
   474  var intType = Java.type("int")
   475  var stringArrayType = Java.type("java.lang.String[]")
   476  var int2DArrayType = Java.type("int[][]")
   477 </code>
   478 </pre> 
   480 Note that the name of the type is always a string for a fully qualified name. You can use any of these expressions to create new instances, e.g.:
   482 <pre><code>
   483  var anArrayList = new (Java.type("java.util.ArrayList"))
   484 </code></pre> 
   486 or
   488 <pre><code>
   489  var ArrayList = Java.type("java.util.ArrayList")
   490  var anArrayList = new ArrayList
   491  var anArrayListWithSize = new ArrayList(16)
   492 </code></pre> 
   494 In the special case of inner classes, you need to use the JVM fully qualified name, meaning using $ sign in the class name:
   496 <pre><code>
   497  var ftype = Java.type("java.awt.geom.Arc2D$Float")
   498 </code></pre> 
   501 However, once you retrieved the outer class, you can access the inner class as a property on it:
   503 <pre><code>
   504  var arctype = Java.type("java.awt.geom.Arc2D")
   505  var ftype = arctype.Float
   506 </code></pre> 
   507 <p>
   508 You can access both static and non-static inner classes. If you want to create an instance of a non-static inner class, remember to pass an instance of its outer class as the first argument to the constructor.
   509 </p>
   510 <p>
   511 In addition to creating new instances, the type objects returned from <code>Java.type</code> calls can also be used to access the
   512 static fields and methods of the classes:
   513 <pre><code>
   514  var File = Java.type("java.io.File")
   515  File.createTempFile("nashorn", ".tmp")
   516 </code></pre> 
   517 <p>
   518 Methods with names of the form <code>isXxx()</code>, <code>getXxx()</code>, and <code>setXxx()</code> can also be used as properties, for both instances and statics.
   519 </p>
   520 <p>
   521 A type object returned from <code>Java.type</code> is distinct from a <code>java.lang.Class</code> object. You can obtain one from the other using properties <code>class</code> and <code>static</code> on them.
   522 <pre><code>
   523  var ArrayList = Java.type("java.util.ArrayList")
   524  var a = new ArrayList
   526  // All of the following print true:
   527  print("Type acts as target of instanceof: " + (a instanceof ArrayList))
   528  print("Class doesn't act as target of instanceof: " + !(a instanceof a.getClass()))
   529  print("Type is not same as instance's getClass(): " + (a.getClass() !== ArrayList))
   530  print("Type's `class` property is same as instance getClass(): " + (a.getClass() === ArrayList.class))
   531  print("Type is same as instance getClass()'s `static` property: " + (a.getClass().static === ArrayList))
   532 </code></pre> 
   533 <p>
   534 You can think of the type object as similar to the class names as used in Java source code: you use them as the
   535 arguments to the <code>new</code> and <code>instanceof</code> operators and as the namespace for the static fields
   536 and methods, but they are different than the runtime <code>Class</code> objects returned by <code>getClass()</code> calls.
   537 Syntactically and semantically, this separation produces code that is most similar to Java code, where a distinction
   538 between compile-time class expressions and runtime class objects also exists. (Also, Java can't have the equivalent of <code>static</code>
   539 property on a <code>Class</code> object since compile-time class expressions are never reified as objects).
   540 </p>
   541 <hr>
   542 <a name="jsimport" id="jsimport"></a>
   543 <h3>Importing Java Packages, Classes</h3>
   544 <p>The built-in functions <code>importPackage</code> (in compatibility script) and
   545 <code>importClass</code> can be used to import Java packages and
   546 classes.</p>
   547 <pre><code>
   549 // <a href="source/importpackageclass.js">importpackageclass.js</a>
   551 // load compatibility script
   552 load("nashorn:mozilla_compat.js");
   553 // Import Java packages and classes 
   554 // like import package.*; in Java
   555 <span class="functionref">importPackage</span>(java.awt);
   556 // like import java.awt.Frame in Java
   557 <span class="functionref">importClass</span>(java.awt.Frame);
   558 // Create Java Objects by "new ClassName"
   559 var frame = new java.awt.Frame("hello");
   560 // Call Java public methods from script
   561 frame.setVisible(true);
   562 // Access "JavaBean" properties like "fields"
   563 print(frame.title);
   564 </code>
   565 </pre>
   566 <p>The <span class="objectref">Packages</span> global variable can
   567 be used to access Java packages. Examples:
   568 <code>Packages.java.util.Vector</code>,
   569 <code>Packages.javax.swing.JFrame</code>. Please note that "java"
   570 is a shortcut for "Packages.java". There are equivalent shortcuts
   571 for javax, org, edu, com, net prefixes, so pratically all JDK
   572 platform classes can be accessed without the "Packages" prefix.</p>
   573 <p>Note that java.lang is not imported by default (unlike Java)
   574 because that would result in conflicts with JavaScript's built-in
   575 Object, Boolean, Math and so on.</p>
   576 <p><code>importPackage</code> and <code>importClass</code>
   577 functions "pollute" the global variable scope of JavaScript. To
   578 avoid that, you may use <span class="functionref">JavaImporter</span>.</p>
   579 <pre><code>
   581 // <a href="source/javaimporter.js">javaimporter.js</a>
   583 // create JavaImporter with specific packages and classes to import
   585 var SwingGui = new <span class="functionref">JavaImporter</span>(javax.swing,
   586                             javax.swing.event,
   587                             javax.swing.border,
   588                             java.awt.event);
   589 with (SwingGui) {
   590     // within this 'with' statement, we can access Swing and AWT
   591     // classes by unqualified (simple) names.
   593     var mybutton = new JButton("test");
   594     var myframe = new JFrame("test");
   595 }
   597 </code>
   598 </pre>
   599 <hr>
   600 <a name="jsarrays" id="jsarrays"></a>
   601 <h3>Creating, Converting and Using Java Arrays</h3>
   602 <p>
   603 Array element access or length access is the same as in Java.</p>
   604 <pre><code>
   605 // <a href="source/javaarray.js">javaarray.js</a>
   607 // create Java String array of 5 elements
   608 var StringArray = Java.type("java.lang.String[]");
   609 var a = new StringArray(5);
   611 // Accessing elements and length access is by usual Java syntax
   612 a[0] = "scripting is great!";
   613 print(a.length);
   614 print(a[0]);
   615 </code>
   616 </pre>
   617 <p>
   618 It is also possible to convert between JavaScript and Java arrays.
   619 Given a JavaScript array and a Java type, <code>Java.to</code> returns a Java array with the same initial contents, and with the specified array type. 
   620 </p>
   621 <pre><code>
   622  var anArray = [1, "13", false]
   623  var javaIntArray = Java.to(anArray, "int[]")
   624  print(javaIntArray[0]) // prints 1
   625  print(javaIntArray[1]) // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
   626  print(javaIntArray[2]) // prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
   627 </code></pre>
   628 <p>
   629 You can use either a string or a type object returned from <code>Java.type()</code> to specify the type of the array. 
   630 You can also omit the array type, in which case a <code>Object[]</code> will be created.
   631 </p>
   632 <p>
   633 Given a Java array or Collection, <code>Java.from</code> returns a JavaScript array with a shallow copy of its contents. Note that in most cases, you can use Java arrays and lists natively in Nashorn; in cases where for some reason you need to have an actual JavaScript native array (e.g. to work with the array comprehensions functions), you will want to use this method.
   634 </p>
   635 <pre><code>
   636 var File = Java.type("java.io.File");
   637 var listCurDir = new File(".").listFiles();
   638 var jsList = Java.from(listCurDir);
   639 print(jsList);
   640 </code></pre>
   641 <hr>
   642 <a name="jsimplement" id="jsimplement"></a>
   643 <h3>Implementing Java interfaces</h3>
   644 <p>A Java interface can be implemented in JavaScript by using a
   645 Java anonymous class-like syntax:</p>
   646 <pre><code>
   647 // <a href="source/runnable.js">runnable.js</a>
   649 var r  = new java.lang.Runnable() {
   650     run: function() {
   651         print("running...\n");
   652     }
   653 };
   655 // "r" can be passed to Java methods that expect java.lang.Runnable
   656 var th = new java.lang.Thread(r);
   657 th.start();
   658 th.join();
   659 </code>
   660 </pre>
   661 <p>When an interface with a single method is expected, you can pass
   662 a script function directly.(auto conversion)</p>
   663 <pre><code>
   664 // <a href="source/samfunc.js">samfunc.js</a>
   666 function func() {
   667      print("I am func!");
   668 }
   670 // pass script function for java.lang.Runnable argument
   671 var th = new java.lang.Thread(func);
   672 th.start();
   673 th.join();
   674 </code>
   675 </pre>
   676 <hr>
   677 <a name="jsextendabstract" id="jsextendabstract"></a>
   678 <h3>Extending Abstract Java Classes</h3>
   679 <p>
   680 If a Java class is abstract, you can instantiate an anonymous subclass of it using an argument list that is applicable to any of its public or protected constructors, but inserting a JavaScript object with functions properties that provide JavaScript implementations of the abstract methods. If method names are overloaded, the JavaScript function will provide implementation for all overloads. E.g.:
   681 </p>
   683 <pre><code>
   684  var TimerTask =  Java.type("java.util.TimerTask")
   685  var task = new TimerTask({ run: function() { print("Hello World!") } })
   686 </code></pre>
   688 Nashorn supports a syntactic extension where a "new" expression followed by an argument is identical to invoking the constructor and passing the argument to it, so you can write the above example also as:
   690 <pre><code>
   691  var task = new TimerTask {
   692      run: function() {
   693        print("Hello World!")
   694      }
   695  }
   696 </code></pre>
   698 which is very similar to Java anonymous inner class definition. On the other hand, if the type is an abstract type with a single abstract method (commonly referred to as a "SAM type") or all abstract methods it has share the same overloaded name), then instead of an object, you can just pass a function, so the above example can become even more simplified to:
   700 <pre><code>
   701  var task = new TimerTask(function() { print("Hello World!") })
   702 </code></pre>
   704 <p>
   705 Note that in every one of these cases if you are trying to instantiate an abstract class that has constructors that take some arguments, you can invoke those simply by specifying the arguments after the initial implementation object or function.
   706 </p>
   707 <p>
   708 The use of functions can be taken even further; if you are invoking a Java method that takes a SAM type, you can just pass in a function object, and Nashorn will know what you meant:
   709 </p>
   710 <code><pre>
   711  Java.type("java.util.Timer")
   712  timer.schedule(function() { print("Hello World!") })
   713 </code></pre>
   715 Here, <code>Timer.schedule()</code> expects a <code>TimerTask</code> as its argument, so Nashorn creates an instance of a TimerTask subclass and uses the passed function to implement its only abstract method, run(). In this usage though, you can't use non-default constructors; the type must be either an interface, or must have a protected or public no-arg constructor.
   717 <hr>
   718 <a name="jsextendconcrete" id="jsextendconcrete"></a>
   719 <h3>Extending Concrete Java Classes</h3>
   720 <p>
   721 To extend a concrete Java class, you have to use <code>Java.extend</code> function.
   722 <code>Java.extend</code> returns a type object for a subclass of the specified Java class (or implementation of the specified interface) that acts as a script-to-Java adapter for it.  
   723 </p>
   724 <pre><code>
   725 // <a href="source/javaextend.js">javaextend.js</a>
   727 var ArrayList = Java.type("java.util.ArrayList")
   728 var ArrayListExtender = Java.extend(ArrayList)
   729 var printSizeInvokedArrayList = new ArrayListExtender() {
   730     size: function() { print("size invoked!"); }
   731 }
   732 var printAddInvokedArrayList = new ArrayListExtender() {
   733     add: function(x, y) {
   734         if(typeof(y) === "undefined") {
   735             print("add(e) invoked!");
   736         } else {
   737             print("add(i, e) invoked!");
   738         }
   739     }
   740 };
   741 printSizeInvokedArrayList.size();
   742 printAddInvokedArrayList.add(33, 33);
   743 </code></pre>
   744 <p>
   745 The reason you must use <code>Java.extend()</code> with concrete classes is that with concrete classes, there can be a 
   746 syntactic ambiguity if you just invoke their constructor. Consider this example:
   747 </p>
   748 <pre><code>
   749 var t = new java.lang.Thread({ run: function() { print("Hello!") } })
   750 </code></pre>
   751 <p>
   752 If we allowed subclassing of concrete classes with constructor syntax, Nashorn couldn't tell if you're creating a new 
   753 <code>Thread</code> and passing it a <code>Runnable</code> at this point, or you are subclassing <code>Thread</code> and
   754 passing it a new implementation for its own <code>run()</code> method.
   755 </p>
   756 <hr>
   757 <a name="jsimplementmultiple" id="jsimplementmultiple"></a>
   758 <h3>Implementing Multiple Interfaces</h3>
   759 <p>
   760 <code>Java.extend</code> can in fact take a list of multiple types. At most one of the types can be a class, and the rest must
   761 be interfaces (the class doesn't have to be the first in the list). You will get back an object that extends the class and 
   762 implements all the interfaces. (Obviously, if you only specify interfaces and no class, the object will extend <code>java.lang.Object</code>).
   763 <hr>
   764 <a name="classBoundImplementations" id="classBoundImplementations"></a>
   765 <h3>Class-Bound Implementations</h3>
   766 <p>
   767 The methods shown so far for extending Java classes and implementing interfaces &ndash; passing an implementation JavaScript object 
   768 or function to a constructor, or using <code>Java.extend</code> with <code>new</code> &ndash; all produce classes that take an
   769 extra JavaScript object parameter in their constructors that specifies the implementation. The implementation is therefore always bound
   770 to the actual instance being created with <code>new</code>, and not to the whole class. This has some advantages, for example in the
   771 memory footprint of the runtime, as Nashorn can just create a single "universal adapter" for every combination of types being implemented.
   772 In reality, the below code shows that different instantiations of, say, <code>Runnable</code> have the same class regardless of them having
   773 different JavaScript implementation objects:
   774 </p>
   775 <pre><code>
   776 var Runnable = java.lang.Runnable;
   777 var r1 = new Runnable(function() { print("I'm runnable 1!") })
   778 var r2 = new Runnable(function() { print("I'm runnable 2!") })
   779 r1.run()
   780 r2.run()
   781 print("We share the same class: " + (r1.class === r2.class))
   782 </code></pre>
   783 <p>
   784 prints:
   785 </p>
   786 <pre><code>
   787 I'm runnable 1!
   788 I'm runnable 2!
   789 We share the same class: true
   790 </code></pre>
   791 <p>
   792 Sometimes, however, you'll want to extend a Java class or implement an interface with implementation bound to the class, not to
   793 its instances. Such a need arises, for example, when you need to pass the class for instantiation to an external API; prime example
   794 of this is the JavaFX framework where you need to pass an Application class to the FX API and let it instantiate it.
   795 </p>
   796 <p>
   797 Fortunately, there's a solution for that: <code>Java.extend()</code> &ndash; aside from being able to take any number of type parameters
   798 denoting a class to extend and interfaces to implement &ndash; can also take one last argument that has to be a JavaScript object
   799 that serves as the implementation for the methods. In this case, <code>Java.extend()</code> will create a class that has the same
   800 constructors as the original class had, as they don't need to take an an extra implementation object parameter. The example below
   801 shows how you can create class-bound implementations, and shows that in this case, the implementation classes for different invocations
   802 are indeed different:
   803 </p>
   804 <pre><code>
   805 var RunnableImpl1 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") })
   806 var RunnableImpl2 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 2!") })
   807 var r1 = new RunnableImpl1()
   808 var r2 = new RunnableImpl2()
   809 r1.run()
   810 r2.run()
   811 print("We share the same class: " + (r1.class === r2.class))
   812 </code></pre>
   813 <p>
   814 prints:
   815 </p>
   816 <pre><code>
   817 I'm runnable 1!
   818 I'm runnable 2!
   819 We share the same class: false
   820 </code></pre>
   821 <p>
   822 As you can see, the major difference here is that we moved the implementation object into the invocation of <code>Java.extend</code>
   823 from the constructor invocations &ndash; indeed the constructor invocations now don't even need to take an extra parameter! Since
   824 the implementations are bound to a class, the two classes obviously can't be the same, and we indeed see that the two runnables no
   825 longer share the same class &ndash; every invocation of <code>Java.extend()</code> with a class-specific implementation object triggers
   826 the creation of a new Java adapter class.
   827 </p>
   828 <p>
   829 Finally, the adapter classes with class-bound implementations can <i>still</i> take an additional constructor parameter to further
   830 override the behavior on a per-instance basis. Thus, you can even combine the two approaches: you can provide part of the implementation
   831 in a class-based JavaScript implementation object passed to <code>Java.extend</code>, and part in another object passed to the constructor.
   832 Whatever functions are provided by the constructor-passed object will override the functions in the class-bound object.
   833 </p>
   834 <pre><code>
   835 var RunnableImpl = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") })
   836 var r1 = new RunnableImpl()
   837 var r2 = new RunnableImpl(function() { print("I'm runnable 2!") })
   838 r1.run()
   839 r2.run()
   840 print("We share the same class: " + (r1.class === r2.class))
   841 </code></pre>
   842 <p>
   843 prints:
   844 </p>
   845 <pre><code>
   846 I'm runnable 1!
   847 I'm runnable 2!
   848 We share the same class: true
   849 </code></pre>
   850 <hr>
   851 <a name="jsoverload" id="jsoverload"></a>
   852 <h3>Overload Resolution</h3>
   853 <p>Java methods can be overloaded by argument types. In Java,
   854 overload resolution occurs at compile time (performed by javac).
   855 When calling Java methods from Nashorn, the appropriate method will be
   856 selected based on the argument types at invocation time. You do not need
   857 to do anything special &ndash; the correct Java method overload variant 
   858 is selected based automatically. You still have the option of explicitly
   859 specifying a particular overload variant. Reasons for this include 
   860 either running into a genuine ambiguity with actual argument types, or 
   861 rarely reasons of performance &ndash; if you specify the actual overload
   862 then the engine doesn't have to perform resolution during invocation.
   863 Individual overloads of a Java methods are exposed as special properties
   864 with the name of the method followed with its signature in parentheses. 
   865 You can invoke them like this:</p>
   866 <pre><code>
   867 // <a href="source/overload.js">overload.js</a>
   869 var out = java.lang.System.out;
   871 // select a particular print function 
   872 out["println(Object)"]("hello");
   873 </code>
   874 </pre>
   875 <p>
   876 Note that you normally don't even have to use qualified class names in 
   877 the signatures as long as the unqualified name of the type is sufficient
   878 for uniquely identifying the signature. In practice this means that only
   879 in the extremely unlikely case that two overloads only differ in 
   880 parameter types that have identical unqualified names but come from 
   881 different packages would you need to use the fully qualified name of the
   882 class.
   883 </p>
   884 <hr>
   885 <a name="dataTypeMapping" id="dataTypeMapping"></a>
   886 <h3>Mapping of Data Types Between Java and JavaScript</h3>
   887 <p>
   888 We have previously shown some of the data type mappings between Java and JavaScript.
   889 We saw that arrays need to be explicitly converted. We have also shown that JavaScript functions
   890 are automatically converted to SAM types when passed as parameters to Java methods. Most other
   891 conversions work as you would expect.
   892 </p>
   893 <p>
   894 Every JavaScript object is also a <code>java.util.Map</code> so APIs receiving maps will receive them directly.
   895 </p>
   896 <p>
   897 When numbers are passed to a Java API, they will be converted to the expected target numeric type, either boxed or
   898 primitive, but if the target type is less specific, say <code>Number</code> or <code>Object</code>, you can only
   899 count on them being a <code>Number</code>, and have to test specifically for whether it's a boxed <code>Double</code>,
   900 <code>Integer</code>, <code>Long</code>, etc. &ndash; it can be any of these due to internal optimizations. Also, you 
   901 can pass any JavaScript value to a Java API expecting either a boxed or primitive number; the JavaScript specification's
   902 <code>ToNumber</code> conversion algorithm will be applied to the value.
   903 </p>
   904 <p>
   905 In a similar vein, if a Java method expects a <code>String</code> or a <code>Boolean</code>, the values will be
   906 converted using all conversions allowed by the JavaScript specification's <code>ToString</code> and <code>ToBoolean</code>
   907 conversions.
   908 </p>
   909 <p>
   910 Finally, a word of caution about strings. Due to internal performance optimizations of string operations, JavaScript strings are
   911 not always necessarily of type <code>java.lang.String</code>, but they will always be of type <code>java.lang.CharSequence</code>.
   912 If you pass them to a Java method that expects a <code>java.lang.String</code> parameter, then you will naturally receive a Java
   913 String, but if the signature of your method is more generic, i.e. it receives a <code>java.lang.Object</code> parameter, you can 
   914 end up with an object of private engine implementation class that implements <code>CharSequence</code> but is not a Java String.
   915 </p>
   916 <hr>
   917 <a name="engineimpl" id="engineimpl"></a>
   918 <h2>Implementing Your Own Script Engine</h2>
   919 <p>We will not cover implementation of JSR-223 compliant script
   920 engines in detail. Minimally, you need to implement the
   921 <code>javax.script.ScriptEngine</code> and
   922 <code>javax.script.ScriptEngineFactory</code> interfaces. The
   923 abstract class <code>javax.script.AbstractScriptEngine</code>
   924 provides useful defaults for a few methods of the
   925 <code>ScriptEngine</code> interface.</p>
   926 <p>Before starting to implement a JSR-223 engine, you may want to
   927 check <a href="http://java.net/projects/Scripting">http://java.net/projects/Scripting</a>
   928 project. This project maintains JSR-223 implementations for many
   929 popular open source scripting languages.</p>
   930 <hr>
   931 <a name="refs" id="refs"></a>
   932 <h2>References</h2>
   933 <ul>
   934 <li><a href="http://jcp.org/en/jsr/detail?id=223">JSR-223 Scripting
   935 for the Java Platform</a></li>
   936 <li><a href="http://java.net/projects/Scripting">http://java.net/projects/Scripting
   937 </a></li>
   938 </ul>
   942 <div class="hr"><hr></div>
   943 <table summary="layout" border="0" width="100%">
   944 <tbody><tr valign="TOP">
   945 <td width="30%"> <img src="Java%20Scripting%20Programmer%27s%20Guide_files/logo_oracle_footer.gif" alt="Oracle and/or its affiliates" border="0" height="29" width="100"><br>
   946 <font size="+1"> <i>Java Technology</i></font> </td>
   948 <td width="30%">
   949 <p><font size="-2">
   950 <a href="http://docs.oracle.com/javase/6/docs/legal/cpyr.html">Copyright ©</a> 2013, Oracle and/or its affiliates. All rights reserved.
   951 </font></p> 
   952 </td>
   953 <td width="30%">
   954 <p align="right"><font size="-2"><a href="http://download.oracle.com/javase/feedback.html">Contact Us</a></font></p><font size="-2">
   955 </font></td>
   956 </tr>
   957 </tbody></table> 
   958 <div class="hr"><hr></div>
   959 </div>
   961 <!-- Start SiteCatalyst code   -->
   962 <script language="JavaScript" src="Java%20Scripting%20Programmer%27s%20Guide_files/s_code_download.js"></script>
   963 <script language="JavaScript" src="Java%20Scripting%20Programmer%27s%20Guide_files/s_code.js"></script>
   965 <!-- ********** DO NOT ALTER ANYTHING BELOW THIS LINE ! *********** -->
   966 <!--  Below code will send the info to Omniture server -->
   967 <script language="javascript">var s_code=s.t();if(s_code)document.write(s_code)</script>
   969 <!-- End SiteCatalyst code -->
   973 </body></html>

mercurial