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
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@513
   100
{@link net.java.html.js.JavaScriptResource}("mul.js") <b>class</b> Mul {
jaroslav@513
   101
jaroslav@513
   102
  {@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
jaroslav@530
   205
        via {@link org.apidesign.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@166
   293
    </body>
jaroslav@166
   294
</html>