liveconnect
Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
parent directory.. | ||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Scott Furman">
<meta name="GENERATOR" content="Mozilla/4.5 [en] (WinNT; I) [Netscape]">
<title>README for LiveConnect</title>
</head>
<body>
This is the README file for the JavaScript LiveConnect
Version 3 ("LC3") implementation.
<h2>
Table of Contents</h2>
<blockquote><a href="#Introduction">Introduction</a>
<br><a href="#New_Features">New features</a>
<br><a href="#Compatibility">Compatibility</a>
<br><a href="#Limitations">Limitations/Bugs/To-Do</a>
<br><a href="#Build_conventions">Build conventions</a>
<br><a href="#coding_conventions">Naming and coding conventions</a>
<br><a href="#API">The LiveConnect API</a>
<br><a href="#sample_shell_interaction">Sample LiveConnect shell interactions</a></blockquote>
<h2>
<a NAME="Introduction"></a>Introduction</h2>
LiveConnect allows JavaScript and Java virtual machines to interoperate.
Specifically, it enables JavaScript to access Java fields, invoke Java
methods and makes it possible for Java to access JavaScript object properties
and evaluate arbitrary JavaScript. More information on LiveConnect
can be found by <a href="http://developer.netscape.com/find/find.cgi?scope=LiveConnect&browse-category=&ui=sr&chunk-size=&page=1&taxonomy=DevEdge+Online">searching
the index on Netscape's DevEdge site</a>. This README assumes basic
familiarity with <a href="http://cvs-mirror.mozilla.org/webtools/lxr/source/js/src/README.html">JSRef</a>,
the reference implementation of JavaScript, and with the LiveConnect technology.
<p>JSRef project/makefiles build a library or DLL containing the JavaScript
runtime (compiler, interpreter, decompiler, garbage collector, atom manager,
standard classes). The LiveConnect project/makefiles build a library
that links both with JSRef and with any Java Virtual Machine (JVM) that
implements the Java Native Interface (JNI), as specified by JavaSoft.
It then compiles a small "shell" example program and links that with the
library to make an interpreter that can be used interactively and with
test scripts. See the <a href="#sample_shell_interaction">sample
shell interactions</a>.
<p><i>Scott Furman, 10/31/98</i>
<h2>
<a NAME="New_Features"></a>New features</h2>
The following features were not available in the versions of LiveConnect
that were integrated with Netscape Navigator versions 4.x and earlier.
For information on LiveConnect version 1, which was used in Navigator 3
and 4 and Enterprise Server 3, see <a href="http://developer.netscape.com/find/find.cgi?scope=LiveConnect&browse-category=&ui=sr&chunk-size=&page=1&taxonomy=DevEdge+Online">Netscape's
DevEdge site</a> or any number of 3rd-party publications.)
<h4>
LiveConnect version 3 (10/31/98)</h4>
<ul>
<li>
In previous versions of LiveConnect, when more than one overloaded Java
method was compatible with the types of arguments in an invocation from
JS, the choice of Java method was made arbitrarily, by using the first
one enumerated by the Java reflection APIs. Unfortunately, the ordering
of methods when enumerating is not governed by any specification, so differences
between JVM vendors could lead to inconsistencies in LiveConnect behavior.
Now, a <a href="http://www.mozilla.org/js/liveconnect/lc3_method_overloading.html">JVM-independent
set of rules</a> is used to choose among a set of overloaded methods.
Informally, the method with Java parameter types that most closely
match the JavaScript types is chosen.</li>
<li>
The weak correspondence between the JS language typing system and Java's
may result in ambiguity and/or shadowing when resolving among overloaded
Java methods, even when using LC3's improved method overload resolution
algorithm. For example, JS's number type can map to any of Java's
floating-point or integral types: byte, char, short, int, long, float,
double.
If necessary, it is possible to bypass the method overload resolution process
and explicitly specify the method to be invoked:</li>
<br>
<ul><tt>myPrintMethod = java.io.PrintStream["print(double)"];</tt>
<br><tt>myPrintMethod(13);</tt></ul>
<br>
<li>
Static methods can now be invoked using either the class name or a reference
to an instance of the class. (Older versions of LiveConnect allow
only the former.)</li>
<li>
It is no longer necessary to convert Java Strings to JS strings before
using them as the receivers of JS string methods, which is typically done
by appending an empty string to the Java string, e.g.</li>
<p><br><tt> s = new java.lang.String("foo")</tt>
<br><tt> s = s + "";
</tt>// s is now a JS string
<br><tt> m = s.match(/o?/)</tt>
<p>The explicit conversion to a JS string is no longer required because
<i>java.lang.String</i>
objects are treated as a special case that "inherit" all the methods of
JS strings, i.e. so that the second statement in the example above is now
superfluous.
<li>
Similarly, JavaArray objects "inherit" the methods of JS's <tt>Array.prototype</tt>,
so it is possible to appy many of the JS array utility methods such as
<tt>reverse()</tt>
and <tt>join()</tt> to JavaArray objects.</li>
<li>
There is now support for the <tt>instanceof</tt> and <tt>in</tt> operators.
These operators are currently proposed for inclusion in the ECMA-2 standard.</li>
<li>
LiveConnect has been extended to take advantage of JavaScript exceptions,
a language feature that debuted in JavaScript 1.4. Now, when JavaScript
calls into Java, any Java exceptions are converted to JS exceptions which
can be caught using JS try-catch statements. Similarly, JS exceptions
are propagated to Java wrapped in an instance of <i>netscape.javascript.JSException</i>.</li>
</ul>
<h4>
LiveConnect version 2 (7/31/98)</h4>
<blockquote>
<li>
The Java methods of <i>java.lang.Object</i> are now invokeable methods
of <tt><font size=+1>JavaArray</font></tt> objects, matching the behavior
of arrays when accessed from Java<i>.</i> (Java arrays are a subclass
of <i>java.lang.Object</i>.) For example, Java's <tt><font size=+1>getClass()</font></tt>
and <tt><font size=+1>hashCode()</font></tt> methods can now be called
on <tt><font size=+1>JavaArray</font></tt> objects. (In prior versions
of LiveConnect, the methods of <i>java.lang.Object</i> were only inherited
by non-array Java objects.)</li>
<p>Note that this change has caused the string representation of JavaArray
objects to change. Previously, the JavaArray toString() method always
printed "<tt><font size=+1>[object JavaArray]"</font></tt> for all <tt><font size=+1>JavaArray</font></tt>'s.
Now, the Java <tt><font size=+1>java.lang.Object.toString()</font></tt>
method is called to convert JavaArray objects to strings, just as with
other, non-array Java objects that are accessible via LiveConnect. <tt><font size=+1>java.lang.Object.toString()</font></tt>is
defined in the <i>Java Language Specification</i> to return the value of
the following expression:
<p><tt><font size=-1>getClass().getName() + '@' + Integer.toHexString(hashCode())</font></tt>
<br>
<li>
A one-character string is now an acceptable match for an argument to a
Java method of type <tt><font size=+1>char</font></tt>. (In earlier
versions of LiveConnect, the only acceptable match for a <tt><font size=+1>char</font></tt>
had to be a JavaScript value that was convertible to a number.) For
example, the following is now possible:</li>
<p><tt><font size=-1>c = new java.lang.Character("F")</font></tt>
<br>
<li>
A JavaClass object is now an acceptable match for an argument to a Java
method of type <i>java.lang.Class</i>. For example, you can now write:</li>
<p><tt><font size=-1>java.lang.reflect.Array.newInstance(java.lang.String,
3)</font></tt>
<p>instead of the more verbose:
<p><tt><font size=-1>jls = java.lang.Class.forName("java.lang.String")</font></tt>
<br><tt><font size=-1>java.lang.reflect.Array.newInstance(jls, 3)</font></tt>
<br> </blockquote>
<h2>
<a NAME="Compatibility"></a>Compatibility</h2>
Unlike this standalone/component release, all previous versions of LiveConnect
appeared only as an integrated feature of Netscape Navigator. The
variants of LiveConnect that appeared in Navigator versions 3.x and 4.x
all behave much the same, modulo bugs. For brevity we refer to this
classic version of LiveConnect as "LC1" (LiveConnect version 1) and this
most recent release as "LC3". (There was an intermediate LiveConnect
release known as "LC2" in 7/98, but it was not used in any products.
"LC3" provides a superset of LC2 features.)
<ul>
<li>
As in LC1, JavaScript objects appear to Java as instances of <i>netscape.javascript.JSObject</i>.
In LC1, two <i>JSObject</i>'s could be tested for equality, i.e. to see
if they refer to the same instance, by using the `==' operator. Instead,
developers must now use the <tt>equals()</tt>method of <i>netscape.javascript.JSObject</i>
for comparison, a method that overrides <tt>java.lang.Object.equals()</tt>.
Using <tt>equals()</tt> instead of `==' should work the same in all versions
of LiveConnect.</li>
<p>It is not possible to replicate the identity behavior of the `==' operator
that LC1 provides without the use of "weak" references, i.e. references
that do not contribute to making a Java object reachable for purposes of
garbage collection, but which nonetheless allow reference to an object
as long as it is reachable by other means. The use of weak references
is not portable, however. It is not part of the JNI or the JDK and
it is not provided on all JVMs. The JDK1.2 release will include standard
support for weak references.
<br>
<li>
It's possible that, in a set of overloaded Java methods, more than one
method is compatible with the types of the actual arguments in a call from
JavaScript via LiveConnect. LC1 and LC2 resolved these ambiguities
in a simplistic manner, by simply invoking whatever method was enumerated
first by the JVM. The enumeration order of reflected methods using
<i>java.lang.reflect</i>
is not specified by Sun and may differ among vendor's JVMs, i.e. enumeration
could be in order of classfile appearance, hashtable order, etc.
Hence, the Java method chosen when there is more than one compatible method
may vary depending on the JVM. With the Netscape and Sun JVMs, it
is possible to change the behavior of an LC1/LC2 program by changing the
order that Java methods appear in a source file, thus changing the method
enumeration order.</li>
<p>In LC3, a new method overload resolution algorithm is used. Informally,
the method with Java parameter types that most closely match the
JavaScript types is chosen. You can read all the gorey details in
the <a href="http://www.mozilla.org/js/liveconnect/lc3_method_overloading.html">spec</a>.
<br>
<li>
There are several minor changes in error handling to make LiveConnect more
conformant to ECMAScript. These include, for example, making any
attempt to delete JavaObject, JavaClass or JavaPackage properties fail
silently, rather than causing an error. Also, some error messages
have been changed to be more informative. These changes should generally
be backward-compatible with LC1 because few programs that use LiveConnect
will depend on the exact behavior of LiveConnect when handling errors.</li>
</ul>
<h2>
<a NAME="Limitations"></a>Limitations/Bugs/To-Do</h2>
<ul>
<li>
There is no way to explicitly resolve overloaded constructors, i.e. in
the same way that can be done with instance and static methods.</li>
<li>
The efficiency of calling Java methods leaves something to be desired,
due to the convoluted nature of implementing native methods for JS.
JS_CloneFunctionObject() is called for every Java method invocation and
the inability to store private data in a JSFunction object requires that
the method table be searched twice instead of once.</li>
<li>
When Java objects are referenced from JS, they are entered into a hash
table, so as to ensure that the same JS Object wrapper is used every time
a particular Java object is reflected into JS. In this way, the behavior of
the JS '==' and '===' operators are preserved. Unfortunately, the
hash table may grow quite large (objects are only removed from the hash
table when finalized). One solution would be to make it possible
to overload JS's equality-test operators, so that the hash table would
no longer be required.</li>
<li>
Initially, JavaClassDescriptors were reference-counted to permit free'ing
of unused descriptors. However, it's relatively common to develop
cycles in the graph of JavaClassDescriptors, which leads to unused JavaClassDescriptors
that are not free'ed until JSJ_Shutdown(). Luckily, the amount of
memory used by JavaClassDescriptors tends to be relatively small.</li>
<li>
The LiveConnect API is designed to allow multiple JVMs to be used simultaneously
in the same executable (although each JSContext is limited to interaction
with at most one JVM). However, the API is not fully implemented.
For example, many global variables will need to become members of the JSJavaVM
struct so that they are stored on a per-JVM basis.</li>
<li>
Java and JavaScript use independent garbage collection systems. A reference between the two worlds must, therefore, take the form of a GC root. It's possible to create uncollectable objects when cyclic graphs cross the boundary between JS and Java, e.g. a JS object that refers to a Java object that refers back to the original JS object. There is no simple solution to this dual-GC problem. Luckily, such cyclic object graphs are extremely rare.
</li>
</ul>
<h2>
<a NAME="Build_conventions"></a>Build conventions</h2>
Update your JVM's <tt><font size=+1>CLASSPATH</font></tt> to point to the
<tt>js/src/liveconnect/classes</tt>
subdirectory. If you do not, LiveConnect will still operate but with
the limitation that JS objects may not be passed as arguments of Java methods
and it will not be possible to call from Java into JavaScript, i.e. the
<i>netscape.javascript.JSObject</i> class will be inaccessible. Another
downside of operating without these classes is that Java error messages
will not include a Java stack trace, when one is available. If your
<tt><font size=+1>CLASSPATH</font></tt>
is set improperly, you will see a message like, "<tt>initialization error:
Can't load class netscape/javascript/JSObject</tt>" when starting a LiveConnect
debug build.
<p>By default, all platforms build a version of LiveConnect that is <i>not</i>
threadsafe. If you require thread-safety, you must also populate
the <tt>mozilla/dist</tt> directory with <a href="http://www.mozilla.org/docs/tplist/catCode/nsprdesc.htm">NSPR</a>
headers and libraries. (NSPR implements a portable threading library,
among other things. The source is downloadable via <a href="http://www.mozilla.org/cvs.html">CVS</a>
from <tt><a href="http://cvs-mirror.mozilla.org/webtools/lxr/source/nsprpub">mozilla/nsprpub</a></tt>.)
Next, you must define <tt>JS_THREADSAFE</tt> when building LiveConnect,
either on the command-line (gmake/nmake) or in a universal header file.
Note that JSRef must also be built with <tt><font size=+1>JS_THREADSAFE</font></tt>.
<ul><b>Windows</b>
<ul>
<li>
Build the JS runtime and interpreter, <tt>js32.dll</tt>, by using the <a href="http://cvs-mirror.mozilla.org/webtools/lxr/source/js/src/README.html#Build">normal
JSRef build procedure</a>.</li>
<li>
Set the <tt><font size=+1>JDK</font></tt> environment variable to point
to the top-level JDK directory, e.g. <tt>D:\jdk1.1.5</tt>. This is
used to establish paths for header file inclusion, linking and execution.
If you are not using Sun's JVM, the project files may require manual tweaking
to set these paths correctly.</li>
<li>
Use MSDEV5.0 with the <tt>LiveConnectShell.dsw</tt> project file.
<font color="#993300">NOTE: makefile.win is an nmake file used only for
building the JS-engine in the Mozilla browser. Don't attempt to use
it to build the standalone JS-engine.</font></li>
<li>
The output files (DLLs and executables) are placed in either the <tt>js\src\liveconnect\Debug</tt>
or the <tt>js\src\liveconnect\Release</tt> directory.</li>
<li>
The LiveConnect-enabled shell is named <tt>lcshell.exe</tt> and appears
in the output directory.</li>
<li>
You must have the JVM DLL in your <tt><font size=+1>PATH</font></tt> environment
variable in order to run. If you are using the Sun JDK, the DLL appears
in the JDK's bin directory, e.g. <tt>D:\jdk1.1.5\bin\javai_g.dll</tt>.</li>
<li>
Use any Java compiler to compile the java source files in the <tt>js\src\liveconnect\classes\netscape\javascript</tt>
directory.</li>
<li>
Update your JVM's <tt><font size=+1>CLASSPATH</font></tt> to point to the
<tt>js\src\liveconnect\classes</tt>
subdirectory. (See above)<br>
<BR></li>
</ul>
<b>Mac OS</b>
<ul>
<li>
Using CodeWarrior Pro 3 is recommended, though the project files will probably
also work with CodeWarrior Pro 4.</li>
<li>
Install Apple's JVM, MRJ 2.0 (or later), and the <a href="ftp://dev.apple.com/devworld/Java/MRJSDK2.0.1EarlyAccess4.hqx">MRJ
SDK v2.0.1ea4</a>. Note: You do not need to install MRJ if you are
running a recent version of MacOS 8, since it is shipped with the OS.</li>
<li>
Copy the folders <tt>CIncludes</tt> & <tt>Libraries</tt> from the SDK's
<tt>Interfaces&Libraries</tt> directory to <tt>js:src:liveconnect:macbuild:JavaSession</tt>.</li>
<li>
Build the LiveConnect test application, <tt>LiveConnectShell</tt>, with
<tt>js:src:liveconnect:macbuild:LiveConnectShell.mcp</tt>.</li>
<li>
Build <tt>liveconnect.jar</tt> with <tt>js:src:liveconnect:macbuild:LiveConnect.mcp</tt>.</li>
<li>
Make an alias to <tt>liveconnect.jar</tt> and place it in "<tt>{SystemFolder}Extensions:MRJ
Libraries:MRJClasses</tt>".<br>
<BR></li>
</ul>
<b>Unix</b>
<ul>
<li>
<font color="#000000">Use '<tt>gmake -f Makefile.ref</tt>' to build. To
compile optimized code, pass <tt>BUILD_OPT=1</tt> on the gmake command
line or preset it in the environment or <tt>Makefile.ref</tt>. </font><font color="#990000">NOTE:
Do not attempt to use <tt>Makefile</tt> to build. This file is used
only for building LiveConnect in the Mozilla browser.</font></li>
<li>
<font color="#000000">Each platform on which LiveConnect is built must
have a *.mk configuration file in the <tt>js/src/liveconnect/config</tt>
directory. The configuration file specifies the JVM headers/libraries
used and allows for customization of command-line options. To date,
the build system has been tested on Solaris, AIX, HP/UX, OSF, IRIX, x86
Linux and Windows NT. Most platforms will work with either the vendor compiler
or gcc.</font></li>
<li>
Use any Java compiler to compile the java source files in the <tt>js/src/liveconnect/classes/netscape/javascript</tt>
directory.</li>
<li>
Update your JVM's <tt><font size=+1>CLASSPATH</font></tt> to point to the
<tt>js/src/liveconnect/classes</tt>
subdirectory. (See above)</li>
</ul>
</ul>
<h2>
<a NAME="coding_conventions"></a>Naming and coding conventions:</h2>
<ul>
<li>
Public function names begin with JSJ_ followed by capitalized "intercaps",
e.g. JSJ_ConnectToJavaVM.</li>
<li>
Extern but library-private function names use a jsj_ prefix and mixed case,
e.g. jsj_LookupSymbol.</li>
<li>
Most static function names have unprefixed, underscore-separated names:
get_char.</li>
<li>
But static native methods of JS objects have intercaps names, e.g., JavaObject_getProperty().</li>
<li>
And library-private and static data use underscores, not intercaps (but
library-private data do use a js_ prefix).</li>
<li>
Scalar type names are lowercase and js-prefixed: jsdouble.</li>
<li>
Aggregate type names are JS-prefixed and mixed-case: JSObject.</li>
<li>
Macros are generally ALL_CAPS and underscored, to call out potential side
effects, multiple uses of a formal argument, etc.</li>
<li>
Four spaces of indentation per statement nesting level. The files
are space-filled, so adjusting of your tab setting should be unnecessary.</li>
<li>
I don't bow down to the ancient "80 columns per line" gods, since most
of us are not using vt100's to read source code. My rule of thumb
is to use no more than 95 columns per line, but exceptions are made to
format tables or table-like code.</li>
<li>
DLL entry points have their return type expanded within a JS_EXPORT_API()
macro call, to get the right Windows secret type qualifiers in the right
places for both 16- and 32-bit builds.</li>
<li>
Callback functions that might be called from a DLL are similarly macroized
with JS_STATIC_DLL_CALLBACK (if the function otherwise would be static
to hide its name) or JS_DLL_CALLBACK (this macro takes no type argument;
it should be used after the return type and before the function name).</li>
</ul>
<h2>
<a NAME="API"></a>The LiveConnect API</h2>
All public LiveConnect entry points and callbacks are documented in <A HREF=http://cvs-mirror.mozilla.org/webtools/lxr/source/js/src/liveconnect/jsjava.h>jsjava.h</A>,
the header file that exports those functions.
<br>
<h2>
<a NAME="File_walkthrough"></a>File walk-through</h2>
<table BORDER=3 CELLSPACING=0 CELLPADDING=4 >
<tr>
<td>jsjava.h</td>
<td>LiveConnect's only public header file. Defines all public API
entry points, callbacks and types. </td>
</tr>
<tr>
<td>jsj_private.h</td>
<td>LiveConnect internal header file for intra-module sharing of functions
and types.</td>
</tr>
<tr>
<td>jsj.c</td>
<td>Public LiveConnect API entry points and initialization code. Handling
of multiple threads and multiple JVMs.</td>
</tr>
<tr>
<td>jsj_array.c</td>
<td>Read and write elements of a Java array, performing needed conversions
to/from JS types.</td>
</tr>
<tr>
<td>jsj_class.c</td>
<td>Construct and manipulate JavaClassDescriptor structs, which are the
native representation for Java classes. JavaClassDescriptors are
used to describe the methods and fields of a class, including their type
signatures, and include a reference to the peer <i>java.lang.Class</i>
object. Since each Java object has a class, there is a JavaClassDescriptor
associated with the JavaScript reflection of each Java Object.</td>
</tr>
<tr>
<td>jsj_convert.c</td>
<td>Convert between Java and JavaScript values of all types, which may
require calling routines in other files to wrap JS objects as Java objects
and vice-versa.</td>
</tr>
<tr>
<td>jsj_field.c</td>
<td>Reflect Java fields as properties of JavaObject objects and implement
getter/setter access to those fields.</td>
</tr>
<tr>
<td>jsj_JavaArray.c</td>
<td>Implementation of the JavaScript JavaArray class. Instances of
JavaArray are used to reflect Java arrays.</td>
</tr>
<tr>
<td>jsj_JavaClass.c</td>
<td>Implementation of the JavaScript JavaClass class. Instances
of JavaClass are used to reflect Java classes.</td>
</tr>
<tr>
<td>jsj_JavaObject.c</td>
<td>Implementation of the JavaScript JavaObject class. Instances
of JavaObject are used to reflect Java objects, except for Java arrays,
although some of the code in this file is used by the JavaArray code.</td>
</tr>
<tr>
<td>jsj_JavaMember.c</td>
<td>Implementation of the JavaScript JavaMember class. JavaMember's
are a strange beast required only to handle the special case of a public
field and a public method that appear in the same Java class and which
have the same name.</td>
</tr>
<tr>
<td>jsj_JavaPackage.c</td>
<td>Implementation of the JavaScript JavaPackage class. Instances
of JavaPackage are used to reflect Java packages. The JS properties
of a JavaPackage are either nested JavaPackage objects or a JavaClass object.</td>
</tr>
<tr>
<td>jsj_JSObject.c</td>
<td>Implementation of the native methods for the <i>netscape.javascript.JSObject</i>
Java class, which are used for calling into JavaScript from Java.
It also contains the code that wraps JS objects as instances of <i>netscape.javascript.JSObject
</i>and
the code that handles propagation of exceptions both into and out of Java.</td>
</tr>
<tr>
<td>jsj_method.c</td>
<td>Reflect Java methods as properties of JavaObject objects and make it
possible to invoke those methods. Includes overloaded method resolution
and argument/return-value conversion code.</td>
</tr>
<tr>
<td>jsj_utils.c</td>
<td>Low-level utility code for reporting errors, etc.</td>
</tr>
</table>
<h2>
<a NAME="sample_shell_interaction"></a>Sample LiveConnect shell interactions</h2>
<h4>
Java packages, classes and constructors</h4>
<tt>js> java</tt>
<br><tt>[JavaPackage java]</tt>
<br><tt>js> awt = java.awt</tt>
<br><tt>[JavaPackage java.awt]</tt>
<br><tt>js> Rectangle = awt.Rectangle</tt>
<br><tt>[JavaClass java.awt.Rectangle]</tt>
<h4>
Java instance fields and methods</h4>
<tt>js> r = new java.awt.Rectangle(34, 23)</tt>
<br><tt>java.awt.Rectangle[x=0,y=0,width=34,height=23]</tt>
<br><tt>js> r.width - r.height</tt>
<br><tt>11</tt>
<br><tt>js> r.x = 7; r.y = 4</tt>
<br><tt>4</tt>
<br><tt>js> r</tt>
<br><tt>java.awt.Rectangle[x=7,y=4,width=34,height=23]</tt>
<br><tt>js> r.grow(3)</tt>
<br><tt>There is no Java method java.awt.Rectangle.grow that matches JavaScript
argument types (number).</tt>
<br><tt>Candidate methods with the same name are:</tt>
<br><tt> void grow(int, int)</tt>
<p><tt>js> r.grow(3, 3)</tt>
<br><tt>js> r</tt>
<br><tt>java.awt.Rectangle[x=4,y=1,width=40,height=29]</tt>
<h4>
Java arrays</h4>
<tt>js> s = new java.lang.String("mastiff")</tt>
<br><tt>mastiff</tt>
<br><tt>js> c = s.toCharArray()</tt>
<br><tt>[C@298e9b</tt>
<br><tt>js> c[0] = "b"; c[4] = "a"; c[5] = "r"; c[6] = "d"</tt>
<br><tt>d</tt>
<br><tt>js> s2 = new java.lang.String(c)</tt>
<br><tt>bastard</tt>
<h4>
Java static fields and methods</h4>
<tt>js> java.lang.reflect.Modifier.ABSTRACT</tt>
<br><tt>1024</tt>
<br><tt>js> java.lang.Math.sin(3) + 2</tt>
<br><tt>2.1411200080598674</tt>
<h4>
Explicit resolution of overloaded Java methods</h4>
<tt>js> x = "23"</tt>
<br><tt>23</tt>
<br><tt>js> java.lang.Math.abs(x)</tt>
<br><tt>The choice of static Java method java.lang.Math.abs matching JavaScript
argument types (string) is ambiguous.</tt>
<br><tt>Candidate methods are:</tt>
<br><tt> long abs(long)</tt>
<br><tt> float abs(float)</tt>
<br><tt> double abs(double)</tt>
<br><tt> int abs(int)</tt>
<br><tt>js> abs = java.lang.Math["abs(int)"]</tt>
<p><tt>function abs(int)() {</tt>
<br><tt> [native code]</tt>
<br><tt>}</tt>
<p><tt>js> abs(x)</tt>
<br><tt>23</tt>
<h4>
Public Method/field enumeration</h4>
<tt>js> out = java.lang.System.out</tt>
<br><tt>java.io.PrintStream@2980f5</tt>
<br><tt>js> for (m in out) print(m)</tt>
<br><tt>println</tt>
<br><tt>print</tt>
<br><tt>checkError</tt>
<br><tt>close</tt>
<br><tt>flush</tt>
<br><tt>write</tt>
<br><tt>wait</tt>
<br><tt>notifyAll</tt>
<br><tt>notify</tt>
<br><tt>toString</tt>
<br><tt>equals</tt>
<br><tt>hashCode</tt>
<br><tt>getClass</tt>
<br><tt>js> for (m in java.lang.String) print(m)</tt>
<br><tt>copyValueOf</tt>
<br><tt>valueOf</tt>
<h4>
'instanceof' and 'in' operators</h4>
<tt>js> s = new java.lang.String("foop")</tt>
<br><tt>foop</tt>
<br><tt>js> s instanceof java.lang.Class</tt>
<br><tt>false</tt>
<br><tt>js> s instanceof java.lang.Object</tt>
<br><tt>true</tt>
<br><tt>js> "valueOf" in s</tt>
<br><tt>true</tt>
<br><tt>js> "NoSuchThing" in s</tt>
<br><tt>false</tt>
<h4>
Applying JavaScript string methods to Java strings</h4>
<tt>js> s = new java.lang.String("The rain in Spain falls mainly on my
head.")</tt>
<br><tt>The rain in Spain falls mainly on my head.</tt>
<br><tt>js> s.match(/Spain.*my/)</tt>
<br><tt>Spain falls mainly on my</tt>
<h4>
Applying JavaScript array methods to Java arrays</h4>
<tt>js> s = new java.lang.String("JavaScript")</tt>
<br><tt>JavaScript</tt>
<br><tt>js> c = s.toCharArray()</tt>
<br><tt>[C@298aef</tt>
<br><tt>js> c.reverse()</tt>
<br><tt>[C@298aef</tt>
<br><tt>js> new java.lang.String(c)</tt>
<br><tt>tpircSavaJ</tt>
<br>
</body>
</html>