JavaScriptingProgrammersGuide.html revision 266:b37eb709ae27
1129198Scognet<!-- 2129198Scognet Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3129198Scognet DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4129198Scognet 5129198Scognet This code is free software; you can redistribute it and/or modify it 6129198Scognet under the terms of the GNU General Public License version 2 only, as 7129198Scognet published by the Free Software Foundation. Oracle designates this 8129198Scognet particular file as subject to the "Classpath" exception as provided 9129198Scognet by Oracle in the LICENSE file that accompanied this code. 10129198Scognet 11129198Scognet This code is distributed in the hope that it will be useful, but WITHOUT 12129198Scognet ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13129198Scognet FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14129198Scognet version 2 for more details (a copy is included in the LICENSE file that 15129198Scognet accompanied this code). 16129198Scognet 17129198Scognet You should have received a copy of the GNU General Public License version 18129198Scognet 2 along with this work; if not, write to the Free Software Foundation, 19129198Scognet Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20129198Scognet 21129198Scognet Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22129198Scognet or visit www.oracle.com if you need additional information or have any 23129198Scognet questions. 24129198Scognet--> 25129198Scognet<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 26129198Scognet<html class=" regenabled gecko radius jsenabled regloaded" xmlns="http://www.w3.org/1999/xhtml"><head> 27129198Scognet<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> 28129198Scognet<title>Java Scripting Programmer's Guide</title> 29129198Scognet 30129198Scognet<!-- ============ --> 31129198Scognet<!-- MAIN CONTENT --> 32129198Scognet<!-- ============ --> 33129198Scognet<table summary="layout" border="0" width="100%"> 34129198Scognet<tbody><tr> 35129198Scognet<td> 36129198Scognet 37129198Scognet<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&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&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 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&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> 38129198Scognet 39129198Scognet</td> 40129198Scognet</tr> 41129198Scognet</tbody></table> 42129198Scognet<!-- Body text begins here --> 43129198Scognet<ul> 44129198Scognet<li><span><a href="#who">Who is the Java Scripting API 45129198ScognetFor?</a></span></li> 46129198Scognet<li><span><a href="#package">Scripting Package</a></span></li> 47129198Scognet<li><span><a href="#examples">Examples</a></span> 48129198Scognet<ul> 49129198Scognet<li><span><a href="#helloworld">"Hello, World"</a></span></li> 50129198Scognet<li><span><a href="#evalfile">Evaluating a Script 51129198ScognetFile</a></span></li> 52129198Scognet<li><span><a href="#scriptvars">Script Variables</a></span></li> 53129198Scognet<li><span><a href="#invoke">Invoking Script Functions and 54129198ScognetMethods</a></span></li> 55129198Scognet<li><span><a href="#interfaces">Implementing Java Interfaces by 56129198ScognetScripts</a></span></li> 57129198Scognet<li><span><a href="#scopes">Multiple Scopes for 58129198ScognetScripts</a></span></li> 59129198Scognet</ul> 60129198Scognet</li> 61129198Scognet<li><span><a href="#jsengine">JavaScript Script 62129198ScognetEngine</a></span></li> 63129198Scognet<li><span><a href="#jstojava">JavaScript to Java 64129198ScognetCommunication</a></span> 65129198Scognet<ul> 66129198Scognet<li><span><a href="#jsjavaclass">Accessing Java 67129198ScognetClasses</a></span></li> 68129198Scognet<li><span><a href="#jsimport">Importing Java Packages, 69129198ScognetClasses</a></span></li> 70129198Scognet<li><span><a href="#jsarrays">Creating, Converting and Using Java 71129198ScognetArrays</a></span></li> 72129198Scognet<li><span><a href="#jsimplement">Implementing Java 73129198ScognetInterfaces</a></span></li> 74129198Scognet<li><span><a href="#jsextendabstract">Extending Abstract Java Classes 75129198Scognet</a></span></li> 76129198Scognet<li><span><a href="#jsextendconcrete">Extending Concrete Java Classes 77129198Scognet</a></span></li> 78129198Scognet<li><span><a href="#jsimplementmultiple">Implementing Multiple Java Interfaces 79129198Scognet</a></span></li> 80129198Scognet<li><span><a href="#classBoundImplementations">Class-Bound Implementations 81129198Scognet</a></span></li> 82146794Smarcel<li><span><a href="#jsoverload">Overload Resolution</a></span></li> 83146794Smarcel<li><span><a href="#dataTypeMapping">Mapping of Data Types Between Java 84129198Scognetand JavaScript</a></span></li> 85129198Scognet 86129198Scognet 87129198Scognet 88129198Scognet</ul> 89146794Smarcel</li> 90129198Scognet<li><span><a href="#engineimpl">Implementing Your Own Script 91129198ScognetEngine</a></span></li> 92129198Scognet<li><span><a href="#refs">References</a></span></li> 93129198Scognet</ul> 94129198Scognet<span><a name="who" id="who"></a></span> 95129198Scognet<h2><span>Who is the Java Scripting API For?</span></h2> 96146790Smarcel<span>Some useful characteristics of scripting languages 97146790Smarcelare:</span> 98146790Smarcel<ul> 99129198Scognet<li><span><b>Convenience</b>: Most scripting languages are 100dynamically typed. You can usually create new variables without 101declaring the variable type, and you can reuse variables to store 102objects of different types. Also, scripting languages tend to 103perform many type conversions automatically, for example, 104converting the number 10 to the text "10" as necessary.</span></li> 105<li><span><b>Developing rapid prototypes</b>: You can avoid the 106edit-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 109scripts, business logic/rules and math expressions for financial 110applications.</span></li> 111<li><span><b>"Command line" shells for applications</b> -for 112debugging, runtime/deploy time configuration etc. Most applications 113have a web-based GUI configuaration tool these days. But 114sysadmins/deployers frequently prefer command line tools. Instead 115of 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 119is a scripting language indepedent framework for using script 120engines from Java code. With the Java Scripting API, it is possible 121to write customizable/extendable applications in the Java language 122and leave the customization scripting language choice to the end 123user. The Java application developer need not choose the extension 124language during development. If you write your application with 125JSR-223 API, then your users can use any JSR-223 compliant 126scripting 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> 131package. This is a relatively small, simple API. The starting point 132of the scripting API is the <code>ScriptEngineManager</code> class. 133A ScriptEngineManager object can discover script engines through 134the jar file service discovery mechanism. It can also instantiate 135ScriptEngine objects that interpret scripts written in a specific 136scripting language. The simplest way to use the scripting API is as 137follows:</span></p> 138<ol> 139<li><span>Create a <code>ScriptEngineManager</code> 140object.</span></li> 141<li><span>Get a <code>ScriptEngine</code> object from the 142manager.</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 147not mandatory, it may be useful to know a bit of JavaScript to read 148these 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 155request 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 158JavaScript code! For brevity, in this as well as in subsequent 159examples, we have not shown exception handling. There are checked 160and runtime exceptions thrown from <code>javax.script</code> API. 161Needless to say, you have to handle the exceptions 162appropriately.</span></p> 163<pre> 164<span><code> 165// <a href="source/EvalScript.java">EvalScript.java</a> 166 167import javax.script.*; 168public 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 184accepts <code>java.io.Reader</code> for the input source. The 185script read by the given reader is executed. This way it is 186possible to execute scripts from files, URLs and resources by 187wrapping the relevant input stream objects as readers.</p> 188<pre> 189<code> 190// <a href="source/EvalFile.java">EvalFile.java</a> 191 192import javax.script.*; 193 194public 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> 206Let us assume that we have the file named <a href="source/test.js">test.js</a> with the 207following text: 208<pre><code> 209print("This is hello from test.js"); 210</code> 211</pre> 212We can run the above Java as 213<pre><code> 214java 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 221application, you may want to expose your application objects as 222global variables to scripts. This example demonstrates how you can 223expose your application objects as global variables to a script. We 224create a <code>java.io.File</code> in the application and expose 225the same as a global variable with the name "file". The script can 226access the variable - for example, it can call public methods on 227it. Note that the syntax to access Java objects, methods and fields 228is dependent on the scripting language. JavaScript supports the 229most "natural" Java-like syntax.</p> 230<pre><code> 231// <a href="source/ScriptVars.java">ScriptVars.java</a> 232 233import javax.script.*; 234import java.io.*; 235 236public class ScriptVars { 237 public static void main(String[] args) throws Exception { 238 ScriptEngineManager manager = new ScriptEngineManager(); 239 ScriptEngine engine = manager.getEngineByName("nashorn"); 240 241 File f = new File("test.txt"); 242 // expose File object as variable to script 243 engine.<span class="methodref">put</span>("file", f); 244 245 // evaluate a script string. The script accesses "file" 246 // variable and calls method on it 247 engine.eval("print(file.getAbsolutePath())"); 248 } 249} 250 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 257repeatedly - for example, your application menu functionality might 258be implemented by a script. In your menu's action event handler you 259may want to call a specific script function. The following example 260demonstrates invoking a specific script function from Java 261code.</p> 262<pre><code> 263// <a href="source/InvokeScriptFunction.java">InvokeScriptFunction.java</a> 264 265import javax.script.*; 266 267public class InvokeScriptFunction { 268 public static void main(String[] args) throws Exception { 269 ScriptEngineManager manager = new ScriptEngineManager(); 270 ScriptEngine engine = manager.getEngineByName("nashorn"); 271 272 // JavaScript code in a String 273 String script = "function hello(name) { print('Hello, ' + name); }"; 274 // evaluate script 275 engine.eval(script); 276 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; 281 282 // invoke the global function named "hello" 283 inv.<span class="methodref">invokeFunction</span>("hello", "Scripting!!" ); 284 } 285} 286 287</code> 288</pre> 289<p>If your scripting language is object based (like JavaScript) or 290object-oriented, then you can invoke a script method on a script 291object.</p> 292<pre><code> 293// <a href="source/InvokeScriptMethod.java">InvokeScriptMethod.java</a> 294 295import javax.script.*; 296 297public class InvokeScriptMethod { 298 public static void main(String[] args) throws Exception { 299 ScriptEngineManager manager = new ScriptEngineManager(); 300 ScriptEngine engine = manager.getEngineByName("nashorn"); 301 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); 307 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; 312 313 // get script object on which we want to call the method 314 Object obj = engine.<span class="methodref">get</span>("obj"); 315 316 // invoke the method named "hello" on the script object "obj" 317 inv.<span class="methodref">invokeMethod</span>(obj, "hello", "Script Method !!" ); 318 } 319} 320 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, 327sometimes it is convenient to implement a Java interface by script 328functions or methods. Also, by using interfaces we can avoid having 329to use the <code>javax.script</code> API in many places. We can get 330an interface implementor object and pass it to various Java APIs. 331The 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> 335 336import javax.script.*; 337 338public class RunnableImpl { 339 public static void main(String[] args) throws Exception { 340 ScriptEngineManager manager = new ScriptEngineManager(); 341 ScriptEngine engine = manager.getEngineByName("nashorn"); 342 343 // JavaScript code in a String 344 String script = "function run() { print('run called'); }"; 345 346 // evaluate script 347 engine.eval(script); 348 349 <span class="classref">Invocable</span> inv = (Invocable) engine; 350 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); 354 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, 365it is possible to implement a Java interface by script methods on 366script objects. This avoids having to call script global functions 367for interface methods. The script object can store the "state" 368associated with the interface implementor.</p> 369<pre><code> 370// <a href="source/RunnableImplObject.java">RunnableImplObject.java</a> 371 372import javax.script.*; 373 374public class RunnableImplObject { 375 public static void main(String[] args) throws Exception { 376 ScriptEngineManager manager = new ScriptEngineManager(); 377 ScriptEngine engine = manager.getEngineByName("nashorn"); 378 379 // JavaScript code in a String 380 String script = "var obj = new Object(); obj.run = function() { print('run method called'); }"; 381 382 // evaluate script 383 engine.eval(script); 384 385 // get script object on which we want to implement the interface with 386 Object obj = engine.<span class="methodref">get</span>("obj"); 387 388 <span class="classref">Invocable</span> inv = (Invocable) engine; 389 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); 393 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 407saw how to expose application objects as script global variables. 408It is possible to expose multiple global "scopes" for scripts. A 409single scope is an instance of <code>javax.script.Bindings</code>. 410This interface is derived from <code>java.util.Map<String, 411Object></code>. A scope a set of name-value pairs where name is 412any non-empty, non-null String. 413<code>javax.script.ScriptContext</code> interface supports multiple 414scopes with associated Bindings for each 415scope. By default, every script engine has a default script 416context. The default script context has atleast one scope called 417"ENGINE_SCOPE". Various scopes supported by a script context are 418available through <code>getScopes</code> method.</p> 419<pre><code> 420// <a href="source/MultiScopes.java">MultiScopes.java</a> 421 422import javax.script.*; 423 424public class MultiScopes { 425 public static void main(String[] args) throws Exception { 426 ScriptEngineManager manager = new ScriptEngineManager(); 427 ScriptEngine engine = manager.getEngineByName("nashorn"); 428 429 engine.put("x", "hello"); 430 // print global variable "x" 431 engine.eval("print(x);"); 432 // the above line prints "hello" 433 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); 438 439 // add new variable "x" to the new engineScope 440 engineScope.<span class="methodref">put</span>("x", "world"); 441 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} 447 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 454script 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 459is straightforward. In particular field and method access from 460JavaScript is the same as it is from Java. We highlight important 461aspects of JavaScript Java access here. 462The following examples are JavaScript snippets accessing Java. This 463section requires knowledge of JavaScript. This section can be 464skipped if you are planning to use some other JSR-223 scripting 465language 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> 472 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> 479 480Note 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.: 481 482<pre><code> 483 var anArrayList = new (Java.type("java.util.ArrayList")) 484</code></pre> 485 486or 487 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> 493 494In the special case of inner classes, you need to use the JVM fully qualified name, meaning using $ sign in the class name: 495 496<pre><code> 497 var ftype = Java.type("java.awt.geom.Arc2D$Float") 498</code></pre> 499 500 501However, once you retrieved the outer class, you can access the inner class as a property on it: 502 503<pre><code> 504 var arctype = Java.type("java.awt.geom.Arc2D") 505 var ftype = arctype.Float 506</code></pre> 507<p> 508You 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> 511In addition to creating new instances, the type objects returned from <code>Java.type</code> calls can also be used to access the 512static 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> 518Methods 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> 521A 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 525 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> 534You can think of the type object as similar to the class names as used in Java source code: you use them as the 535arguments to the <code>new</code> and <code>instanceof</code> operators and as the namespace for the static fields 536and methods, but they are different than the runtime <code>Class</code> objects returned by <code>getClass()</code> calls. 537Syntactically and semantically, this separation produces code that is most similar to Java code, where a distinction 538between compile-time class expressions and runtime class objects also exists. (Also, Java can't have the equivalent of <code>static</code> 539property 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 546classes.</p> 547<pre><code> 548 549// <a href="source/importpackageclass.js">importpackageclass.js</a> 550 551// load compatibility script 552load("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" 559var frame = new java.awt.Frame("hello"); 560// Call Java public methods from script 561frame.setVisible(true); 562// Access "JavaBean" properties like "fields" 563print(frame.title); 564</code> 565</pre> 566<p>The <span class="objectref">Packages</span> global variable can 567be used to access Java packages. Examples: 568<code>Packages.java.util.Vector</code>, 569<code>Packages.javax.swing.JFrame</code>. Please note that "java" 570is a shortcut for "Packages.java". There are equivalent shortcuts 571for javax, org, edu, com, net prefixes, so pratically all JDK 572platform classes can be accessed without the "Packages" prefix.</p> 573<p>Note that java.lang is not imported by default (unlike Java) 574because that would result in conflicts with JavaScript's built-in 575Object, Boolean, Math and so on.</p> 576<p><code>importPackage</code> and <code>importClass</code> 577functions "pollute" the global variable scope of JavaScript. To 578avoid that, you may use <span class="functionref">JavaImporter</span>.</p> 579<pre><code> 580 581// <a href="source/javaimporter.js">javaimporter.js</a> 582 583// create JavaImporter with specific packages and classes to import 584 585var SwingGui = new <span class="functionref">JavaImporter</span>(javax.swing, 586 javax.swing.event, 587 javax.swing.border, 588 java.awt.event); 589with (SwingGui) { 590 // within this 'with' statement, we can access Swing and AWT 591 // classes by unqualified (simple) names. 592 593 var mybutton = new JButton("test"); 594 var myframe = new JFrame("test"); 595} 596 597</code> 598</pre> 599<hr> 600<a name="jsarrays" id="jsarrays"></a> 601<h3>Creating, Converting and Using Java Arrays</h3> 602<p> 603Array element access or length access is the same as in Java.</p> 604<pre><code> 605// <a href="source/javaarray.js">javaarray.js</a> 606 607// create Java String array of 5 elements 608var StringArray = Java.type("java.lang.String[]"); 609var a = new StringArray(5); 610 611// Accessing elements and length access is by usual Java syntax 612a[0] = "scripting is great!"; 613print(a.length); 614print(a[0]); 615</code> 616</pre> 617<p> 618It is also possible to convert between JavaScript and Java arrays. 619Given a JavaScript array and a Java type, <code>Java.toJavaArray</code> returns a Java array with the same initial contents, and with the specified component type. 620</p> 621<pre><code> 622 var anArray = [1, "13", false] 623 var javaIntArray = Java.toJavaArray(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> 629You can use either a string or a type object returned from <code>Java.type()</code> to specify the component type of the array. 630You can also omit the array type, in which case a <code>Object[]</code> will be created. 631</p> 632<p> 633Given a Java array or Collection, <code>Java.toJavaScriptArray</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> 636var File = Java.type("java.io.File"); 637var listCurDir = new File(".").listFiles(); 638var jsList = Java.toJavaScriptArray(listCurDir); 639print(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 645Java anonymous class-like syntax:</p> 646<pre><code> 647// <a href="source/runnable.js">runnable.js</a> 648 649var r = new java.lang.Runnable() { 650 run: function() { 651 print("running...\n"); 652 } 653}; 654 655// "r" can be passed to Java methods that expect java.lang.Runnable 656var th = new java.lang.Thread(r); 657th.start(); 658th.join(); 659</code> 660</pre> 661<p>When an interface with a single method is expected, you can pass 662a script function directly.(auto conversion)</p> 663<pre><code> 664// <a href="source/samfunc.js">samfunc.js</a> 665 666function func() { 667 print("I am func!"); 668} 669 670// pass script function for java.lang.Runnable argument 671var th = new java.lang.Thread(func); 672th.start(); 673th.join(); 674</code> 675</pre> 676<hr> 677<a name="jsextendabstract" id="jsextendabstract"></a> 678<h3>Extending Abstract Java Classes</h3> 679<p> 680If 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> 682 683<pre><code> 684 var TimerTask = Java.type("java.util.TimerTask") 685 var task = new TimerTask({ run: function() { print("Hello World!") } }) 686</code></pre> 687 688Nashorn 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: 689 690<pre><code> 691 var task = new TimerTask { 692 run: function() { 693 print("Hello World!") 694 } 695 } 696</code></pre> 697 698which 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: 699 700<pre><code> 701 var task = new TimerTask(function() { print("Hello World!") }) 702</code></pre> 703 704<p> 705Note 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> 708The 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> 714 715Here, <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. 716 717<hr> 718<a name="jsextendconcrete" id="jsextendconcrete"></a> 719<h3>Extending Concrete Java Classes</h3> 720<p> 721To 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> 726 727var ArrayList = Java.type("java.util.ArrayList") 728var ArrayListExtender = Java.extend(ArrayList) 729var printSizeInvokedArrayList = new ArrayListExtender() { 730 size: function() { print("size invoked!"); } 731} 732var 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}; 741printSizeInvokedArrayList.size(); 742printAddInvokedArrayList.add(33, 33); 743</code></pre> 744<p> 745The reason you must use <code>Java.extend()</code> with concrete classes is that with concrete classes, there can be a 746syntactic ambiguity if you just invoke their constructor. Consider this example: 747</p> 748<pre><code> 749var t = new java.lang.Thread({ run: function() { print("Hello!") } }) 750</code></pre> 751<p> 752If 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 754passing 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 761be interfaces (the class doesn't have to be the first in the list). You will get back an object that extends the class and 762implements 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> 767The methods shown so far for extending Java classes and implementing interfaces – passing an implementation JavaScript object 768or function to a constructor, or using <code>Java.extend</code> with <code>new</code> – all produce classes that take an 769extra JavaScript object parameter in their constructors that specifies the implementation. The implementation is therefore always bound 770to the actual instance being created with <code>new</code>, and not to the whole class. This has some advantages, for example in the 771memory footprint of the runtime, as Nashorn can just create a single "universal adapter" for every combination of types being implemented. 772In reality, the below code shows that different instantiations of, say, <code>Runnable</code> have the same class regardless of them having 773different JavaScript implementation objects: 774</p> 775<pre><code> 776var Runnable = java.lang.Runnable; 777var r1 = new Runnable(function() { print("I'm runnable 1!") }) 778var r2 = new Runnable(function() { print("I'm runnable 2!") }) 779r1.run() 780r2.run() 781print("We share the same class: " + (r1.class === r2.class)) 782</code></pre> 783<p> 784prints: 785</p> 786<pre><code> 787I'm runnable 1! 788I'm runnable 2! 789We share the same class: true 790</code></pre> 791<p> 792Sometimes, however, you'll want to extend a Java class or implement an interface with implementation bound to the class, not to 793its instances. Such a need arises, for example, when you need to pass the class for instantiation to an external API; prime example 794of 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> 797Fortunately, there's a solution for that: <code>Java.extend()</code> – aside from being able to take any number of type parameters 798denoting a class to extend and interfaces to implement – can also take one last argument that has to be a JavaScript object 799that serves as the implementation for the methods. In this case, <code>Java.extend()</code> will create a class that has the same 800constructors as the original class had, as they don't need to take an an extra implementation object parameter. The example below 801shows how you can create class-bound implementations, and shows that in this case, the implementation classes for different invocations 802are indeed different: 803</p> 804<pre><code> 805var RunnableImpl1 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") }) 806var RunnableImpl2 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 2!") }) 807var r1 = new RunnableImpl1() 808var r2 = new RunnableImpl2() 809r1.run() 810r2.run() 811print("We share the same class: " + (r1.class === r2.class)) 812</code></pre> 813<p> 814prints: 815</p> 816<pre><code> 817I'm runnable 1! 818I'm runnable 2! 819We share the same class: false 820</code></pre> 821<p> 822As you can see, the major difference here is that we moved the implementation object into the invocation of <code>Java.extend</code> 823from the constructor invocations – indeed the constructor invocations now don't even need to take an extra parameter! Since 824the implementations are bound to a class, the two classes obviously can't be the same, and we indeed see that the two runnables no 825longer share the same class – every invocation of <code>Java.extend()</code> with a class-specific implementation object triggers 826the creation of a new Java adapter class. 827</p> 828<p> 829Finally, the adapter classes with class-bound implementations can <i>still</i> take an additional constructor parameter to further 830override the behavior on a per-instance basis. Thus, you can even combine the two approaches: you can provide part of the implementation 831in a class-based JavaScript implementation object passed to <code>Java.extend</code>, and part in another object passed to the constructor. 832Whatever functions are provided by the constructor-passed object will override the functions in the class-bound object. 833</p> 834<pre><code> 835var RunnableImpl = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") }) 836var r1 = new RunnableImpl() 837var r2 = new RunnableImpl(function() { print("I'm runnable 2!") }) 838r1.run() 839r2.run() 840print("We share the same class: " + (r1.class === r2.class)) 841</code></pre> 842<p> 843prints: 844</p> 845<pre><code> 846I'm runnable 1! 847I'm runnable 2! 848We 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, 854overload resolution occurs at compile time (performed by javac). 855When calling Java methods from Nashorn, the appropriate method will be 856selected based on the argument types at invocation time. You do not need 857to do anything special – the correct Java method overload variant 858is selected based automatically. You still have the option of explicitly 859specifying a particular overload variant. Reasons for this include 860either running into a genuine ambiguity with actual argument types, or 861rarely reasons of performance – if you specify the actual overload 862then the engine doesn't have to perform resolution during invocation. 863Individual overloads of a Java methods are exposed as special properties 864with the name of the method followed with its signature in parentheses. 865You can invoke them like this:</p> 866<pre><code> 867// <a href="source/overload.js">overload.js</a> 868 869var out = java.lang.System.out; 870 871// select a particular print function 872out["println(Object)"]("hello"); 873</code> 874</pre> 875<p> 876Note that you normally don't even have to use qualified class names in 877the signatures as long as the unqualified name of the type is sufficient 878for uniquely identifying the signature. In practice this means that only 879in the extremely unlikely case that two overloads only differ in 880parameter types that have identical unqualified names but come from 881different packages would you need to use the fully qualified name of the 882class. 883</p> 884<hr> 885<a name="dataTypeMapping" id="dataTypeMapping"></a> 886<h3>Mapping of Data Types Between Java and JavaScript</h3> 887<p> 888We have previously shown some of the data type mappings between Java and JavaScript. 889We saw that arrays need to be explicitly converted. We have also shown that JavaScript functions 890are automatically converted to SAM types when passed as parameters to Java methods. Most other 891conversions work as you would expect. 892</p> 893<p> 894Every JavaScript object is also a <code>java.util.Map</code> so APIs receiving maps will receive them directly. 895</p> 896<p> 897When numbers are passed to a Java API, they will be converted to the expected target numeric type, either boxed or 898primitive, but if the target type is less specific, say <code>Number</code> or <code>Object</code>, you can only 899count 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. – it can be any of these due to internal optimizations. Also, you 901can 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> 905In a similar vein, if a Java method expects a <code>String</code> or a <code>Boolean</code>, the values will be 906converted using all conversions allowed by the JavaScript specification's <code>ToString</code> and <code>ToBoolean</code> 907conversions. 908</p> 909<p> 910Finally, a word of caution about strings. Due to internal performance optimizations of string operations, JavaScript strings are 911not always necessarily of type <code>java.lang.String</code>, but they will always be of type <code>java.lang.CharSequence</code>. 912If you pass them to a Java method that expects a <code>java.lang.String</code> parameter, then you will naturally receive a Java 913String, but if the signature of your method is more generic, i.e. it receives a <code>java.lang.Object</code> parameter, you can 914end 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 920engines in detail. Minimally, you need to implement the 921<code>javax.script.ScriptEngine</code> and 922<code>javax.script.ScriptEngineFactory</code> interfaces. The 923abstract class <code>javax.script.AbstractScriptEngine</code> 924provides 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 927check <a href="http://java.net/projects/Scripting">http://java.net/projects/Scripting</a> 928project. This project maintains JSR-223 implementations for many 929popular 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 935for the Java Platform</a></li> 936<li><a href="http://java.net/projects/Scripting">http://java.net/projects/Scripting 937</a></li> 938</ul> 939 940 941 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> 947 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> 960 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> 964 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> 968 969<!-- End SiteCatalyst code --> 970 971 972 973</body></html> 974