boot/src/main/java/net/java/html/js/package.html
author Jaroslav Tulach <jtulach@netbeans.org>
Wed, 02 Dec 2015 08:44:31 +0100
changeset 1022 2f6f1d20fa7a
parent 937 64f89b8b7244
child 1083 b49546d64269
permissions -rw-r--r--
Improving documentation of the @JavaScriptBody's callback mechanism
     1 <!--
     2 
     3     DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     4 
     5     Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
     6 
     7     Oracle and Java are registered trademarks of Oracle and/or its affiliates.
     8     Other names may be trademarks of their respective owners.
     9 
    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]"
    27 
    28     Contributor(s):
    29 
    30     The Original Software is NetBeans. The Initial Developer of the Original
    31     Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
    32 
    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.
    43 
    44 -->
    45 <!DOCTYPE html>
    46 <html>
    47     <body>
    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>.
    55         
    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
    59         accessible from Java:
    60 <pre>
    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);
    63 </pre>
    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:
    69 <pre>        
    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>;
    72 }
    73 </pre>
    74         <em>Real code tip:</em> real classes using this technique are
    75         available online:
    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>.
    78         <p></p>
    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.
    87         
    88         <a name="#library"><h3>Including JavaScript Libraries</h3></a>
    89 
    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:
    94 <pre> 
    95 <b>function</b> <em>mul</em>(x, y) { <b>return</b> x * y; }
    96 </pre>
    97         Place the file next to your class and reference it with 
    98         {@link net.java.html.js.JavaScriptResource the annotation}:
    99 <pre>
   100 {@code @}{@link net.java.html.js.JavaScriptResource}("mul.js") <b>class</b> Mul {
   101 
   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);
   104 
   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>;
   107   }
   108 }
   109 </pre>
   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.
   114         <p></p>
   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> 
   117         is the way 
   118         the <a target="top" href="http://knockoutjs.com">knockout.js</a> library
   119         is included in its <em>ko4j</em> library.
   120         
   121         <h3>Callback to Java</h3>
   122         
   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:
   126 <pre> 
   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" + 
   130 "       };\n" + 
   131 "    ")
   132 <b>public static native void</b> onClick(String id, Runnable r);
   133 </pre>
   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)
   142 </pre>        
   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
   146         look like:
   147 <pre>{@code @}the.pkg.Clazz::compare(ILjava/lang/String;ILjava/lang/String;)(1, 'One', 2, 'Two');
   148 </pre>        
   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.
   152         <p></p>
   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
   156         following parts:
   157         <p></p>
   158         <pre>[instance.]@classname::methodname(signature)(arguments)</pre>
   159         <ul>
   160             <li><b>instance</b> - must be present when calling an 
   161                 instance method and must be absent when calling a 
   162                 static method</li>
   163             <li><b>classname</b> - fully qualified name of the class in 
   164                 which the method is declared 
   165             </li>
   166             <li><b>signature</b> - internal JVM method signature 
   167                 (as specified at 
   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
   171             </li>
   172         </ul>
   173 
   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 
   177             representation:</p>
   178         
   179         <table border=1 width='100%'>
   180             <tr>
   181                 <td><b>Type Signature</b></td>
   182                 <td><b>Java Type</b></td>
   183             </tr>
   184             <tr>
   185               <td>Z</td>
   186               <td>boolean</td>
   187             </tr>
   188             <tr>
   189               <td>B</td>
   190               <td>byte</td>
   191             </tr>
   192             <tr>
   193               <td>C</td>
   194               <td>char</td>
   195             </tr>
   196             <tr>
   197               <td>S</td>
   198               <td>short</td>
   199             </tr>
   200             <tr>
   201               <td>I</td>
   202               <td>int</td>
   203             </tr>
   204             <tr>
   205               <td>J</td>
   206               <td>long</td>
   207             </tr>
   208             <tr>
   209               <td>F</td>
   210               <td>float</td>
   211             </tr>
   212             <tr>
   213               <td>D</td>
   214               <td>double</td>
   215             </tr>
   216             <tr>
   217               <td>L fully-qualified-class ;</td>
   218               <td>fully-qualified-class</td>
   219             </tr>
   220             <tr>
   221               <td>[ type</td>
   222               <td>type[]</td>
   223             </tr>
   224           </tbody>
   225         </table>
   226         <p></p>
   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.
   237         
   238         <h3>Overloaded Methods</h3>
   239         
   240         Specifying the actual callback signature is important in case of 
   241         overloaded methods. Imagine a class:
   242 <pre>
   243 <b>package</b> x.y.z;
   244 <b>class</b> Handler {
   245   <b>int</b> pulse() {
   246     <b>return</b> 1;
   247   }
   248   <b>int</b> pulse(<b>int</b> howMuch) {
   249     <b>return</b> howMuch;
   250   }
   251   <b>int</b> pulse(<b>long</b> evenMore) {
   252     <b>return</b> (<b>int</b>) (5 + evenMore);
   253   }
   254 }</pre>        
   255         you then need to choose in {@link net.java.html.js.JavaScriptBody} 
   256         the appropriate method to call:
   257 <pre>
   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>
   262   )
   263   <b>static native void</b> threePulsesFromJavaScript(Handler h);
   264   <b>static</b> {
   265     <b>assert</b> 26 == threePulsesFromJavaScript(<b>new</b> Handler());
   266   }
   267 </pre>
   268         <p>
   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.
   273         </p>
   274         
   275         <h3>Arrays by Copy</h3>
   276         
   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:
   282         <pre>
   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!" };
   287   uselessModify(arr);
   288   System.out.println(arr[0] + " " + arr[1]);
   289 }            
   290 </pre>
   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.
   294         <p></p>
   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:
   297         <pre>        
   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]);
   304 }            
   305 </pre>
   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.
   311         
   312         <h3>Instance Reference to JavaScript Object</h3>
   313         
   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.
   317 <pre>
   318 <b>class</b> WrapperAroundJsObj {
   319   <b>private final</b> Object js;
   320 
   321   WrapperAroundJsObj() {
   322     js = initValue();
   323   }
   324 
   325   <b>public void</b> set(int v) {
   326     setValue(js, v);
   327   }
   328 
   329   {@link net.java.html.js.JavaScriptBody @JavaScriptBody}(args = {}, body = "return { value : 0 };")
   330   <b>private static native</b> Object initValue();
   331 
   332   {@link net.java.html.js.JavaScriptBody @JavaScriptBody}(
   333     args = { "js", "v" }, body = "js.value = v;", wait4js = false
   334   )
   335   <b>private static native void</b> setValue(Object js, int v);
   336 }            
   337 </pre>      
   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.
   344         
   345         <h3>Post Process Classes</h3>
   346         <a name="post-process"></a>
   347 
   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.
   353         <p></p>
   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:
   359 <pre> 
   360 &lt;plugin&gt;
   361     &lt;groupId&gt;org.netbeans.html&lt;/groupId&gt;
   362     &lt;artifactId&gt;html4j-maven-plugin&lt;/artifactId&gt;
   363     &lt;version&gt;${net.java.html.version}&lt;/version&gt;
   364     &lt;executions&gt;
   365         &lt;execution&gt;
   366             &lt;id&gt;js-classes&lt;/id&gt;
   367             &lt;goals&gt;
   368                 &lt;goal&gt;process-js-annotations&lt;/goal&gt;
   369             &lt;/goals&gt;
   370         &lt;/execution&gt;
   371     &lt;/executions&gt;
   372 &lt;/plugin&gt;
   373 </pre>
   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
   382         already processed.
   383         <p></p>
   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
   389         machine with
   390 <pre>
   391 $ java -javaagent:jarpath=net.java.html.boot-x.y.jar
   392 </pre>        
   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
   395         virtual machine. 
   396         <p></p>
   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.
   405         <p></p>
   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.
   410         
   411         <h3>Getting Started</h3>
   412         
   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:
   419 <pre>      
   420 $ mvn archetype:generate \
   421  -DarchetypeGroupId=org.apidesign.html \
   422  -DarchetypeArtifactId=knockout4j-archetype \
   423  -DarchetypeVersion=x.y
   424 </pre>
   425         Answer few questions (for example choose myfirstbrwsrpage as artifactId) and then you can:
   426 <pre>
   427 $ cd myfirstbrwsrpage
   428 $ mvn process-classes exec:java
   429 </pre>
   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:
   435 <pre>
   436 $ ls src/main/java/**/DataModel.java
   437 $ ls src/main/webapp/pages/index.html
   438 </pre>
   439         Play with them, modify them and enjoy
   440         <a href="http://html.java.net">Html for Java</a>!
   441         
   442         <a name="debugging">
   443         <h3>Mixed Java/JavaScript Debugging</h3>
   444         </a>
   445         
   446         <p>
   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.
   453         </p>
   454         
   455         <iframe width="420" height="315" 
   456             src="http://www.youtube.com/embed/EvaTejQDRwA" 
   457             frameborder="0" allowfullscreen>
   458         </iframe>
   459     </body>
   460 </html>