boot/src/main/java/net/java/html/js/package.html
author Jaroslav Tulach <jtulach@netbeans.org>
Tue, 26 Aug 2014 18:13:30 +0200
changeset 838 bdc3d696dd4a
parent 614 cf91336956b8
child 883 3299d5335b8f
permissions -rw-r--r--
During the API review process (bug 246133) the reviewers decided that in order to include html4j to NetBeans Platform, we need to stop using org.apidesign namespace and switch to NetBeans one. Repackaging all SPI packages into org.netbeans.html.smthng.spi.
jaroslav@166
     1
<!--
jaroslav@166
     2
jaroslav@358
     3
    DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
jaroslav@166
     4
jaroslav@551
     5
    Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
jaroslav@166
     6
jaroslav@358
     7
    Oracle and Java are registered trademarks of Oracle and/or its affiliates.
jaroslav@358
     8
    Other names may be trademarks of their respective owners.
jaroslav@166
     9
jaroslav@358
    10
    The contents of this file are subject to the terms of either the GNU
jaroslav@358
    11
    General Public License Version 2 only ("GPL") or the Common
jaroslav@358
    12
    Development and Distribution License("CDDL") (collectively, the
jaroslav@358
    13
    "License"). You may not use this file except in compliance with the
jaroslav@358
    14
    License. You can obtain a copy of the License at
jaroslav@358
    15
    http://www.netbeans.org/cddl-gplv2.html
jaroslav@358
    16
    or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
jaroslav@358
    17
    specific language governing permissions and limitations under the
jaroslav@358
    18
    License.  When distributing the software, include this License Header
jaroslav@358
    19
    Notice in each file and include the License file at
jaroslav@358
    20
    nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
jaroslav@358
    21
    particular file as subject to the "Classpath" exception as provided
jaroslav@358
    22
    by Oracle in the GPL Version 2 section of the License file that
jaroslav@358
    23
    accompanied this code. If applicable, add the following below the
jaroslav@358
    24
    License Header, with the fields enclosed by brackets [] replaced by
jaroslav@358
    25
    your own identifying information:
jaroslav@358
    26
    "Portions Copyrighted [year] [name of copyright owner]"
jaroslav@358
    27
jaroslav@358
    28
    Contributor(s):
jaroslav@358
    29
jaroslav@358
    30
    The Original Software is NetBeans. The Initial Developer of the Original
jaroslav@551
    31
    Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
jaroslav@358
    32
jaroslav@358
    33
    If you wish your version of this file to be governed by only the CDDL
jaroslav@358
    34
    or only the GPL Version 2, indicate your decision by adding
jaroslav@358
    35
    "[Contributor] elects to include this software in this distribution
jaroslav@358
    36
    under the [CDDL or GPL Version 2] license." If you do not indicate a
jaroslav@358
    37
    single choice of license, a recipient has the option to distribute
jaroslav@358
    38
    your version of this file under either the CDDL, the GPL Version 2 or
jaroslav@358
    39
    to extend the choice of license to its licensees as provided above.
jaroslav@358
    40
    However, if you add GPL Version 2 code and therefore, elected the GPL
jaroslav@358
    41
    Version 2 license, then the option applies only if the new code is
jaroslav@358
    42
    made subject to such option by the copyright holder.
jaroslav@166
    43
jaroslav@166
    44
-->
jaroslav@166
    45
<!DOCTYPE html>
jaroslav@166
    46
<html>
jaroslav@166
    47
    <body>
jaroslav@513
    48
        <div>Essential support for those who write <em>native</em> methods communicating directly with JavaScript.</div>
jaroslav@513
    49
        Mix your Java and JavaScript code seamlessly - perform calls from Java
jaroslav@513
    50
        to JavaScript and back with as much freedom as JavaScript gives you
jaroslav@513
    51
        and as much type safety you can get from Java. Execute your code
jaroslav@513
    52
        in a headless testing environment or in a 
