boot/src/main/java/net/java/html/js/package.html
author Jaroslav Tulach <jaroslav.tulach@netbeans.org>
Fri, 07 Feb 2014 07:44:34 +0100
changeset 551 7ca2253fa86d
parent 530 ce0da3e90343
child 559 17f78ec9a632
permissions -rw-r--r--
Updating copyright headers to mention current year
     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 {@link net.java.html.js.JavaScriptResource}("mul.js") <b>class</b> Mul {
   101 
   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);
   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 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 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>.
   156         <p></p>
   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.
   162         
   163         <h3>Arrays by Copy</h3>
   164         
   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:
   170         <pre>
   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!" };
   175   uselessModify(arr);
   176   System.out.println(arr[0] + " " + arr[1]);
   177 }            
   178 </pre>
   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.
   182         <p></p>
   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:
   185         <pre>        
   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]);
   192 }            
   193 </pre>
   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.
   199         
   200         <h3>Post Process Classes</h3>
   201 
   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.
   207         <p></p>
   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:
   213 <pre> 
   214 &lt;plugin&gt;
   215     &lt;groupId&gt;org.netbeans.html&lt;/groupId&gt;
   216     &lt;artifactId&gt;html4j-maven-plugin&lt;/artifactId&gt;
   217     &lt;version&gt;${net.java.html.version}&lt;/version&gt;
   218     &lt;executions&gt;
   219         &lt;execution&gt;
   220             &lt;id&gt;js-classes&lt;/id&gt;
   221             &lt;goals&gt;
   222                 &lt;goal&gt;process-js-annotations&lt;/goal&gt;
   223             &lt;/goals&gt;
   224         &lt;/execution&gt;
   225     &lt;/executions&gt;
   226 &lt;/plugin&gt;
   227 </pre>
   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
   236         already processed.
   237         <p></p>
   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
   243         machine with
   244 <pre>
   245 $ java -javaagent:jarpath=net.java.html.boot-x.y.jar
   246 </pre>        
   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
   249         virtual machine. 
   250         <p></p>
   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.
   259         <p></p>
   260         The options are rich, however to avoid any troubles, it is recommended
   261         to perform the <b>compile time</b> processing.
   262         
   263         <h3>Getting Started</h3>
   264         
   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:
   271 <pre>      
   272 $ mvn archetype:generate \
   273  -DarchetypeGroupId=org.apidesign.html \
   274  -DarchetypeArtifactId=knockout4j-archetype \
   275  -DarchetypeVersion=x.y
   276 </pre>
   277         Answer few questions (for example choose myfirstbrwsrpage as artifactId) and then you can:
   278 <pre>
   279 $ cd myfirstbrwsrpage
   280 $ mvn process-classes exec:java
   281 </pre>
   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:
   287 <pre>
   288 $ ls src/main/java/**/DataModel.java
   289 $ ls src/main/webapp/pages/index.html
   290 </pre>
   291         Play with them, modify them and enjoy
   292         <a href="http://html.java.net">Html for Java</a>!
   293     </body>
   294 </html>