docs/JavaScriptingProgrammersGuide.html

Tue, 12 Mar 2013 18:12:42 +0530

author
sundar
date
Tue, 12 Mar 2013 18:12:42 +0530
changeset 136
c54e218333be
parent 68
5c2ed5d89524
child 182
e7e82c1e9aed
permissions
-rw-r--r--

8009757: Package access clean up and refactoring
Reviewed-by: jlaskey, lagergren, attila

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

mercurial