docs/JavaScriptingProgrammersGuide.html

Wed, 27 Apr 2016 01:36:41 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:36:41 +0800
changeset 0
b1a7da25b547
child 952
6d5471a497fb
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/nashorn/
changeset: 1034:4b9cc65dd24d
tag: jdk8u25-b17

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

mercurial