jaroslav@513
    53
        <a href="http://wiki.apidesign.org/wiki/FXBrwsr">JavaFX WebView</a>. 
jaroslav@513
    54
        When done, deploy to <a href="http://bck2brwsr.apidesign.org">real browsers</a>.
jaroslav@513
    55
        
jaroslav@513
    56
        <h3>Simple Meaning of World</h3>
jaroslav@513
    57
        The whole support is build around @<a href="JavaScriptBody.html">JavaScriptBody</a>
jaroslav@513
    58
        annotation. Use it to create parametrised JavaScript snippet easily
jaroslav@513
    59
        accessible from Java:
jaroslav@513
    60
<pre>
jaroslav@513
    61
{@code @}{@link net.java.html.js.JavaScriptBody}(args = {"x", "y"}, body = "return x + y;")
jaroslav@513
    62
<b>private static native int</b> meaning(<b>int</b> x, <b>int</b> y);
jaroslav@513
    63
</pre>
jaroslav@513
    64
        The above defines method <em>meaning</em> which sums two JavaScript
jaroslav@513
    65
        objects together (being invoked inside of a JavaScript interpreter).
jaroslav@513
    66
        The <em>meaning</em> method now becomes a properly typed Java
jaroslav@513
    67
        surface to your JavaScript code which can be directly
jaroslav@513
    68
        called from the rest of your Java code:
jaroslav@513
    69
<pre>        
jaroslav@513
    70
<b>public static void</b> main(String... args) {
jaroslav@513
    71
  <b>assert</b> 42 == meaning(40, 2) : <em>"Meaning of World should be 42!"</em>;
jaroslav@513
    72
}
jaroslav@513
    73
</pre>
jaroslav@513
    74
        <em>Real code tip:</em> real classes using this technique are
jaroslav@513
    75
        available online:
jaroslav@513
    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
jaroslav@513
    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>.
jaroslav@513
    78
        <p></p>
jaroslav@513
    79
        <em>Editing hint:</em> one can see the list of arguments of the
jaroslav@513
    80
        <em>meaning</em> is now duplicated - it is once specified in Java, 
jaroslav@513
    81
        and once inside of the {@link net.java.html.js.JavaScriptBody} 
jaroslav@513
    82
        array of <code>args</code>. This is necessary to keep the names of 
jaroslav@513
    83
        arguments accessible during runtime. However don't despair - there
jaroslav@513
    84
        is a code completion for the value of <code>args</code> attribute!
jaroslav@513
    85
        Just type the Java signature first and then press Ctrl+Space and the
jaroslav@513
    86
        right parameter names will be inserted for you.
jaroslav@513
    87
        
jaroslav@513
    88
        <a name="#library"><h3>Including JavaScript Libraries</h3></a>
jaroslav@513
    89
jaroslav@513
    90
        Large amount of JavaScript code is easier to be delivered in whole
jaroslav@513
    91
        files rather than {@link net.java.html.js.JavaScriptBody small code snippets} -
jaroslav@513
    92
        that is also possible thanks to {@link net.java.html.js.JavaScriptResource}
jaroslav@513
    93
        annotation. Imagine file <code>mul.js</code> with following content:
jaroslav@513
    94
<pre> 
jaroslav@513
    95
<b>function</b> <em>mul</em>(x, y) { <b>return</b> x * y; }
jaroslav@513
    96
</pre>
jaroslav@513
    97
        Place the file next to your class and reference it with 
jaroslav@513
    98
        {@link net.java.html.js.JavaScriptResource the annotation}:
jaroslav@513
    99
