3 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
5 Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
7 Oracle and Java are registered trademarks of Oracle and/or its affiliates.
8 Other names may be trademarks of their respective owners.
10 The contents of this file are subject to the terms of either the GNU
11 General Public License Version 2 only ("GPL") or the Common
12 Development and Distribution License("CDDL") (collectively, the
13 "License"). You may not use this file except in compliance with the
14 License. You can obtain a copy of the License at
15 http://www.netbeans.org/cddl-gplv2.html
16 or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
17 specific language governing permissions and limitations under the
18 License. When distributing the software, include this License Header
19 Notice in each file and include the License file at
20 nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
21 particular file as subject to the "Classpath" exception as provided
22 by Oracle in the GPL Version 2 section of the License file that
23 accompanied this code. If applicable, add the following below the
24 License Header, with the fields enclosed by brackets [] replaced by
25 your own identifying information:
26 "Portions Copyrighted [year] [name of copyright owner]"
30 The Original Software is NetBeans. The Initial Developer of the Original
31 Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
33 If you wish your version of this file to be governed by only the CDDL
34 or only the GPL Version 2, indicate your decision by adding
35 "[Contributor] elects to include this software in this distribution
36 under the [CDDL or GPL Version 2] license." If you do not indicate a
37 single choice of license, a recipient has the option to distribute
38 your version of this file under either the CDDL, the GPL Version 2 or
39 to extend the choice of license to its licensees as provided above.
40 However, if you add GPL Version 2 code and therefore, elected the GPL
41 Version 2 license, then the option applies only if the new code is
42 made subject to such option by the copyright holder.
48 <div>Essential support for those who write <em>native</em> methods communicating directly with JavaScript.</div>
49 Mix your Java and JavaScript code seamlessly - perform calls from Java
50 to JavaScript and back with as much freedom as JavaScript gives you
51 and as much type safety you can get from Java. Execute your code
52 in a headless testing environment or in a
53 <a href="http://wiki.apidesign.org/wiki/FXBrwsr">JavaFX WebView</a>.
54 When done, deploy to <a href="http://bck2brwsr.apidesign.org">real browsers</a>.
56 <h3>Simple Meaning of World</h3>
57 The whole support is build around @<a href="JavaScriptBody.html">JavaScriptBody</a>
58 annotation. Use it to create parametrised JavaScript snippet easily
61 {@code @}{@link net.java.html.js.JavaScriptBody}(args = {"x", "y"}, body = "return x + y;")
62 <b>private static native int</b> meaning(<b>int</b> x, <b>int</b> y);
64 The above defines method <em>meaning</em> which sums two JavaScript
65 objects together (being invoked inside of a JavaScript interpreter).
66 The <em>meaning</em> method now becomes a properly typed Java
67 surface to your JavaScript code which can be directly
68 called from the rest of your Java code:
70 <b>public static void</b> main(String... args) {
71 <b>assert</b> 42 == meaning(40, 2) : <em>"Meaning of World should be 42!"</em>;
74 <em>Real code tip:</em> real classes using this technique are
76 <a target="top" href="http://hg.netbeans.org/html4j/file/release-0.7/boot/src/test/java/org/netbeans/html/boot/impl/JsMethods.java">JsMethods</a> and
77 <a target="top" href="http://hg.netbeans.org/html4j/file/release-0.7/json-tck/src/main/java/net/java/html/js/tests/Bodies.java">Bodies</a>.
79 <em>Editing hint:</em> one can see the list of arguments of the
80 <em>meaning</em> is now duplicated - it is once specified in Java,
81 and once inside of the {@link net.java.html.js.JavaScriptBody}
82 array of <code>args</code>. This is necessary to keep the names of
83 arguments accessible during runtime. However don't despair - there
84 is a code completion for the value of <code>args</code> attribute!
85 Just type the Java signature first and then press Ctrl+Space and the
86 right parameter names will be inserted for you.
88 <a name="#library"><h3>Including JavaScript Libraries</h3></a>
90 Large amount of JavaScript code is easier to be delivered in whole
91 files rather than {@link net.java.html.js.JavaScriptBody small code snippets} -
92 that is also possible thanks to {@link net.java.html.js.JavaScriptResource}
93 annotation. Imagine file <code>mul.js</code> with following content:
95 <b>function</b> <em>mul</em>(x, y) { <b>return</b> x * y; }
97 Place the file next to your class and reference it with
98 {@link net.java.html.js.JavaScriptResource the annotation}:
100 {@code @}{@link net.java.html.js.JavaScriptResource}("mul.js") <b>class</b> Mul {
102 {@code @}{@link net.java.html.js.JavaScriptBody}(args = { "x", "y" }, body = "return <b>mul</b>(x, y);")
103 <b>public static native int</b> multiply(int x, int y);
105 <b>public static void</b> main(String... args) {
106 <b>assert</b> 42 == multiply(6, 7) : <em>"Meaning of World should be 42!"</em>;
110 All the Java methods annotated {@link net.java.html.js.JavaScriptBody}
111 can now reference everything that is in the <code>mul.js</code> file -
112 e.g. the body of the <code>multiply</code> method can reference the
113 function <code>mul</code> and use it.
115 <em>Real code tip:</em>
116 <a target="top" href="http://hg.netbeans.org/html4j/file/release-0.7/ko4j/src/main/java/org/netbeans/html/ko4j/Knockout.java">this</a>
118 the <a target="top" href="http://knockoutjs.com">knockout.js</a> library
119 is included in its <em>ko4j</em> library.
121 <h3>Callback to Java</h3>
123 Often JavaScript code needs to call back into the Java classes.
124 For example when a button in a browser is pressed and your code would
125 like to invoke a runnable to handle such situation:
127 {@code @}{@link net.java.html.js.JavaScriptBody}(args = {"id", "r"}, {@link net.java.html.js.JavaScriptBody#javacall() javacall} = true, body = "\n" +
128 " document.getElementById(id).onclick = function() {\n" +
129 " r.<em>{@code @}java.lang.Runnable::run()</em>();\n" +
132 <b>public static native void</b> onClick(String id, Runnable r);
134 As can be seen, there is a special syntax (starting with <b>@</b>) to
135 properly identify the right Java method to call on a Java object passed
136 into the JavaScript interpreter. The syntax starts with a fully
137 qualified name of the class, followed by <b>::</b> and name of the
138 method including signature of its parameters. In case of runnable,
139 this is just <em>()</em> as the method has no parameters, but the
140 signature can be more complicated. For example in case of following method
141 <pre><b>static int</b> compare(<b>int</b> i1, String s1, <b>int</b> i2, String s2)
143 it would be <em>(ILjava/lang/String;ILjava/lang/String;)</em> (btw. the
144 return type is not included in the signature). The actual parameters
145 then follows. The JavaScript call to such compare method would then
147 <pre>{@code @}the.pkg.Clazz::compare(ILjava/lang/String;ILjava/lang/String;)(1, 'One', 2, 'Two');
149 This syntax gives enough flexibility, helps to properly select one
150 of overloaded methods and follows the tradition of previous attempts to
151 provide JavaScript to Java calling conventions.
153 Please note that to turn the special Java callback syntax on, one
154 needs to set the {@link net.java.html.js.JavaScriptBody#javacall()}
155 attribute to <b>true</b>. The callback syntax consists of
158 <pre>[instance.]@classname::methodname(signature)(arguments)</pre>
160 <li><b>instance</b> - must be present when calling an
161 instance method and must be absent when calling a
163 <li><b>classname</b> - fully qualified name of the class in
164 which the method is declared
166 <li><b>signature</b> - internal JVM method signature
168 <a target="top" href="http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/types.html#wp16432">JNI type Signatures</a>)
169 without the trailing signature of the method return type</li>
170 <li><b>arguments</b> - the actual values to pass to the called Java method
174 <p>Here is the <a target="top" href="http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/types.html#wp16432">JNI type signatures table</a>
175 one can use to convert
176 Java parameters to JVM's internal <em>letter</em> based
179 <table border=1 width='100%'>
181 <td><b>Type Signature</b></td>
182 <td><b>Java Type</b></td>
217 <td>L fully-qualified-class ;</td>
218 <td>fully-qualified-class</td>
227 <em>Editing hint:</em> The callback syntax may seem complicated at
228 first, however there is an associated <b>annotation processor</b>
229 that checks the syntax and verifies the referenced class and
230 method with the requested signature exist. If it does not, the
231 <em>compilation fails offering correct alternatives</em>.
232 Thus don't despair seeing the syntax, make sure you get the
233 fully qualified name of the callback class right.
234 You'll get warning and help
235 if there is a typo in the specified signature then -
236 during compilation of your code.
238 <h3>Overloaded Methods</h3>
240 Specifying the actual callback signature is important in case of
241 overloaded methods. Imagine a class:
243 <b>package</b> x.y.z;
244 <b>class</b> Handler {
248 <b>int</b> pulse(<b>int</b> howMuch) {
249 <b>return</b> howMuch;
251 <b>int</b> pulse(<b>long</b> evenMore) {
252 <b>return</b> (<b>int</b>) (5 + evenMore);
255 you then need to choose in {@link net.java.html.js.JavaScriptBody}
256 the appropriate method to call:
258 {@code @}{@link net.java.html.js.JavaScriptBody}(args = { "h" }, javacall = <b>true</b>, <em>// you want to process the @ syntax</em>
259 body = "<b>return</b> h.@x.y.z.Handler::pulse()() +" + <em>// the call to no argument method</em>
260 "h.@x.y.z.Handler::pulse(I)(10) +" + <em>// the call to method with integer argument</em>
261 "h.@x.y.z.Handler::pulse(J)(10);" <em>// the call to method with long argument</em>
263 <b>static native void</b> threePulsesFromJavaScript(Handler h);
265 <b>assert</b> 26 == threePulsesFromJavaScript(<b>new</b> Handler());
269 To avoid ambiguity, the specification of the correct signature is
270 required on every call. However, to simplify the development,
271 there is an annotation processor to
272 verify the signature really refers to an existing method.
275 <h3>Arrays by Copy</h3>
277 It is possible to exchange arrays between Java and JavaScript. Some
278 implementations can pass arrays by reference, however in some systems
279 this is hard to achieve. To choose the least common denominator,
280 the TCK for behavior of {@link net.java.html.js.JavaScriptBody} requires
281 the arrays to be always transfered by a copy. As such following code:
283 {@code @}{@link net.java.html.js.JavaScriptBody}(args = {"arr"}, body = "arr[0] = null;")
284 <b>private static native void</b> uselessModify(String[] arr);
285 <b>public static void</b> main(String... args) {
286 String[] hello = { "Hello", "World!" };
288 System.out.println(arr[0] + " " + arr[1]);
291 will still print <em>Hello World!</em> in spite the JavaScript code
292 sets the 0-th array element to <code>null</code>. Because the array
293 is passed as a copy, such assignment has no effect on the Java array.
295 In case one needs to modify an array in a JavaScript and use its
296 values in Java, one has to return the array back as a return value:
298 {@code @}{@link net.java.html.js.JavaScriptBody}(args = {"arr"}, body = "arr[0] = 'Ahoy'; return arr;")
299 <b>private static native</b> Object[] usefulModify(String[] arr);
300 <b>public static void</b> main(String... args) {
301 String[] hello = { "Hello", "World!" };
302 Object[] ret = usefulModify(arr);
303 System.out.println(ret[0] + " " + ret[1]);
306 now the program prints <em>Ahoy World!</em> as the modified array
307 is returned back and converted (by a copy) into a Java <code>Object[]</code>
308 (but of course the <code>ret != hello</code>). Usually the copy based
309 passing of arrays works OK. It is however good to keep it in mind to
310 avoid unwanted surprises.
312 <h3>Instance Reference to JavaScript Object</h3>
314 When writing wrappers around existing JavaScript libraries, it may be
315 useful to hold a reference to some JavaScript object from a Java
316 instance and use it later.
318 <b>class</b> WrapperAroundJsObj {
319 <b>private final</b> Object js;
321 WrapperAroundJsObj() {
325 <b>public void</b> set(int v) {
329 {@link net.java.html.js.JavaScriptBody @JavaScriptBody}(args = {}, body = "return { value : 0 };")
330 <b>private static native</b> Object initValue();
332 {@link net.java.html.js.JavaScriptBody @JavaScriptBody}(
333 args = { "js", "v" }, body = "js.value = v;", wait4js = false
335 <b>private static native void</b> setValue(Object js, int v);
338 The type of the Java reference is {@link java.lang.Object}.
339 From a Java perspective it has no additional methods or fields, however
340 its properties can be manipulated from JavaScript. Send the object back
341 to JavaScript by passing it as a parameter of some method
342 (like the <code>setValue</code> one) and perform necessary JavaScript
343 calls or changes on it.
345 <h3>Post Process Classes</h3>
346 <a name="post-process"></a>
348 Classes with {@link net.java.html.js.JavaScriptBody} annotated methods need to
349 be post processed before they can be used - e.g. their <code>native</code>
350 body needs to be generated to call into JavaScript (btw. the code is performed
351 via {@link org.netbeans.html.boot.spi.Fn}). There are three ways
352 such post processing can happen.
354 <b>Compile time</b> processing - this is the preferred method that
355 most of the <a href="http://html.java.net">Html Java APIs</a> are using.
356 Just include following plugin configuration into your <code>pom.xml</code>
357 and your classes will be ready for execution as soon as <em>process-classes</em>
358 <a href="http://wiki.apidesign.org/wiki/Maven">Maven</a> phase is over:
361 <groupId>org.netbeans.html</groupId>
362 <artifactId>html4j-maven-plugin</artifactId>
363 <version>${net.java.html.version}</version>
366 <id>js-classes</id>
368 <goal>process-js-annotations</goal>
374 This plugin works in orchestration with
375 <a href="http://wiki.apidesign.org/wiki/AnnotationProcessor">annotation
376 processor</a> associated with {@link net.java.html.js.JavaScriptBody}
377 and {@link net.java.html.js.JavaScriptResource} - the processor creates
378 list of files that need post-processing. The
379 <a href="http://wiki.apidesign.org/wiki/Maven">Maven</a>
380 plugin reads these files, processes classes mentioned in them and
381 modifies (and deletes at the end) the files to not include classes
384 <b>Instrumentation Agent</b> - one can do processing in runtime
385 using JDK's {@link java.lang.instrument.ClassFileTransformer instrumentation}
386 abilities. The JAR artifact of <code>org.netbeans.html:net.java.html.boot</code>
387 contains an <code>Agent-Class</code> and <code>Premain-Class</code>
388 definitions in its manifest. As such one can launch the Java virtual
391 $ java -javaagent:jarpath=net.java.html.boot-x.y.jar
393 and the runtime will take care of processing bytecode of classes
394 not yet processed in compile time before they are loaded into the
397 <b>Special classloading</b> - when booting your application with
398 {@link net.java.html.boot.BrowserBuilder} there is a 3rd option of
399 processing the classes. If there are some classes not yet processed
400 (remember the files listing them generated by the
401 <a href="http://wiki.apidesign.org/wiki/AnnotationProcessor">annotation
402 processor</a>), the {@link net.java.html.boot.BrowserBuilder#showAndWait() launching method}
403 will create a special classloader to that does the processing before
404 loading the bytecode into the virtual machine.
406 The options are rich, however to avoid any troubles (as the runtime
407 processing needs to also include <code>asm-5.0.jar</code> on application
408 classpath), it is recommended
409 to perform the <b>compile time</b> processing.
411 <h3>Getting Started</h3>
413 There are many ways to start developing
414 <a href="http://html.java.net">Html for Java</a> application.
415 However to be sure one chooses the most recent setup, it is recommended
416 to switch to good old command line and use a
417 <a href="http://wiki.apidesign.org/wiki/Knockout4Java">Maven archetype</a>
418 associated with every version of this project. Just type:
420 $ mvn archetype:generate \
421 -DarchetypeGroupId=org.apidesign.html \
422 -DarchetypeArtifactId=knockout4j-archetype \
423 -DarchetypeVersion=x.y
425 Answer few questions (for example choose myfirstbrwsrpage as artifactId) and then you can:
427 $ cd myfirstbrwsrpage
428 $ mvn process-classes exec:java
430 In a few seconds (or minutes if
431 <a href="http://wiki.apidesign.org/wiki/Maven">Maven</a>
432 decides to download the whole Internet of dependencies) you should
433 see a sample Hello World application. It is basically composed from one
434 Java and one HTML file:
436 $ ls src/main/java/**/DataModel.java
437 $ ls src/main/webapp/pages/index.html
439 Play with them, modify them and enjoy
440 <a href="http://html.java.net">Html for Java</a>!
443 <h3>Mixed Java/JavaScript Debugging</h3>
447 The following video shows how easy it is to use
448 NetBeans 8.0, JDK8 to debug an application that intermixes Java
449 and JavaScript calls. One can put breakpoints into Java part,
450 as well as JavaScript source code, inspect Java as well
451 as JavaScript variables and switch between these two
452 languages without any restrictions.
455 <iframe width="420" height="315"
456 src="http://www.youtube.com/embed/EvaTejQDRwA"
457 frameborder="0" allowfullscreen>