JavaScriptingProgrammersGuide.html revision 181:e7e82c1e9aed
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. 4 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. 10 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). 16 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. 20 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> 29 30<!-- ============ --> 31<!-- MAIN CONTENT --> 32<!-- ============ --> 33<table summary="layout" border="0" width="100%"> 34<tbody><tr> 35<td> 36 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&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> 38 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 45For?</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 51File</a></span></li> 52<li><span><a href="#scriptvars">Script Variables</a></span></li> 53<li><span><a href="#invoke">Invoking Script Functions and 54Methods</a></span></li> 55<li><span><a href="#interfaces">Implementing Java Interfaces by 56Scripts</a></span></li> 57<li><span><a href="#scopes">Multiple Scopes for 58Scripts</a></span></li> 59</ul> 60</li> 61<li><span><a href="#jsengine">JavaScript Script 62Engine</a></span></li> 63<li><span><a href="#jstojava">JavaScript to Java 64Communication</a></span> 65<ul> 66<li><span><a href="#jsjavaclass">Accessing Java 67Classes</a></span></li> 68<li><span><a href="#jsimport">Importing Java Packages, 69Classes</a></span></li> 70<li><span><a href="#jsarrays">Creating, Converting and Using Java 71Arrays</a></span></li> 72<li><span><a href="#jsimplement">Implementing Java 73Interfaces</a></span></li> 74<li><span><a href="#jsextend">Extending Java classes 75</a></span></li> 76<li><span><a href="#jsoverload">Overload Resolution</a></span></li> 77</ul> 78</li> 79<li><span><a href="#engineimpl">Implementing Your Own Script 80Engine</a></span></li> 81<li><span><a href="#refs">References</a></span></li> 82</ul> 83<span><a name="who" id="who"></a></span> 84<h2><span>Who is the Java Scripting API For?</span></h2> 85<span>Some useful characteristics of scripting languages 86are:</span> 87<ul> 88<li><span><b>Convenience</b>: Most scripting languages are 89dynamically typed. You can usually create new variables without 90declaring the variable type, and you can reuse variables to store 91objects of different types. Also, scripting languages tend to 92perform many type conversions automatically, for example, 93converting the number 10 to the text "10" as necessary.</span></li> 94<li><span><b>Developing rapid prototypes</b>: You can avoid the 95edit-compile-run cycle and just use edit-run!</span></li> 96<li><span><b>Application extension/customization</b>: You can 97"externalize" parts of your application - like configuration 98scripts, business logic/rules and math expressions for financial 99applications.</span></li> 100<li><span><b>"Command line" shells for applications</b> -for 101debugging, runtime/deploy time configuration etc. Most applications 102have a web-based GUI configuaration tool these days. But 103sysadmins/deployers frequently prefer command line tools. Instead 104of inventing ad-hoc scripting language for that purpose, a 105"standard" scripting language can be used.</span></li> 106</ul> 107<p><span>The Java<font size="-1"><sup>TM</sup></font> Scripting API 108is a scripting language indepedent framework for using script 109engines from Java code. With the Java Scripting API, it is possible 110to write customizable/extendable applications in the Java language 111and leave the customization scripting language choice to the end 112user. The Java application developer need not choose the extension 113language during development. If you write your application with 114JSR-223 API, then your users can use any JSR-223 compliant 115scripting language.</span></p> 116<hr> 117<span><a name="package" id="package"></a></span> 118<h2><span>Scripting Package</span></h2> 119<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> 120package. This is a relatively small, simple API. The starting point 121of the scripting API is the <code>ScriptEngineManager</code> class. 122A ScriptEngineManager object can discover script engines through 123the jar file service discovery mechanism. It can also instantiate 124ScriptEngine objects that interpret scripts written in a specific 125scripting language. The simplest way to use the scripting API is as 126follows:</span></p> 127<ol> 128<li><span>Create a <code>ScriptEngineManager</code> 129object.</span></li> 130<li><span>Get a <code>ScriptEngine</code> object from the 131manager.</span></li> 132<li><span>Evaluate script using the <code>ScriptEngine</code>'s 133<code>eval</code> methods.</span></li> 134</ol> 135<p><span>Now, it is time to look at some sample code. While it is 136not mandatory, it may be useful to know a bit of JavaScript to read 137these examples.</span></p> 138<hr> 139<span><a name="examples" id="examples"></a></span> 140<h2><span>Examples</span></h2> 141<span><a name="helloworld" id="helloworld"></a></span> 142<h3><span>"Hello, World"</span></h3> 143<p><span>From the <code>ScriptEngineManager</code> instance, we 144request a JavaScript engine instance using 145<code>getEngineByName</code> method. On the script engine, the 146<code>eval</code> method is called to execute a given String as 147JavaScript code! For brevity, in this as well as in subsequent 148examples, we have not shown exception handling. There are checked 149and runtime exceptions thrown from <code>javax.script</code> API. 150Needless to say, you have to handle the exceptions 151appropriately.</span></p> 152<pre> 153<span><code> 154// <a href="source/EvalScript.java">EvalScript.java</a> 155 156import javax.script.*; 157public class EvalScript { 158 public static void main(String[] args) throws Exception { 159 // create a script engine manager 160 <span class="classref">ScriptEngineManager</span> factory = new ScriptEngineManager(); 161 // create a JavaScript engine 162 <span class="classref">ScriptEngine</span> engine = factory.<span class="methodref">getEngineByName</span>("nashorn"); 163 // evaluate JavaScript code from String 164 engine.<span class="methodref">eval</span>("print('Hello, World')"); 165 } 166} 167</code></span> 168</pre> 169<hr> 170<a name="evalfile" id="evalfile"></a> 171<h3>Evaluating a Script File</h3> 172<p>In this example, we call the <code>eval</code> method that 173accepts <code>java.io.Reader</code> for the input source. The 174script read by the given reader is executed. This way it is 175possible to execute scripts from files, URLs and resources by 176wrapping the relevant input stream objects as readers.</p> 177<pre> 178<code> 179// <a href="source/EvalFile.java">EvalFile.java</a> 180 181import javax.script.*; 182 183public class EvalFile { 184 public static void main(String[] args) throws Exception { 185 // create a script engine manager 186 <span class="classref">ScriptEngineManager</span> factory = new ScriptEngineManager(); 187 // create JavaScript engine 188 <span class="classref">ScriptEngine</span> engine = factory.<span class="methodref">getEngineByName</span>("nashorn"); 189 // evaluate JavaScript code from given file - specified by first argument 190 engine.<span class="methodref">eval</span>(new java.io.FileReader(args[0])); 191 } 192} 193</code> 194</pre> 195Let us assume that we have the file named <a href="source/test.js">test.js</a> with the 196following text: 197<pre><code> 198print("This is hello from test.js"); 199</code> 200</pre> 201We can run the above Java as 202<pre><code> 203java EvalFile test.js 204</code> 205</pre> 206<hr> 207<a name="scriptvars" id="scriptvars"></a> 208<h3>Script Variables</h3> 209<p>When you embed script engines and scripts with your Java 210application, you may want to expose your application objects as 211global variables to scripts. This example demonstrates how you can 212expose your application objects as global variables to a script. We 213create a <code>java.io.File</code> in the application and expose 214the same as a global variable with the name "file". The script can 215access the variable - for example, it can call public methods on 216it. Note that the syntax to access Java objects, methods and fields 217is dependent on the scripting language. JavaScript supports the 218most "natural" Java-like syntax.</p> 219<pre><code> 220// <a href="source/ScriptVars.java">ScriptVars.java</a> 221 222import javax.script.*; 223import java.io.*; 224 225public class ScriptVars { 226 public static void main(String[] args) throws Exception { 227 ScriptEngineManager manager = new ScriptEngineManager(); 228 ScriptEngine engine = manager.getEngineByName("nashorn"); 229 230 File f = new File("test.txt"); 231 // expose File object as variable to script 232 engine.<span class="methodref">put</span>("file", f); 233 234 // evaluate a script string. The script accesses "file" 235 // variable and calls method on it 236 engine.eval("print(file.getAbsolutePath())"); 237 } 238} 239 240</code> 241</pre> 242<hr> 243<a name="invoke" id="invoke"></a> 244<h3>Invoking Script Functions and Methods</h3> 245<p>Sometimes you may want to call a specific scripting function 246repeatedly - for example, your application menu functionality might 247be implemented by a script. In your menu's action event handler you 248may want to call a specific script function. The following example 249demonstrates invoking a specific script function from Java 250code.</p> 251<pre><code> 252// <a href="source/InvokeScriptFunction.java">InvokeScriptFunction.java</a> 253 254import javax.script.*; 255 256public class InvokeScriptFunction { 257 public static void main(String[] args) throws Exception { 258 ScriptEngineManager manager = new ScriptEngineManager(); 259 ScriptEngine engine = manager.getEngineByName("nashorn"); 260 261 // JavaScript code in a String 262 String script = "function hello(name) { print('Hello, ' + name); }"; 263 // evaluate script 264 engine.eval(script); 265 266 // <code>javax.script.Invocable</code> is an optional interface. 267 // Check whether your script engine implements it or not! 268 // Note that the JavaScript engine implements Invocable interface. 269 <span class="classref">Invocable</span> inv = (Invocable) engine; 270 271 // invoke the global function named "hello" 272 inv.<span class="methodref">invokeFunction</span>("hello", "Scripting!!" ); 273 } 274} 275 276</code> 277</pre> 278<p>If your scripting language is object based (like JavaScript) or 279object-oriented, then you can invoke a script method on a script 280object.</p> 281<pre><code> 282// <a href="source/InvokeScriptMethod.java">InvokeScriptMethod.java</a> 283 284import javax.script.*; 285 286public class InvokeScriptMethod { 287 public static void main(String[] args) throws Exception { 288 ScriptEngineManager manager = new ScriptEngineManager(); 289 ScriptEngine engine = manager.getEngineByName("nashorn"); 290 291 // JavaScript code in a String. This code defines a script object 'obj' 292 // with one method called 'hello'. 293 String script = "var obj = new Object(); obj.hello = function(name) { print('Hello, ' + name); }"; 294 // evaluate script 295 engine.eval(script); 296 297 // <code>javax.script.Invocable</code> is an optional interface. 298 // Check whether your script engine implements or not! 299 // Note that the JavaScript engine implements Invocable interface. 300 <span class="classref">Invocable</span> inv = (Invocable) engine; 301 302 // get script object on which we want to call the method 303 Object obj = engine.<span class="methodref">get</span>("obj"); 304 305 // invoke the method named "hello" on the script object "obj" 306 inv.<span class="methodref">invokeMethod</span>(obj, "hello", "Script Method !!" ); 307 } 308} 309 310</code> 311</pre> 312<hr> 313<a name="interfaces" id="interfaces"></a> 314<h3>Implementing Java Interfaces by Scripts</h3> 315<p>Instead of calling specific script functions from Java, 316sometimes it is convenient to implement a Java interface by script 317functions or methods. Also, by using interfaces we can avoid having 318to use the <code>javax.script</code> API in many places. We can get 319an interface implementor object and pass it to various Java APIs. 320The following example demonstrates implementing the 321<code>java.lang.Runnable</code> interface with a script.</p> 322<pre><code> 323// <a href="source/RunnableImpl.java">RunnableImpl.java</a> 324 325import javax.script.*; 326 327public class RunnableImpl { 328 public static void main(String[] args) throws Exception { 329 ScriptEngineManager manager = new ScriptEngineManager(); 330 ScriptEngine engine = manager.getEngineByName("nashorn"); 331 332 // JavaScript code in a String 333 String script = "function run() { print('run called'); }"; 334 335 // evaluate script 336 engine.eval(script); 337 338 <span class="classref">Invocable</span> inv = (Invocable) engine; 339 340 // get Runnable interface object from engine. This interface methods 341 // are implemented by script functions with the matching name. 342 Runnable r = inv.<span class="methodref">getInterface</span>(Runnable.class); 343 344 // start a new thread that runs the script implemented 345 // runnable interface 346 Thread th = new Thread(r); 347 th.start(); 348 th.join(); 349 } 350} 351</code> 352</pre> 353<p>If your scripting language is object-based or object-oriented, 354it is possible to implement a Java interface by script methods on 355script objects. This avoids having to call script global functions 356for interface methods. The script object can store the "state" 357associated with the interface implementor.</p> 358<pre><code> 359// <a href="source/RunnableImplObject.java">RunnableImplObject.java</a> 360 361import javax.script.*; 362 363public class RunnableImplObject { 364 public static void main(String[] args) throws Exception { 365 ScriptEngineManager manager = new ScriptEngineManager(); 366 ScriptEngine engine = manager.getEngineByName("nashorn"); 367 368 // JavaScript code in a String 369 String script = "var obj = new Object(); obj.run = function() { print('run method called'); }"; 370 371 // evaluate script 372 engine.eval(script); 373 374 // get script object on which we want to implement the interface with 375 Object obj = engine.<span class="methodref">get</span>("obj"); 376 377 <span class="classref">Invocable</span> inv = (Invocable) engine; 378 379 // get Runnable interface object from engine. This interface methods 380 // are implemented by script methods of object 'obj' 381 Runnable r = inv.<span class="methodref">getInterface</span>(obj, Runnable.class); 382 383 // start a new thread that runs the script implemented 384 // runnable interface 385 Thread th = new Thread(r); 386 th.start(); 387 th.join(); 388 } 389} 390</code> 391</pre> 392<hr> 393<a name="scopes" id="scopes"></a> 394<h3>Multiple Scopes for Scripts</h3> 395<p>In the <a href="#scriptvars">script variables</a> example, we 396saw how to expose application objects as script global variables. 397It is possible to expose multiple global "scopes" for scripts. A 398single scope is an instance of <code>javax.script.Bindings</code>. 399This interface is derived from <code>java.util.Map<String, 400Object></code>. A scope a set of name-value pairs where name is 401any non-empty, non-null String. 402<code>javax.script.ScriptContext</code> interface supports multiple 403scopes with associated Bindings for each 404scope. By default, every script engine has a default script 405context. The default script context has atleast one scope called 406"ENGINE_SCOPE". Various scopes supported by a script context are 407available through <code>getScopes</code> method.</p> 408<pre><code> 409// <a href="source/MultiScopes.java">MultiScopes.java</a> 410 411import javax.script.*; 412 413public class MultiScopes { 414 public static void main(String[] args) throws Exception { 415 ScriptEngineManager manager = new ScriptEngineManager(); 416 ScriptEngine engine = manager.getEngineByName("nashorn"); 417 418 engine.put("x", "hello"); 419 // print global variable "x" 420 engine.eval("print(x);"); 421 // the above line prints "hello" 422 423 // Now, pass a different script context 424 <span class="classref">ScriptContext</span> newContext = new <span class="classref">SimpleScriptContext</span>(); 425 newContext.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE); 426 <span class="classref">Bindings</span> engineScope = newContext.<span class="methodref">getBindings</span>(ScriptContext.ENGINE_SCOPE); 427 428 // add new variable "x" to the new engineScope 429 engineScope.<span class="methodref">put</span>("x", "world"); 430 431 // execute the same script - but this time pass a different script context 432 engine.eval("print(x);", newContext); 433 // the above line prints "world" 434 } 435} 436 437</code> 438</pre> 439<hr> 440<a name="jsengine" id="jsengine"></a> 441<h2>JavaScript Script Engine</h2> 442<p>Oracle's implementation of JDK 8 is co-bundled with the Nashorn ECMAScript 443script engine. 444<hr> 445<a name="jstojava" id="jstojava"></a> 446<h2>JavaScript to Java Communication</h2> 447<p>For the most part, accessing Java classes, objects and methods 448is straightforward. In particular field and method access from 449JavaScript is the same as it is from Java. We highlight important 450aspects of JavaScript Java access here. 451The following examples are JavaScript snippets accessing Java. This 452section requires knowledge of JavaScript. This section can be 453skipped if you are planning to use some other JSR-223 scripting 454language rather than JavaScript.</p> 455<hr> 456<a name="jsjavaclass" id=jsjavalass"></a> 457<h3>Accessing Java Classes</h3> 458<pre> 459<code> 460// <a href="source/javatypes.js">javatypes.js</a> 461 462 var arrayListType = Java.type("java.util.ArrayList") 463 var intType = Java.type("int") 464 var stringArrayType = Java.type("java.lang.String[]") 465 var int2DArrayType = Java.type("int[][]") 466</code> 467</pre> 468 469Note that the name of the type is always a string for a fully qualified name. You can use any of these types to create new instances, e.g.: 470 471<pre><code> 472 var anArrayList = new Java.type("java.util.ArrayList") 473</code></pre> 474 475or 476 477<pre><code> 478 var ArrayList = Java.type("java.util.ArrayList") 479 var anArrayList = new ArrayList 480 var anArrayListWithSize = new ArrayList(16) 481</code></pre> 482 483In the special case of inner classes, you need to use the JVM fully qualified name, meaning using $ sign in the class name: 484 485<pre><code> 486 var ftype = Java.type("java.awt.geom.Arc2D$Float") 487</code></pre> 488 489 490However, once you retrieved the outer class, you can access the inner class as a property on it: 491 492<pre><code> 493 var arctype = Java.type("java.awt.geom.Arc2D") 494 var ftype = arctype.Float 495</code></pre> 496<p> 497You 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. 498</p> 499<hr> 500<a name="jsimport" id="jsimport"></a> 501<h3>Importing Java Packages, Classes</h3> 502<p>The built-in functions <code>importPackage</code> (in compatibility script) and 503<code>importClass</code> can be used to import Java packages and 504classes.</p> 505<pre><code> 506 507// <a href="source/importpackageclass.js">importpackageclass.js</a> 508 509// load compatibility script 510load("nashorn:mozilla_compat.js"); 511// Import Java packages and classes 512// like import package.*; in Java 513<span class="functionref">importPackage</span>(java.awt); 514// like import java.awt.Frame in Java 515<span class="functionref">importClass</span>(java.awt.Frame); 516// Create Java Objects by "new ClassName" 517var frame = new java.awt.Frame("hello"); 518// Call Java public methods from script 519frame.setVisible(true); 520// Access "JavaBean" properties like "fields" 521print(frame.title); 522</code> 523</pre> 524<p>The <span class="objectref">Packages</span> global variable can 525be used to access Java packages. Examples: 526<code>Packages.java.util.Vector</code>, 527<code>Packages.javax.swing.JFrame</code>. Please note that "java" 528is a shortcut for "Packages.java". There are equivalent shortcuts 529for javax, org, edu, com, net prefixes, so pratically all JDK 530platform classes can be accessed without the "Packages" prefix.</p> 531<p>Note that java.lang is not imported by default (unlike Java) 532because that would result in conflicts with JavaScript's built-in 533Object, Boolean, Math and so on.</p> 534<p><code>importPackage</code> and <code>importClass</code> 535functions "pollute" the global variable scope of JavaScript. To 536avoid that, you may use <span class="functionref">JavaImporter</span>.</p> 537<pre><code> 538 539// <a href="source/javaimporter.js">javaimporter.js</a> 540 541// create JavaImporter with specific packages and classes to import 542 543var SwingGui = new <span class="functionref">JavaImporter</span>(javax.swing, 544 javax.swing.event, 545 javax.swing.border, 546 java.awt.event); 547with (SwingGui) { 548 // within this 'with' statement, we can access Swing and AWT 549 // classes by unqualified (simple) names. 550 551 var mybutton = new JButton("test"); 552 var myframe = new JFrame("test"); 553} 554 555</code> 556</pre> 557<hr> 558<a name="jsarrays" id="jsarrays"></a> 559<h3>Creating, Converting and Using Java Arrays</h3> 560<p> 561Array element access or length access is 562the same as in Java. Also, a script array can be used when a Java 563method expects a Java array (auto conversion). So in most cases we 564don't have to create Java arrays explicitly.</p> 565<pre><code> 566// <a href="source/javaarray.js">javaarray.js</a> 567 568// create Java String array of 5 elements 569var StringArray = Java.type("java.lang.String[]"); 570var a = new StringArray(5); 571 572// Accessing elements and length access is by usual Java syntax 573a[0] = "scripting is great!"; 574print(a.length); 575print(a[0]); 576</code> 577</pre> 578<p> 579It is also possible to convert between JavaScript and Java arrays. 580Given 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. 581</p> 582<pre><code> 583 var anArray = [1, "13", false] 584 var javaIntArray = Java.toJavaArray(anArray, "int") 585 print(javaIntArray[0]) // prints 1 586 print(javaIntArray[1]) // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion 587 print(javaIntArray[2]) // prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion 588</code></pre> 589<p> 590Given 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.i 591</p> 592<pre><code> 593var File = Java.type("java.io.File"); 594var listCurDir = new File(".").listFiles(); 595var jsList = Java.toJavaScriptArray(listCurDir); 596print(jsList); 597</code></pre> 598<hr> 599<a name="jsimplement" id="jsimplement"></a> 600<h3>Implementing Java Interfaces</h3> 601<p>A Java interface can be implemented in JavaScript by using a 602Java anonymous class-like syntax:</p> 603<pre><code> 604// <a href="source/runnable.js">runnable.js</a> 605 606var r = new java.lang.Runnable() { 607 run: function() { 608 print("running...\n"); 609 } 610}; 611 612// "r" can be passed to Java methods that expect java.lang.Runnable 613var th = new java.lang.Thread(r); 614th.start(); 615th.join(); 616</code> 617</pre> 618<p>When an interface with a single method is expected, you can pass 619a script function directly.(auto conversion)</p> 620<pre><code> 621// <a href="source/samfunc.js">samfunc.js</a> 622 623function func() { 624 print("I am func!"); 625} 626 627// pass script function for java.lang.Runnable argument 628var th = new java.lang.Thread(func); 629th.start(); 630th.join(); 631</code> 632</pre> 633<hr> 634<a name="jsextend" id="jsextend"></a> 635<h3>Extending Java classes</h3> 636<p> 637If 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.: 638</p> 639 640<pre><code> 641 var TimerTask = Java.type("java.util.TimerTask") 642 var task = new TimerTask({ run: function() { print("Hello World!") } }) 643</code></pre> 644 645Nashorn 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: 646 647<pre><code> 648 var task = new TimerTask { 649 run: function() { 650 print("Hello World!") 651 } 652 } 653</code></pre> 654 655which 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: 656 657<pre><code> 658 var task = new TimerTask(function() { print("Hello World!") }) 659</code></pre> 660 661<p> 662Note 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. 663</p> 664<p> 665The 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: 666</p> 667<code><pre> 668 Java.type("java.util.Timer") 669 timer.schedule(function() { print("Hello World!") }) 670</code></pre> 671 672Here, <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. 673 674<p> 675To extend a concrete Java class, you have to use <code>Java.extend</code> function. 676<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. 677</p> 678<pre><code> 679// <a href="source/javaextend.js">javaextend.js</a> 680 681var ArrayList = Java.type("java.util.ArrayList") 682var ArrayListExtender = Java.extend(ArrayList) 683var printSizeInvokedArrayList = new ArrayListExtender() { 684 size: function() { print("size invoked!"); } 685} 686var printAddInvokedArrayList = new ArrayListExtender() { 687 add: function(x, y) { 688 if(typeof(y) === "undefined") { 689 print("add(e) invoked!"); 690 } else { 691 print("add(i, e) invoked!"); 692 } 693 } 694}; 695printSizeInvokedArrayList.size(); 696printAddInvokedArrayList.add(33, 33); 697</code></pre> 698<hr> 699<a name="jsoverload" id="jsoverload"></a> 700<h3>Overload Resolution</h3> 701<p>Java methods can be overloaded by argument types. In Java, 702overload resolution occurs at compile time (performed by javac). 703When calling Java methods from a script, the script 704interpreter/compiler needs to select the appropriate method. With 705the JavaScript engine, you do not need to do anything special - the 706correct Java method overload variant is selected based on the 707argument types. But, sometimes you may want (or have) to explicitly 708select a particular overload variant.</p> 709<pre><code> 710// <a href="source/overload.js">overload.js</a> 711 712var out = java.lang.System.out; 713 714// select a particular print function 715out["println(java.lang.Object)"]("hello"); 716</code> 717</pre> 718<hr> 719<a name="engineimpl" id="engineimpl"></a> 720<h2>Implementing Your Own Script Engine</h2> 721<p>We will not cover implementation of JSR-223 compliant script 722engines in detail. Minimally, you need to implement the 723<code>javax.script.ScriptEngine</code> and 724<code>javax.script.ScriptEngineFactory</code> interfaces. The 725abstract class <code>javax.script.AbstractScriptEngine</code> 726provides useful defaults for a few methods of the 727<code>ScriptEngine</code> interface.</p> 728<p>Before starting to implement a JSR-223 engine, you may want to 729check <a href="http://java.net/projects/Scripting">http://java.net/projects/Scripting</a> 730project. This project maintains JSR-223 implementations for many 731popular open source scripting languages.</p> 732<hr> 733<a name="refs" id="refs"></a> 734<h2>References</h2> 735<ul> 736<li><a href="http://jcp.org/en/jsr/detail?id=223">JSR-223 Scripting 737for the Java Platform</a></li> 738<li><a href="http://java.net/projects/Scripting">http://java.net/projects/Scripting 739</a></li> 740</ul> 741 742 743 744<div class="hr"><hr></div> 745<table summary="layout" border="0" width="100%"> 746<tbody><tr valign="TOP"> 747<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> 748<font size="+1"> <i>Java Technology</i></font> </td> 749 750<td width="30%"> 751<p><font size="-2"> 752<a href="http://docs.oracle.com/javase/6/docs/legal/cpyr.html">Copyright �</a> 2013, Oracle and/or its affiliates. All rights reserved. 753</font></p> 754</td> 755<td width="30%"> 756<p align="right"><font size="-2"><a href="http://download.oracle.com/javase/feedback.html">Contact Us</a></font></p><font size="-2"> 757</font></td> 758</tr> 759</tbody></table> 760<div class="hr"><hr></div> 761</div> 762 763<!-- Start SiteCatalyst code --> 764<script language="JavaScript" src="Java%20Scripting%20Programmer%27s%20Guide_files/s_code_download.js"></script> 765<script language="JavaScript" src="Java%20Scripting%20Programmer%27s%20Guide_files/s_code.js"></script> 766 767<!-- ********** DO NOT ALTER ANYTHING BELOW THIS LINE ! *********** --> 768<!-- Below code will send the info to Omniture server --> 769<script language="javascript">var s_code=s.t();if(s_code)document.write(s_code)</script> 770 771<!-- End SiteCatalyst code --> 772 773 774 775</body></html> 776