docs/JavaScriptingProgrammersGuide.html

Fri, 12 Apr 2013 15:22:56 -0700

author
katleman
date
Fri, 12 Apr 2013 15:22:56 -0700
changeset 182
e7e82c1e9aed
parent 136
c54e218333be
child 267
b37eb709ae27
permissions
-rw-r--r--

8012048: JDK8 b85 source with GPL header errors
Reviewed-by: iris, mduigou, jjg

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

mercurial