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 {@link net.java.html.js.JavaScriptResource}("mul.js") <b>class</b> Mul {
102 {@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 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 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>.
157 <em>Editing hint:</em> there is an associated annotation processor
158 that checks the syntax and verifies the referenced class and
159 method of the right signature exist. If they do not, the
160 compilation fails. Thus don't despair seeing the syntax, you'll get early
161 warnings when there is a typo.
163 <h3>Arrays by Copy</h3>
165 It is possible to exchange arrays between Java and JavaScript. Some
166 implementations can pass arrays by reference, however in some systems
167 this is hard to achieve. To choose the least common denominator,
168 the TCK for behavior of {@link net.java.html.js.JavaScriptBody} requires
169 the arrays to be always transfered by a copy. As such following code:
171 {@code @}{@link net.java.html.js.JavaScriptBody}(args = {"arr"}, body = "arr[0] = null;")
172 <b>private static native void</b> uselessModify(String[] arr);
173 <b>public static void</b> main(String... args) {
174 String[] hello = { "Hello", "World!" };
176 System.out.println(arr[0] + " " + arr[1]);
179 will still print <em>Hello World!</em> in spite the JavaScript code
180 sets the 0-th array element to <code>null</code>. Because the array
181 is passed as a copy, such assignment has no effect on the Java array.
183 In case one needs to modify an array in a JavaScript and use its
184 values in Java, one has to return the array back as a return value:
186 {@code @}{@link net.java.html.js.JavaScriptBody}(args = {"arr"}, body = "arr[0] = 'Ahoy'; return arr;")
187 <b>private static native</b> Object[] usefulModify(String[] arr);
188 <b>public static void</b> main(String... args) {
189 String[] hello = { "Hello", "World!" };
190 Object[] ret = usefulModify(arr);
191 System.out.println(ret[0] + " " + ret[1]);
194 now the program prints <em>Ahoy World!</em> as the modified array
195 is returned back and converted (by a copy) into a Java <code>Object[]</code>
196 (but of course the <code>ret != hello</code>). Usually the copy based
197 passing of arrays works OK. It is however good to keep it in mind to
198 avoid unwanted surprises.
200 <h3>Post Process Classes</h3>
202 Classes with {@link net.java.html.js.JavaScriptBody} annotated methods need to
203 be post processed before they can be used - e.g. their <code>native</code>
204 body needs to be generated to call into JavaScript (btw. the code is performed
205 via {@link org.apidesign.html.boot.spi.Fn}). There are three ways
206 such post processing can happen.
208 <b>Compile time</b> processing - this is the preferred method that
209 most of the <a href="http://html.java.net">Html Java APIs</a> are using.
210 Just include following plugin configuration into your <code>pom.xml</code>
211 and your classes will be ready for execution as soon as <em>process-classes</em>
212 <a href="http://wiki.apidesign.org/wiki/Maven">Maven</a> phase is over:
215 <groupId>org.netbeans.html</groupId>
216 <artifactId>html4j-maven-plugin</artifactId>
217 <version>${net.java.html.version}</version>
220 <id>js-classes</id>
222 <goal>process-js-annotations</goal>
228 This plugin works in orchestration with
229 <a href="http://wiki.apidesign.org/wiki/AnnotationProcessor">annotation
230 processor</a> associated with {@link net.java.html.js.JavaScriptBody}
231 and {@link net.java.html.js.JavaScriptResource} - the processor creates
232 list of files that need post-processing. The
233 <a href="http://wiki.apidesign.org/wiki/Maven">Maven</a>
234 plugin reads these files, processes classes mentioned in them and
235 modifies (and deletes at the end) the files to not include classes
238 <b>Instrumentation Agent</b> - one can do processing in runtime
239 using JDK's {@link java.lang.instrument.ClassFileTransformer instrumentation}
240 abilities. The JAR artifact of <code>org.netbeans.html:net.java.html.boot</code>
241 contains an <code>Agent-Class</code> and <code>Premain-Class</code>
242 definitions in its manifest. As such one can launch the Java virtual
245 $ java -javaagent:jarpath=net.java.html.boot-x.y.jar
247 and the runtime will take care of processing bytecode of classes
248 not yet processed in compile time before they are loaded into the
251 <b>Special classloading</b> - when booting your application with
252 {@link net.java.html.boot.BrowserBuilder} there is a 3rd option of
253 processing the classes. If there are some classes not yet processed
254 (remember the files listing them generated by the
255 <a href="http://wiki.apidesign.org/wiki/AnnotationProcessor">annotation
256 processor</a>), the {@link net.java.html.boot.BrowserBuilder#showAndWait() launching method}
257 will create a special classloader to that does the processing before
258 loading the bytecode into the virtual machine.
260 The options are rich, however to avoid any troubles, it is recommended
261 to perform the <b>compile time</b> processing.
263 <h3>Getting Started</h3>
265 There are many ways to start developing
266 <a href="http://html.java.net">Html for Java</a> application.
267 However to be sure one chooses the most recent setup, it is recommended
268 to switch to good old command line and use a
269 <a href="http://wiki.apidesign.org/wiki/Knockout4Java">Maven archetype</a>
270 associated with every version of this project. Just type:
272 $ mvn archetype:generate \
273 -DarchetypeGroupId=org.apidesign.html \
274 -DarchetypeArtifactId=knockout4j-archetype \
275 -DarchetypeVersion=x.y
277 Answer few questions (for example choose myfirstbrwsrpage as artifactId) and then you can:
279 $ cd myfirstbrwsrpage
280 $ mvn process-classes exec:java
282 In a few seconds (or minutes if
283 <a href="http://wiki.apidesign.org/wiki/Maven">Maven</a>
284 decides to download the whole Internet of dependencies) you should
285 see a sample Hello World application. It is basically composed from one
286 Java and one HTML file:
288 $ ls src/main/java/**/DataModel.java
289 $ ls src/main/webapp/pages/index.html
291 Play with them, modify them and enjoy
292 <a href="http://html.java.net">Html for Java</a>!