зеркало из https://github.com/mozilla/gecko-dev.git
419 строки
16 KiB
HTML
419 строки
16 KiB
HTML
<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.05 [en] (WinNT; I) [Netscape]">
|
|
<TITLE>README for LiveConnect</TITLE>
|
|
</HEAD>
|
|
<BODY>
|
|
|
|
<H2>
|
|
Introduction</H2>
|
|
This is the README file for the JavaScript LiveConnect Version 2 ("LC2")
|
|
implementation. It consists of build conventions and instructions,
|
|
source code conventions, and a brief file-by-file description of the source.
|
|
|
|
<P>This document assumes basic familiarity with JSRef, the reference implementation
|
|
of JavaScript, and with the LiveConnect technology (LiveConnect allows
|
|
JavaScript and Java virtual machines to be connected. It enables
|
|
JavaScript to access Java fields, invoke Java methods and makes it possible
|
|
for Java to access JavaScript object properties and evaluate JavaScript.
|
|
More information on LiveConnect can be found by searching the index on
|
|
Netscape's <A HREF="http://developer.netscape.com">DevEdge site</A>.)
|
|
|
|
<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 a Java Virtual Machine (JVM) that implements
|
|
the Java Native Interface (JNI), as specified by JavaSoft. It then
|
|
compiles a small "shell" program and links that with the library to make
|
|
an interpreter that can be used interactively and with test scripts.
|
|
|
|
<P><I>Scott Furman, 4/8/98</I>
|
|
<H2>
|
|
Compatibility</H2>
|
|
Unlike this release, all previous versions of LiveConnect appeared only
|
|
as a component of Netscape Navigator, not as a standalone module.
|
|
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" and this most recent release
|
|
as "LC2". The following incompatibilities with LC1 are known:
|
|
<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 on both LC1
|
|
and LC2.</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.
|
|
<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 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.
|
|
With the Netscape and Sun JVMs, it is possible to change the behavior of
|
|
an LC1 program by changing the order that Java methods appear in a source
|
|
file, thus changing the method enumeration order. Hence, the Java
|
|
method chosen when there is more than one compatible method may vary depending
|
|
on the JVM.</LI>
|
|
|
|
|
|
<P>A future release of LiveConnect will provide a new algorithm for overloaded
|
|
Java method resolution that is both independent of the JVM used and more
|
|
likely than LC1 to invoke the method that the developer expects.
|
|
<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>
|
|
New Features</H2>
|
|
Several minor features have been added to this release of LiveConnect.
|
|
These features were not available in the versions of LiveConnect that were
|
|
integrated with Netscape Naviagtor versions 4.x and earlier.
|
|
<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>
|
|
Build conventions</H2>
|
|
Update your JVM's <TT><FONT SIZE=+1>CLASSPATH</FONT></TT> to point to the
|
|
<TT><FONT SIZE=+1>liveconnect/classes</FONT></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><FONT SIZE=+1>initialization
|
|
error: Can't load class netscape/javascript/JSObject</FONT></TT>" when
|
|
starting a LiveConnect debug build.
|
|
|
|
<P>By default, LiveConnect is not re-entrant. To enable multi-threaded
|
|
execution, define the <TT><FONT SIZE=+1>JS_THREADSAFE</FONT></TT> cpp macro
|
|
and flesh out the stubs and required headers in jslock.c/.h. See
|
|
the JS API docs for more. JSRef must also be built with <TT><FONT SIZE=+1>JS_THREADSAFE</FONT></TT>.
|
|
<BR>
|
|
<UL><B>Windows</B>
|
|
<UL>
|
|
<LI>
|
|
Use MSDEV5.0 with the <TT><FONT SIZE=+1>LiveConnectShell.dsw</FONT></TT>
|
|
project file.</LI>
|
|
|
|
<LI>
|
|
You must first build the JS runtime, js32.dll, by using the normal JSRef
|
|
build procedure.</LI>
|
|
|
|
<LI>
|
|
Identify the JVM that you are linking against by setting the <TT><FONT SIZE=+1>JDK</FONT></TT>
|
|
environment variable to point to the top-level JDK directory, e.g. <TT><FONT SIZE=+1>D:\jdk1.1.5</FONT></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>
|
|
The output files (DLLs and executables) are placed in the <TT><FONT SIZE=+1>js/ref/liveconnect/Debug</FONT></TT>
|
|
or <TT><FONT SIZE=+1>js/ref/liveconnect/Release</FONT></TT> directories.</LI>
|
|
|
|
<LI>
|
|
The LiveConnect-enabled shell is named <TT><FONT SIZE=+1>lcshell.exe</FONT></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.</LI>
|
|
|
|
<LI>
|
|
Use any Java compiler to compile the java source files in the <TT><FONT SIZE=+1>js/ref/liveconnect/classes/netscape/javascript</FONT></TT>
|
|
directory.</LI>
|
|
</UL>
|
|
|
|
|
|
<P><B>Mac OS</B>
|
|
<UL>
|
|
<LI>
|
|
Using CodeWarrior Pro 3 is recommended. With some modifications,
|
|
the project files can be made to work with CodeWarrior Pro 2. The
|
|
CodeWarrior project files are <TT><FONT SIZE=+1>js/ref/liveconnect/macbuild/LiveConnect.mcp</FONT></TT>,
|
|
<TT><FONT SIZE=+1>js/ref/liveconnect/macbuild/LiveConnectShell.mcp</FONT></TT>,
|
|
and<TT><FONT SIZE=+1> js/ref/macbuild/JSRef.mcp</FONT></TT>.</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 CIncludes & Libraries from the SDK's Interfaces&Libraries
|
|
directory to <TT><FONT SIZE=+1>js/ref/liveconnect/macbuild/JavaSession</FONT></TT>.</LI>
|
|
|
|
<LI>
|
|
Build the JavaScript test application, <TT><FONT SIZE=+1>JSRef</FONT></TT>,
|
|
with <TT><FONT SIZE=+1>js/ref/macbuild/JSRef.mcp</FONT></TT>.</LI>
|
|
|
|
<LI>
|
|
Build the LiveConnect test application, <TT><FONT SIZE=+1>LiveConnectShell</FONT></TT>,
|
|
with <TT><FONT SIZE=+1>js/ref/liveconnect/macbuild/LiveConnectShell.mcp</FONT></TT>.</LI>
|
|
|
|
<LI>
|
|
Build <TT><FONT SIZE=+1>liveconnect.jar</FONT></TT> with <TT><FONT SIZE=+1>js/ref/liveconnect/macbuild/LiveConnect.mcp</FONT></TT>.</LI>
|
|
|
|
<LI>
|
|
Make an alias to <TT><FONT SIZE=+1>liveconnect.jar</FONT></TT> and place
|
|
it in "<TT><FONT SIZE=+1>{SystemFolder}Extensions:MRJ Libraries:MRJClasses</FONT></TT>".</LI>
|
|
</UL>
|
|
<B>Unix</B>
|
|
<UL>
|
|
<LI>
|
|
Use vendor cc or <A HREF="ftp://prep.ai.mit.edu/pub/gnu">gcc</A> for compiling,
|
|
and use gmake for building.</LI>
|
|
|
|
<LI>
|
|
Makefile has only been tested on Solaris 5.5. To build on other platforms
|
|
you must add a .mk file to the ref/liveconnect/config subdir.</LI>
|
|
</UL>
|
|
</UL>
|
|
|
|
<H2>
|
|
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>
|
|
DLL entry points have their return type expanded within a PR_PUBLIC_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 PR_STATIC_CALLBACK (if the function otherwise would be static to hide
|
|
its name) or PR_CALLBACK (this macro takes no type argument; it should
|
|
be used after the return type and before the function name).</LI>
|
|
</UL>
|
|
|
|
<H2>
|
|
The LiveConnect API</H2>
|
|
All public LiveConnect entry points and callbacks are documented in jsjava.h,
|
|
the header file that exports those functions.
|
|
<BR>
|
|
<H2>
|
|
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</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>
|
|
|
|
<BR>
|
|
</BODY>
|
|
</HTML>
|