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