<pre>
jaroslav@559
   100
{@code @}{@link net.java.html.js.JavaScriptResource}("mul.js") <b>class</b> Mul {
jaroslav@513
   101
jaroslav@559
   102
  {@code @}{@link net.java.html.js.JavaScriptBody}(args = { "x", "y" }, body = "return <b>mul</b>(x, y);")
jaroslav@513
   103
  <b>public static native int</b> multiply(int x, int y);
jaroslav@513
   104
jaroslav@513
   105
  <b>public static void</b> main(String... args) {
jaroslav@513
   106
    <b>assert</b> 42 == multiply(6, 7) : <em>"Meaning of World should be 42!"</em>;
jaroslav@513
   107
  }
jaroslav@513
   108
}
jaroslav@513
   109
</pre>
jaroslav@513
   110
        All the Java methods annotated {@link net.java.html.js.JavaScriptBody}
jaroslav@513
   111
        can now reference everything that is in the <code>mul.js</code> file -
jaroslav@513
   112
        e.g. the body of the <code>multiply</code> method can reference the
jaroslav@513
   113
        function <code>mul</code> and use it.
jaroslav@513
   114
        <p></p>
jaroslav@513
   115
        <em>Real code tip:</em>
jaroslav@513
   116
        <a href="http://hg.netbeans.org/html4j/file/release-0.7/ko4j/src/main/java/org/netbeans/html/ko4j/Knockout.java">this</a> 
jaroslav@513
   117
        is the way 
jaroslav@513
   118
        the <a href="http://knockoutjs.com">knockout.js</a> library
jaroslav@513
   119
        is included in its <em>ko4j</em> library.
jaroslav@513
   120
        
jaroslav@513
   121
        <h3>Callback to Java</h3>
jaroslav@513
   122
        
jaroslav@513
   123
        Often JavaScript code needs to call back into the Java classes.
jaroslav@513
   124
        For example when a button in a browser is pressed and your code would
jaroslav@513
   125
        like to invoke a runnable to handle such situation:
jaroslav@513
   126
<pre> 
jaroslav@513
   127
{@code @}{@link net.java.html.js.JavaScriptBody}(args = {"id", "r"}, {@link net.java.html.js.JavaScriptBody#javacall() javacall} = true, body = "\n" + 
jaroslav@513
   128
"       document.getElementById(id).onclick = function() {\n" + 
jaroslav@513
   129
"        r.<em>{@code @}java.lang.Runnable::run()</em>();\n" + 
jaroslav@513
   130
"       };\n" + 
jaroslav@513
   131
"    ")
jaroslav@513
   132
<b>public static native void</b> onClick(String id, Runnable r);
jaroslav@513
   133
</pre>
jaroslav@513
   134
        As can be seen, there is a special syntax (starting with <b>@</b>) to 
jaroslav@513
   135
        properly identify the right Java method to call on a Java object passed
jaroslav@513
   136
        into the JavaScript interpreter. The syntax starts with a fully
jaroslav@513
   137
        qualified name of the class, followed by <b>::</b> and name of the 
jaroslav@513
   138
        method including signature of its parameters. In case of runnable,
jaroslav@513
   139
        this is just <em>()</em> as the method has no parameters, but the
jaroslav@513
   140
        signature can be more complicated. For example in case of following method
jaroslav@513
   141
<pre><b>static int</b> compare(<b>int</b> i1, String s1, <b>int</b> i2, String s2)
jaroslav@513
   142
</pre>        
jaroslav@513
   143
        it would be <em>(ILjava/lang/String;ILjava/lang/String;)</em> (btw. the
jaroslav@513
   144
        return type is not included in the signature). The actual parameters 
jaroslav@513
   145
        then follows. The JavaScript call to such compare method would then
jaroslav@513
   146
        look like:
jaroslav@513
   147
<pre>{@code @}the.pkg.Clazz::compare(ILjava/lang/String;ILjava/lang/String;)(1, 'One', 2, 'Two');
jaroslav@513
   148
</pre>        
jaroslav@513
   149
        This syntax gives enough flexibility, helps to properly select one
jaroslav@513
   150
        of overloaded methods and follows the tradition of previous attempts to
jaroslav@513
   151
        provide JavaScript to Java calling conventions.
jaroslav@513
   152
        <p></p>
jaroslav@513
   153
        Please note that to turn the special Java callback syntax on, one
jaroslav@513
   154
        needs to set the {@link net.java.html.js.JavaScriptBody#javacall()}
jaroslav@513
   155
        attribute to <b>true</b>.
jaroslav@513
   156
        <p></p>
jaroslav@513
   157
        <em>Editing hint:</em> there is an associated annotation processor 
jaroslav@513
   158
        that checks the syntax and verifies the referenced class and
jaroslav@513
   159
        method of the right signature exist. If they do not, the
jaroslav@513
   160
        compilation fails. Thus don't despair seeing the syntax, you'll get early
jaroslav@513
   161
        warnings when there is a typo.
jaroslav@514
   162
        
jaroslav@514
   163
        <h3>Arrays by Copy</h3>
jaroslav@514
   164
        
jaroslav@514
   165
        It is possible to exchange arrays between Java and JavaScript. Some
jaroslav@514
   166
        implementations can pass arrays by reference, however in some systems
jaroslav@514
   167
        this is hard to achieve. To choose the least common denominator, 
jaroslav@514
   168
        the TCK for behavior of {@link net.java.html.js.JavaScriptBody} requires
jaroslav@514
   169
        the arrays to be always transfered by a copy. As such following code:
jaroslav@514
   170
        <pre>
jaroslav@514
   171
{@code @}{@link net.java.html.js.JavaScriptBody}(args = {"arr"}, body = "arr[0] = null;")
jaroslav@514
   172
<b>private static native void</b> uselessModify(String[] arr);
jaroslav@514
   173
<b>public static void</b> main(String... args) {
jaroslav@514
   174
  String[] hello = { "Hello", "World!" };
jaroslav@514
   175
  uselessModify(arr);
jaroslav@514
   176
  System.out.println(arr[0] + " " + arr[1]);
jaroslav@514
   177
}            
jaroslav@514
   178
</pre>
jaroslav@514
   179
        will still print <em>Hello World!</em> in spite the JavaScript code
jaroslav@514
   180
        sets the 0-th array element to <code>null</code>. Because the array
jaroslav@514
   181
        is passed as a copy, such assignment has no effect on the Java array.
jaroslav@514
   182
        <p></p>
jaroslav@514
   183
        In case one needs to modify an array in a JavaScript and use its 
jaroslav@514
   184
        values in Java, one has to return the array back as a return value:
jaroslav@514
   185
        <pre>        
jaroslav@514
   186
{@code @}{@link net.java.html.js.JavaScriptBody}(args = {"arr"}, body = "arr[0] = 'Ahoy'; return arr;")
jaroslav@515
   187
<b>private static native</b> Object[] usefulModify(String[] arr);
jaroslav@514
   188
<b>public static void</b> main(String... args) {
jaroslav@514
   189
  String[] hello = { "Hello", "World!" };
jaroslav@514
   190
  Object[] ret = usefulModify(arr);
jaroslav@514
   191
  System.out.println(ret[0] + " " + ret[1]);
jaroslav@514
   192
}            
jaroslav@514
   193
</pre>
jaroslav@514
   194
        now the program prints <em>Ahoy World!</em> as the modified array
jaroslav@514
   195
        is returned back and converted (by a copy) into a Java <code>Object[]</code>
jaroslav@514
   196
        (but of course the <code>ret != hello</code>). Usually the copy based
jaroslav@514
   197
        passing of arrays works OK. It is however good to keep it in mind to 
jaroslav@514
   198
        avoid unwanted surprises.
jaroslav@514
   199
        
jaroslav@514
   200
        <h3>Post Process Classes</h3>
jaroslav@530
   201
jaroslav@530
   202
        Classes with {@link net.java.html.js.JavaScriptBody} annotated methods need to
jaroslav@530
   203
        be post processed before they can be used - e.g. their <code>native</code>
jaroslav@530
   204
        body needs to be generated to call into JavaScript (btw. the code is performed
jtulach@838
   205
        via {@link org.netbeans.html.boot.spi.Fn}). There are three ways
jaroslav@530
   206
        such post processing can happen.
jaroslav@530
   207
        <p></p>
jaroslav@530
   208
        <b>Compile time</b> processing - this is the preferred method that
jaroslav@530
   209
        most of the <a href="http://html.java.net">Html Java APIs</a> are using. 
jaroslav@530
   210
        Just include following plugin configuration into your <code>pom.xml</code>
jaroslav@530
   211
        and your classes will be ready for execution as soon as <em>process-classes</em>
jaroslav@530
   212
        <a href="http://wiki.apidesign.org/wiki/Maven">Maven</a> phase is over:
jaroslav@530
   213
<pre> 
jaroslav@530
   214
&lt;plugin&gt;
jaroslav@530
   215
    &lt;groupId&gt;org.netbeans.html&lt;/groupId&gt;
jaroslav@530
   216
    &lt;artifactId&gt;html4j-maven-plugin&lt;/artifactId&gt;
jaroslav@530
   217
    &lt;version&gt;${net.java.html.version}&lt;/version&gt;
jaroslav@530
   218
    &lt;executions&gt;
jaroslav@530
   219
        &lt;execution&gt;
jaroslav@530
   220
            &lt;id&gt;js-classes&lt;/id&gt;
jaroslav@530
   221
            &lt;goals&gt;
jaroslav@530
   222
                &lt;goal&gt;process-js-annotations&lt;/goal&gt;
jaroslav@530
   223
            &lt;/goals&gt;
jaroslav@530
   224
        &lt;/execution&gt;
jaroslav@530
   225
    &lt;/executions&gt;
jaroslav@530
   226
&lt;/plugin&gt;
jaroslav@530
   227
</pre>
jaroslav@530
   228
        This plugin works in orchestration with 
jaroslav@530
   229
        <a href="http://wiki.apidesign.org/wiki/AnnotationProcessor">annotation
jaroslav@530
   230
        processor</a> associated with {@link net.java.html.js.JavaScriptBody}
jaroslav@530
   231
        and {@link net.java.html.js.JavaScriptResource} - the processor creates
jaroslav@530
   232
        list of files that need post-processing. The 
jaroslav@530
   233
        <a href="http://wiki.apidesign.org/wiki/Maven">Maven</a>
jaroslav@530
   234
        plugin reads these files, processes classes mentioned in them and 
jaroslav@530
   235
        modifies (and deletes at the end) the files to not include classes
jaroslav@530
   236
        already processed.
jaroslav@530
   237
        <p></p>
jaroslav@530
   238
        <b>Instrumentation Agent</b> - one can do processing in runtime 
jaroslav@530
   239
        using JDK's {@link java.lang.instrument.ClassFileTransformer instrumentation}
jaroslav@530
   240
        abilities. The JAR artifact of <code>org.netbeans.html:net.java.html.boot</code>
jaroslav@530
   241
        contains an <code>Agent-Class</code> and <code>Premain-Class</code> 
jaroslav@530
   242
        definitions in its manifest. As such one can launch the Java virtual
jaroslav@530
   243
        machine with
jaroslav@530
   244
<pre>
jaroslav@530
   245
$ java -javaagent:jarpath=net.java.html.boot-x.y.jar
jaroslav@530
   246
</pre>        
jaroslav@530
   247
        and the runtime will take care of processing bytecode of classes 
jaroslav@530
   248
        not yet processed in compile time before they are loaded into the
jaroslav@530
   249
        virtual machine. 
jaroslav@530
   250
        <p></p>
jaroslav@530
   251
        <b>Special classloading</b> - when booting your application with
jaroslav@530
   252
        {@link net.java.html.boot.BrowserBuilder} there is a 3rd option of
jaroslav@530
   253
        processing the classes. If there are some classes not yet processed
jaroslav@530
   254
        (remember the files listing them generated by the 
jaroslav@530
   255
        <a href="http://wiki.apidesign.org/wiki/AnnotationProcessor">annotation
jaroslav@530
   256
        processor</a>), the {@link net.java.html.boot.BrowserBuilder#showAndWait() launching method}
jaroslav@530
   257
        will create a special classloader to that does the processing before
jaroslav@530
   258
        loading the bytecode into the virtual machine.
jaroslav@530
   259
        <p></p>
jaroslav@530
   260
        The options are rich, however to avoid any troubles, it is recommended
jaroslav@530
   261
        to perform the <b>compile time</b> processing.
jaroslav@514
   262
        
jaroslav@530
   263
        <h3>Getting Started</h3>
jaroslav@530
   264
        
jaroslav@530
   265
        There are many ways to start developing 
jaroslav@530
   266
        <a href="http://html.java.net">Html for Java</a> application. 
jaroslav@530
   267
        However to be sure one chooses the most recent setup, it is recommended
jaroslav@530
   268
        to switch to good old command line and use a 
jaroslav@530
   269
        <a href="http://wiki.apidesign.org/wiki/Knockout4Java">Maven archetype</a>
jaroslav@530
   270
        associated with every version of this project. Just type:
jaroslav@530
   271
<pre>      
jaroslav@530
   272
$ mvn archetype:generate \
jaroslav@530
   273
 -DarchetypeGroupId=org.apidesign.html \
jaroslav@530
   274
 -DarchetypeArtifactId=knockout4j-archetype \
jaroslav@530
   275
 -DarchetypeVersion=x.y
jaroslav@530
   276
</pre>
jaroslav@530
   277
        Answer few questions (for example choose myfirstbrwsrpage as artifactId) and then you can:
jaroslav@530
   278
<pre>
jaroslav@530
   279
$ cd myfirstbrwsrpage
jaroslav@530
   280
$ mvn process-classes exec:java
jaroslav@530
   281
</pre>
jaroslav@530
   282
        In a few seconds (or minutes if 
jaroslav@530
   283
        <a href="http://wiki.apidesign.org/wiki/Maven">Maven</a>
jaroslav@530
   284
        decides to download the whole Internet of dependencies) you should 
jaroslav@530
   285
        see a sample Hello World application. It is basically composed from one 
jaroslav@530
   286
        Java and one HTML file:
jaroslav@530
   287
<pre>
jaroslav@530
   288
$ ls src/main/java/**/DataModel.java
jaroslav@530
   289
$ ls src/main/webapp/pages/index.html
jaroslav@530
   290
</pre>
jaroslav@530
   291
        Play with them, modify them and enjoy
jaroslav@530
   292
        <a href="http://html.java.net">Html for Java</a>!
jaroslav@614
   293
        
jaroslav@614
   294
        <a name="debugging">
jaroslav@614
   295
        <h3>Mixed Java/JavaScript Debugging</h3>
jaroslav@614
   296
        </a>
jaroslav@614
   297
        
jaroslav@614
   298
        <p>
jaroslav@614
   299
        The following video shows how easy it is to use 
jaroslav@614
   300
        NetBeans 8.0, JDK8 to debug an application that intermixes Java 
jaroslav@614
   301
        and JavaScript calls. One can put breakpoints into Java part, 
jaroslav@614
   302
        as well as JavaScript source code, inspect Java as well 
jaroslav@614
   303
        as JavaScript variables and switch between these two 
jaroslav@614
   304
        languages without any restrictions.
jaroslav@614
   305
        </p>
jaroslav@614
   306
        
jaroslav@614
   307
        <iframe width="420" height="315" 
jaroslav@614
   308
            src="http://www.youtube.com/embed/EvaTejQDRwA" 
jaroslav@614
   309
            frameborder="0" allowfullscreen>
jaroslav@614
   310
        </iframe>
jaroslav@166
   311
    </body>
jaroslav@166
   312
</html>