   Copyright (C) 1998-2002, 2004, 2005 Free Software Foundation, Inc.

GNU Classpath Hacker's Guide
****************************

This file contains important information you will need to know if you
are going to write an interface between GNU Classpath and a Virtual
Machine.

   This document is incomplete, as we are still in alpha with the
interface.

1 Introduction
**************

The Classpath Project's ambition to be a 100% clean room implementation
of the standard Java class libraries cannot be fulfilled without some
level of integration with the Virtual Machine, the underlying machinery
that actually runs Java.

   There are several VMs out there, here is a small list.

   * Japhar (http://www.hungry.com/old-hungry/products/japhar/) Japhar
     was the first VM to use GNU Classpath.  Today you can see that
     sort of relationship in the source tree which denotes several
     Japhar specific files as a reference implementation of those
     pieces.  This VM has been primarily tested against Linux and lacks
     garbage collections, a JIT, and suffers recently from slow
     development.

   * Intel's Open Runtime Platform
     (http://www.intel.com/research/mrl/orp/) Intel surprised us not
     long ago with the release of this rather advanced VM that uses GNU
     Classpath for a set of class libraries and works on Linux and
     Windows 2000.  As of June, 2004, it does not appear that ORP is
     under active development.

   * SableVM (http://www.sablevm.org/) SableVM is a robust, extremely
     portable, efficient, and specifications-compliant Java Virtual
     Machine that aims to be easy to maintain and to extend. It
     features a state-of-the-art, efficient interpreter engine. Its
     source code is very accessible and easy to understand, and has
     many robustness features that have been the object of careful
     design.

   * Kaffe (http://www.kaffe.org) Kaffe is an advanced VM and together
     with its own class libraries provides a Java 1.1 compatible
     environment.

   * Electrical Fire (http://www.mozilla.org/projects/ef) The
     Electrical File VM continues to be listed as a Mozilla project
     though development has been somewhat quiet.  A number of concepts
     from EF were expected at one point to be rolled into Japhar, but
     that development has not occurred as of yet.

   * LaTTe (http://latte.snu.ac.kr/) This VM project so far supports
     only Sun UltraSparc processors using the proprietary Solaris 2.5.1
     or higher operating system.  LaTTe was derived from Kaffe but
     claims a number of improvements.

   * GNU Compiler for Java (GCJ) (http://gcc.gnu.org/java/) This is a
     portable, optimizing, ahead-of-time compiler for the Java
     Programming Language. It can compile Java source code directly to
     native machine code, Java source code to Java bytecode (class
     files), and Java bytecode to native machine code. Compiled
     applications are linked with the GCJ runtime, libgcj which is
     based on the GNU Classpath code, which provides the core class
     libraries, a garbage collector, and a bytecode interpreter.
     libgcj can dynamically load and interpret class files, resulting
     in mixed compiled/interpreted applications.  GCJ is part of the
     GNU Compiler Collection (GCC (http://gcc.gnu.org/)).  On March 6
     2000 the libgcj and GNU Classpath projects were officially merged
     and there is active work on merging all the classes between the
     projects.  Licensed under GPL+exception, just as GNU Classpath is.

   * Kissme (http://kissme.sourceforge.net/) This is a free Java
     Virtual Machine that is being developed on GNU/Linux and can run
     console Java applications.  Kissme also provides support for
     orthogonally persistent Java.

   * JamVM (http://jamvm.sourceforge.net/) A simple, small bytecode
     interpreter that works out-of-the-box with pure GNU Classpath; it
     is emerging as the preferred platform for quickly testing a new
     build of GNU Classpath.  Licensed under the GPL.

   * Jikes RVM (http://oss.software.ibm.com/jikesrvm) A free runtime
     environment for Java, written in Java.  Works out-of-the-box with
     pure GNU Classpath.  Features an optimizing JIT.  Runs on the x86
     and PowerPC architectures, on the AIX, Linux, and Mac OS/X
     operating systems.  Licensed under the CPL (Common Public
     License).  Extensively documented.  Actively developed as of June,
     2004.

   In the past integration efforts were focused mainly on Japhar with
an eye towards getting Electrical Fire to work.  Most information
contained in this document is gleaned from these efforts. Recently more
work has been done on getting gcj, orp and kissme to work out of the
box with GNU Classpath but there is much to do before that becomes a
reality.

2 Initialization
****************

The order of initialization, as far as I can tell, doesn't matter just
yet.  However, when we move to 1.2 support, it probably will matter, so
we'll have a note in here at that time.

   The initialization order is currently documented in the
`Runtime.java' source file.

3 Classpath Hooks
*****************

The primary method of interaction between Classpath and the VM is via
the helper classes, which are named after the relevant core library
class, but include an additional `VM' prefix.  The library classes from
Classpath call out to these to get certain VM-specific dirty work done.
A reference copy of each VM class exists.  The majority consist of a
series of static methods, some of which are simply declared `native',
and some which provide a default implementation.  VMs may either use
these as is, or create their own local variations.  When using the
default implementations, the VM is responsible for implementing any of
the code marked as `native' which corresponds to functionality they
wish their VM to provide.  When using their own versions of the
classes, VM implementors may choose to change the mix of native and
non-native methods from that below, so as to best suit their
implementation.

3.1 `java.lang'
===============

`java.lang' is the core Java package, being imported automatically by
all classes.  It includes basic classes as `Object' and `String'.  A VM
must implement at least some parts of this package in order to become
operable.

3.1.1 `java.lang.VMClass'
-------------------------

The core class, `java.lang.Class', and the corresponding VM class,
`java.lang.VMClass', provide two main functions within GNU Classpath.

  1. For basic VM operation, `java.lang.Class' provides the link between
     the Java-based representation of a class it embodies and the VM's
     own internal structure for a class.  See VM Hooks.

  2. As far as the user is concerned, the main function of
     `java.lang.Class' is as an entry point to the reflection
     facilities, and so it also provides this functionality, backed by
     the VM class.

   This VM class lists the following methods, organized by the version
of the Java specification in which they occur.  All are `native', unless
otherwise specified, and pertain to reflection.  As a result, the VM
only needs to implement these methods in order to provide reflection
support, and then only to the degree required.

   * 1.0
        * `isInterface(Class)' - This is simply a property test, and
          matches the presence of an appropriate flag within the class
          file.

        * `getName(Class)' - Returns the fully-qualified name of the
          class.

        * `getSuperclass(Class)' - Returns a `Class' instance which
          represents the superclass.  Again, the class file contains an
          element directly relating to this.  `null' is returned for
          primitives, interfaces and `Object'.

        * `getInterfaces(Class)' - Same as the above, but the
          implemented or extended interfaces rather than the
          superclass.  An empty array should be returned, rather than
          `null'.

        * `getDeclaredClasses(Class,boolean)' - Returns the internal
          classes this instance declares directly.  The flag determines
          whether or not the VM should filter out non-public classes.

        * `getDeclaredFields(Class,boolean)' - The same for fields.

        * `getDeclaredMethods(Class,boolean)' - And for methods.

        * `getDeclaredConstructors(Class,boolean)' - And constructors.

        * `getClassLoader(Class)' - Returns the `ClassLoader' instance
          which is responsible for the specified class.

        * `forName(String)' - The VM should create a `Class' instance
          corresponding to the named class.  As noted in VM Hooks,
          the internal content of the instance is the
          responsibility of the VM.

        * `isArray(Class)' - Another property test, corresponding to a
          class file flag.

        * `initialize(Class)' - The VM should initialize the class
          fully, if it has not already done so.

        * `loadArrayClass(String,ClassLoader)' - This is called if
          `forName' returns `null' and the string specifies an array
          class.  The specified array class should be loaded with the
          supplied class loader.

        * `throwException(Throwable)' - The VM should throw the supplied
          checked exception, without declaring it.

   * 1.1
        * `isInstance(Class,Object)' - This is a reflection-based
          equivalent of the `instanceof' operator.

        * `isAssignableFrom(Class,Class)' - Mainly a shorthand for the
          above, removing the need to create an instance to test
          assignability.

        * `isPrimitive(Class)' - Returns true if this class is simply a
          representation of one of the primitive types: `boolean',
          `byte', `char', `short', `int', `long', `float', `double' and
          `void'.

        * `getComponentType(Class)' - Produces a `Class' instance which
          represents the type of the members of the array the class
          instance represents.  Classes which don't represent an array
          type return `null'.

        * `getModifiers(Class,boolean)' - Returns an integer which
          encodes the class' modifiers, such as `public'.  Again, this
          relates to information stored in the class file.

        * `getDeclaringClass(Class)' - Returns the class that declared
          an inner or member class, or `null' if the instance refers to
          a top-level class.

3.1.2 `java.lang.VMObject'
--------------------------

`VMObject' is the bridge between the low level `Object' facilities such
as making a clone, getting the class of the object and the wait/notify
semantics.  This is accomplished using the following `native' methods.

   * `getClass(Object)' - Returns the `Class' instance for the object.
     `Class' objects are produced by the VM, as described in VM Hooks.

   * `clone(Cloneable)' - The VM should produce a low-level clone of the
     specified object, creating a field-by-field shallow copy of the
     original.  The only difference between the two is that the new
     object should still be `finalizable', even if the original is not.

   * `notify(Object)' - The VM should choose one of the threads waiting
     for a lock on the specified object arbitrarily, and wake it.  If
     the current thread does not currently hold the lock on the object,
     then an `IllegalMonitorStateException' should be thrown.

   * `notifyAll(Object)' - Same as the above, but all threads are
     awakened.

   * `wait(Object,long,int)' - The VM should set the current thread
     into a waiting state, which persists until it receives a notify
     signal or the specified time (in milliseconds and nanoseconds) is
     exceeded.  The nanoseconds restriction may be ignored if such
     granularity is not available, and a `IllegalMonitorStateException'
     should be thrown if the current thread doesn't own the object.

3.1.3 `java.lang.VMClassLoader'
-------------------------------

`VMClassLoader' provides methods for defining and resolving core and
primitive classes, as well as handling resources, packages and
assertions.  The class is a mixture of `native' methods and Java-based
implementations, with some of the latter being _stubs_.

   * Native Methods
        *
          `defineClass(ClassLoader,String,byte[],int,int,ProtectionDomain)'
          - The VM should create a `Class' instance from the supplied
          byte array.

        * `resolveClass(Class)' - Resolve references to other classes
          in the supplied class.

        * `loadClass(name,boolean)' - Load a class using the bootstrap
          loader.

        * `getPrimitiveClass(char)' - The VM should provide a `Class'
          implementation for one of the primitive classes.  The
          supplied character matches the JNI code for the primitive
          class e.g. `B' for byte and `Z' for boolean.

   * Java Methods
        * `getResource(String)' - The default implementation calls
          `getResources' and returns the first element in the returned
          enumeration, or `null' if there are no elements.

        * `getResources(String)' - By default, this compiles a list of
          URLs via the boot class path.  Any matching files within a
          zip file are added, and directories on the boot class path
          are automatically converted to file URLs that refer to join
          the directory with the resource name (whether or not it
          actually exists).

        * `getPackage(String)' - Always returns null, which may be
          suitable if the VM does not wish to return a `Package'
          implementation. Otherwise, it may be necessary to make this a
          `native' method.

        * `getPackages()' - As with the last, a default stub
          implementation exists (returning an empty array) which may be
          replaced if support is required.

        * `defaultAssertionStatus()' - A stub which can be implemented
          by VMs providing assertion support.  At present, it always
          returns `true'.

        * `packageAssertionStatus()' - Much the same status as the
          above.  The method should return a map converting package
          names to boolean status values.  The stub implementation
          provides an empty map.

        * `classAssertionStatus()' - Same as the last, but for classes.

        * `getSystemClassLoader()' - The default calls `ClassLoader' to
          create a new auxillary class loader with a system and
          extension class loader.  The VM may wish to replace it if it
          wishes to supply its own custom system class loader.

3.1.4 `java.lang.VMSystem'
--------------------------

`VMSystem' handles the default I/O streams, provides access to the
system clock and environment variables and provides methods for
`System.arraycopy' and the `identityHashCode' of an `Object'.  It
consists of `native' methods, but the default implementation also
provides some helper methods to simplify stream creation.

   * Native Methods
        * `arraycopy(Object,int,Object,int,int)' - The VM should copy a
          specified number of array objects from one array to another,
          with appropriate checks for compatible typing, available
          elements and space.  The VM should be able to perform this
          more efficiently using native code and direct memory
          manipulation than would have been achieved by using Java.

        * `identityHashCode(Object)' - This is the hashcode for
          `Object', which relates to the actual location of the object
          in memory.

        * `setIn(InputStream)' - Set the system input stream.

        * `setOut(PrintStream)' - Set the system output stream.

        * `setErr(PrintStream)' - Set the system error stream.

        * `currentTimeMillis()' - Gets the system time in milliseconds.

        * `getenv(String)' - Returns the value of the specified
          environment variable.

   * Java Methods
        * `makeStandardInputStream()' - Helps provide the functionality
          of `System.in' by wrapping the appropriate file descriptor in
          a buffered file input stream.  VMs may choose to create the
          stream from the descriptor differently rather than using this
          method.

        * `makeStandardOutputStream()' - Helps provide the
          functionality of `System.out' by wrapping the appropriate
          file descriptor in a buffered file output stream.  VMs may
          choose to create the stream from the descriptor differently
          rather than using this method.

        * `makeStandardErrorStream()' - Helps provide the functionality
          of `System.err' by wrapping the appropriate file descriptor
          in a buffered file output stream.  VMs may choose to create
          the stream from the descriptor differently rather than using
          this method.

   Classpath also provides native implementations of

   * `setIn(InputStream)'

   * `setOut(PrintStream)'

   * `setErr(PrintStream)'

   * `currentTimeMillis()'

   * `getenv(String)'

   making a VM implementation optional.

3.1.5 `java.lang.VMThrowable'
-----------------------------

`VMThrowable' is used to hold the VM state of a throwable, created
either when a `Throwable' is created or the `fillInStackTrace()' method
is called (i.e. when the actual stack trace is needed, as a lot of
exceptions are never actually used).  The actual class has two `native'
methods, one (`fillInStackTrace()') being a method of the class used to
obtain instances, and the other an instance method, `getStackTrace()'.
   * `fillInStackTrace(Throwable)' - The VM should return the current
     execution state of the `Throwable' in the form of a `VMThrowable'
     instance.  The VM may also return `null' if it does not support
     this functionality.

   * `getStackTrace()' - This is used to create a real
     `StackTraceElement' array for the exception, using the state data
     stored during creation of the instance.

3.1.6 `java.lang.VMCompiler'
----------------------------

`VMCompiler' provides an interface for VMs which wish to provide JIT
compilation support.  The default implementation is simply a series of
stubs. The property, `java.compiler', should point to a library
containing the function `java_lang_Compiler_start()' if such support is
to be provided.

   * `compileClass(Class)' - Invoke the compiler to compile the specific
     class, returning `true' if successful.

   * `compileClasses(String)' - The compiler should compile the classes
     matching the specified string, again returning `true' on success.

   * `command(Object)' - The object represents a command given to the
     compiler, and is specific to the compiler implementation.

   * `enable' - Enable the operation of the compiler.

   * `disable' - Disable compiler operation.

3.1.7 `java.lang.VMDouble'
--------------------------

`VMDouble' provides native support for the conversion and parsing of
doubles.

   * `doubleToLongBits(double)' - Converts the double to the IEEE 754
     bit layout, collapsing NaNs to `0x7ff8000000000000L'.

   * `doubleToRawLongBits(double)' - Same as the above, but preserves
     NaNs.

   * `longBitsToDouble(long)' - This is the inverse of the last method,
     preserving NaNs so that the output of one can be fed into the
     other without data loss.

   * `toString(double,boolean)' - Converts the double to a string,
     giving a shorter value if the flag `isFloat' is `true', indicating
     that the conversion was requested by `java.lang.Float' rather than
     `java.lang.Double'.

   * `initIDs' - Used by JNI-based solutions to initialize the cache of
     the static field IDs.  The default `VMDouble' implementation has a
     static initializer which loads the JNI library and calls this
     method.

   * `parseDouble' - Turn the string into a usable double value.

   Classpath provides native implementations of all these, making VM
implementation optional.

3.1.8 `java.lang.VMFloat'
-------------------------

`VMFloat' provides native support for the conversion of floats.

   * `floatToIntBits(float)' - Converts the float to the IEEE 754 bit
     layout, collapsing NaNs to `0x7fc00000'.

   * `floatToRawIntBits(float)' - Same as the above, but preserves NaNs.

   * `intBitsToFloat(int)' - This is the inverse of the last method,
     preserving NaNs so that the output of one can be fed into the
     other without data loss.

   Classpath provides native implementations of all these, making VM
implementation optional.

3.1.9 `java.lang.VMProcess'
---------------------------

`VMProcess' handles the execution of external processes.  In the
default implementation, threads are spawned and reaped by
`ProcessThread'.  A constructor creates a new `VMProcess', which
extends rather than complements `Process', using an array of arguments,
an array of environment variables and a working directory.  The
instance maintains system input, output and error streams linked to the
external process.  Three `native' methods are used, and implementations
are provided for all three by Classpath, making VM implementation
optional.  These use the POSIX functions, `fork()', `waitpid()' and
`kill()'.

   * `nativeSpawn(String[],String[],File)' - The VM should create a new
     process which uses the specified command-line arguments,
     environment variables and working directory.  Unlike the other two
     methods, this method is linked to an instance, and must call
     `setProcessInfo()' with the results before returning.

   * `nativeReap()' - This is called to perform a reap of any zombie
     processes, and should not block, instead returning a boolean as to
     whether reaping actually took place.

   * `nativeKill(long)' - The VM should terminate the specified PID.

3.1.10 `java.lang.VMRuntime'
----------------------------

The `VMRuntime' class provides a series of native methods which divulge
information about the runtime or invoke certain operations.  This
includes retrieving the amount of available memory, and scheduling the
garbage collector.  There are two exceptions: the `enableShutdownHooks'
method, which allows the VM to put in its own shutdown hooks when
`Runtime.addShutdownHook()' is first invoked, and
`exec(String[],String[],File)' which spawns an external process.  These
are Java-based static methods instead.  The first is simply a stub by
default, while the second simply links to the functionality of
`VMProcess' (and should be changed if a different `Process'
implementation is used).

   * `availableProcessors()' - Returns the number of processors
     available to the VM.

   * `freeMemory()' - Returns the amount of memory the VM has available
     on the heap for allocating.

   * `totalMemory()' - Returns the size of the heap.

   * `maxMemory()' - Returns the maximum memory block the VM will
     attempt to allocate.  May be simply `Long.MAX_VALUE' (8 exabytes!)

   * `gc()' - Allows users to explicitly invoke the garbage collector.
     This is a suggestion to the VM, rather than a command, and the
     garbage collector should run anyway _without_ it being invoked.

   * `runFinalization()' - Like the above, but related to the
     finalilzation of objects rather than the garbage collector.

   * `runFinalizationForExit()' - Called immediately prior to VM
     shutdown in order to finalize all objects (including `live' ones)

   * `traceInstructions(boolean)' - This turns on and off the optional
     VM functionality of printing a trace of executed bytecode
     instructions.

   * `traceMethodCalls(boolean)' - This turns on and off the optional
     VM functionality of printing a trace of methods called.

   * `runFinalizersOnExit(boolean)' - A toggleable setting for running
     the finalization process at exit.

   * `exit(int)' - The VM should shutdown with the specified exit code.

   * `nativeLoad(String,ClassLoader)' - Attempts to load a file,
     returning an integer which is non-zero for success.  Nothing
     happens if the file has already been loaded.

   * `mapLibraryName(String)' - The VM should map the system-independent
     library name supplied to the platform-dependent equivalent (e.g. a
     `.so' or `.dll' file)

3.1.11 `java.lang.VMString'
---------------------------

`VMString' is responsible for handling interned strings.  If two strings
are equal (using the `equals()' method), then the results of calling
the `intern()' method on each of them makes them equal (using `==').
Thus, the same string object is always returned by `intern' if the two
strings are equal.  The default implementation is Java-based and
implements `intern(String)' by maintaining a `WeakHashMap' which links
the strings to their `WeakReference'.  A new mapping is created for
each new string being `intern'ed.  A VM may implement this differently
by implementing this method, which is `static' and the only one in
`VMString'.

3.1.12 `java.lang.VMThread'
---------------------------

`VMThread' provides the link between Java's threads and the platform
threading support.  A `VMThread' is created via a private constructor
and linked to a `Thread' instance.  This occurs when the `Thread'
instance is started by the static `create(Thread,long)' method (the
second argument requests a certain stack size, usually zero).  The
thread itself is executed via the `run()' method, which handles any
problems with the running of the thread and its eventual death.

   `VMThread' provides the following accessors and mutators for
accessing the thread state via `VMThread',

   * `getName()'

   * `setName(String)'

   * `getPriority()'

   * `setPriotity(int)'

   * `isDaemon()'

   all of which refer to the `Thread' instance. `setPriority(int)' also
calls the appropriate native method.  `stop(Throwable)' similarly wraps
a native method, merely adding in a check for the state of the thread.

   The default implementation also provides Java-based implementations
of `join(long,int)', `sleep(long,int)' and `holdsLock(Object)'.  `join'
and `sleep' simply wait for the appropriate amount of time, with `join'
additionally waiting for the thread instance to become `null'.
`holdsLock' simply checks if an object is locked by the current thread
by trying to invoke the `notify' method, and catching the failing
exception if this is not the case.

   The remainder of the class is a series of `native' methods, some of
which are mandatory for VM implementation and others which provide
optional or deprecated functionality.

   * Mandatory Instance Methods
        * `start(long)' - The VM should create the native thread and
          start it running using the `run' method of the `VMThread'
          instance on which this method is called.

        * `interrupt()' - The VM should interrupt the running thread and
          throw an appropriate exception.

        * `isInterrupted()' - Checks the interrupted state of the
          thread.

        * `suspend()' - The thread should be suspended until resumed.

        * `resume()' - The thread should be resumed from its suspended
          state.  This pair of methods are deprecated, due to the
          possibility of a deadlock occuring when a thread with locks
          is suspended.

        * `nativeSetPriority(int)' - Called by `setPriority' to allow
          the setting to flow down to the native thread.

        * `nativeStop(Throwable)' - The VM should stop the thread
          abnormally and throw the specified exception.  This is
          clearly deprecated, due to the ambiguous state an
          abruptly-stopped thread may leave.

   * Mandatory Class Methods
        * `currentThread()' - Return a reference to the thread currently
          being executed.

        * `yield()' - The VM should allow some other thread to run.
          The current thread maintains its locks even though it stops
          executing for the time being.

        * `interrupted()' - A shortcut to obtaining the interrupted
          state of the current thread.

   * Other Methods
        * `countStackFrames()' - Returns a count of the number of stack
          frames in the thread.  This depends on the deprecated method
          `suspend()' having returned true, and is thus deprecated as a
          result.

3.2 `gnu.classpath'
===================

The `gnu.classpath' package provides Classpath-specific functionality,
primarily relating to the features in `java.lang'.  At present, this
includes the context of a class (the stack) and the system properties.

3.2.1 `gnu.classpath.VMStackWalker'
-----------------------------------

`VMStackWalker' provides access to the class context or stack.  The
default implementation consists of a `native' `static' method,
`getClassContext()', which obtains the class context, and two helper
methods which obtain the calling class (the 3rd element in the context
array) and its class loader, respectively.

   * `getClassContext()' - The VM should return an array of `Class'
     objects, each of which relates to the method currently being
     executed at that point on the stack.  Thus, the first item (index
     0) is the class that contains this method.

   * `getCallingClass()' - A Java-based helper method which returns the
     `Class' object which contains the method that called the method
     accessing `getCallingClass()'.

   * `getCallingClassLoader()' - Like the last, but returning the class
     loader of the class.

3.2.2 `gnu.classpath.VMSystemProperties'
----------------------------------------

`VMSystemProperties' allows the VM to hook into the property creation
process, both before and after the system properties are added by GNU
Classpath.  The default implementation assumes that the VM will add its
properties first, by making the pre-initialisation method `native', and
that the Classpath properties may then be altered by a Java-based
post-initialisation method.

   As these methods are called as part of the bootstrap process,
caution should be used as to what classes are used, and properties
should only be set using `Properties.setProperty()'.  Specifically, I/O
classes should be avoided at this early stage.

   * `preInit(Properties)' - Allows the VM to add properties _before_
     the Classpath properties are added. The default implementation
     includes a full list of properties that _must_ be added by the VM,
     but additional VM-specific ones may also be added.

   * `postInit(Properties)' - Same as the last, but called after the
     Classpath properties have been added.  The main purpose of this is
     to allow the VM to alter the properties added by GNU Classpath to
     suit it.

3.3 java.util
=============

The `java.util' VM hooks provide links between the mix of functionality
present in that package, which includes collections, date and time
handling and parsing.  At present, there is only one hook, which
connects GNU Classpath to the timezone information provided by the
underlying platform.

3.3.1 `java.util.VMTimeZone'
----------------------------

`VMTimeZone' joins `TimeZone' to the platform timezone information via
the static method, `getDefaultTimeZoneId()'.  The VM hook is expected
to return a `TimeZone' instance that represents the current timezone in
use by the platform.  The default implementation provides this
functionality for POSIX or GNU-like systems, and VMs that want this
functionality can keep this implementation and implement the native
method, `getSystemTimeZoneId()'.  This method is only called when
obtaining the timezone name from the `TZ' environment variable,
`/etc/timezone' and `/etc/localtime' all fail.  This fallback mechanism
also means that a system which doesn't provide the above three methods,
but does provide a timezone in string form, can still use this
implementation.

3.4 java.io
===========

The `java.io' package is heavily reliant on access to the I/O facilities
of the underlying platform.  As far as its VM hooks go, they provide two
areas of functionality to GNU Classpath, these being

   * File and directory queries and manipulation

   * Serialization of objects

   The first corresponds directly to most of the `File' class, while
the latter underlies the functionality provided by the
`ObjectInputStream' and `ObjectOutputStream'.  More low-level I/O is
provided by java.nio.

3.4.1 `java.io.VMFile'
----------------------

`VMFile' allows GNU Classpath's `File' representations to probe and
modify the file system using the native functions of the platform.  The
default implementation (which consists of both a `VMFile' class and the
native methods) is primarily UNIX-centric, working with POSIX functions
and assuming case-sensitive filenames, without the restriction of the
8.3 format.  It consists mainly of `static' `native' methods, with a
few Java helper methods.  The native methods represent the file as a
string containing its path, rather than using the object itself.

   * Native Methods
        * `lastModified(String)' - The native method should return a
          `long' value that represents the last modified date of the
          file.

        * `setReadOnly(String)' - Sets the file's permissions to read
          only, in whichever way this is realised by the platform.

        * `create(String)' - Create the named file.

        * `list(String)' - The native method opens the named directory,
          reads the contents and returns them as a Java `String' array.

        * `renameTo(String,String)' - Renames the first file to the
          second.

        * `length(String)' - Returns a `long' value representing the
          file size.

        * `exists(String)' - Tests for the existence of the named file
          or directory.

        * `delete(String)' - Deletes the file or directory.

        * `setLastModified(String,long)' - Change the last modified
          time.

        * `mkdir(String)' - Creates the named directory.

        * `isFile(String)' - Tests that the named path references a
          file.

        * `canWrite(String)' - Tests that the file can be written to.
          This method is `synchronized', so the object is locked during
          the check.

        * `canRead(String)' - Complement of the last method.

        * `isDirectory(String)' - Tests that the named path references
          a directory.

   * Java Helper Methods
        * `canWriteDirectory(File)' - Checks that the directory can be
          written to, by trying to create a temporary file in it.

        * `listRoots()' - Returns the root of a GNU filesystem i.e. `/'
          in an array.

        * `isHidden(String)' - Checks whether the file starts with `.',
          which is how files are hidden on UNIX-style systems.

        * `getName(String)' - Pulls the actual filename from the end of
          the path, by breaking off the characters after the last
          occurrence of the platform's file separator.

        * `getCanonicalForm(String)' - This converts a UNIX path to its
          canonical form by removing the `.' and `..' sections that
          occur within.

3.4.2 `java.io.VMObjectInputStream'
-----------------------------------

This class consists of two methods which provide functionality used in
deserializing an object.  `currentClassLoader()' provides the first
user-defined class loader from the class context (see
gnu.classpath.VMStackWalker,) via a `PrivilegedAction'.
`allocateObject(Class,Class,Constructor)' is a `native' method (a
reference implementation is provided) which creates an object but calls
the constructor of another class, which is a superclass of the object's
class.

3.4.3 `java.io.VMObjectStreamClass'
-----------------------------------

`VMObjectStreamClass' is a series of `static' `native' methods that
provide some of the groundwork for `ObjectStreamClass' and
`ObjectStreamField'.  `hasClassInitializer(Class)' works with the
former, and checks for the presence of a static initializer.  The
remaining methods are of the form `setXXXNative(Field,Object,XXX)' and
support `ObjectStreamField'.  One exists for each of the main types
(boolean, float, double, long, int, short, char, byte and object) and
is used to set the specified field in the supplied instance to the
given value.

   A default implementation is provided for all of them, so a VM
implementation is optional.

3.5 java.security
=================

The `java.security' package provides support for Java's security
architecture.  At present, `VMAccessController' represents the sole VM
hook for this.

3.5.1 `java.security.VMAccessController'
----------------------------------------

The `AccessController' is used to perform privileged actions.  Its hook
class, `VMAccessController', maintains the `AccessControlContext' and
the default implementation is purely Java-based.  The VM may choose to
replace this with their own.  The methods in the reference version are
as follows:

   * `pushContext(AccessControlContext)' - Adds a new context to the
     stack for the current thread.  This is called before a privileged
     action takes place.

   * `popContext()' - Removes the top context from the stack.  This is
     performed after the privileged action takes place.

   * `getContext()' - Either derives a context based on the
     `ProtectionDomain's of the call stack (see the next method) or
     returns the top of the context stack.

   * `getStack()' - Provides access to the call stack as a pair of
     arrays of classes and method names.  The actual implementation
     returns an empty array, indicating that there are no permissions.

3.6 java.net
============

The `java.net' package is heavily reliant on access to the networking
facilities of the underlying platform.  The VM hooks provide information
about the available network interfaces, and access to lookup facilities
for network addresses.

3.6.1 `java.net.VMInetAddress'
------------------------------

`VMInetAddress' is a series of `static' `native' methods which provide
access to the platform's lookup facilities.  All the methods are
implemented by GNU Classpath, making VM implementation optional, and
are as follows:

   * `getLocalHostname()' - Wraps the `gethostname' function, and falls
     back on `localhost'.

   * `lookupInaddrAny()' - Returns the value of `INADDR_ANY'.

   * `getHostByAddr(byte[])' - Looks up the hostname based on an IP
     address.

   * `getHostByName(String)' - The reverse of the last method, it
     returns the IP addresses which the given host name resolves to.

3.6.2 `java.net.VMNetworkInterface'
-----------------------------------

`VMNetworkInterface' currently consists of a single `static' `native'
method, `getInterfaces()', which retrieves the network interfaces
available on the underlying platform as a `Vector'.  The current GNU
Classpath implementation is a native stub.

3.7 java.nio
============

The `java.nio' package is part of the New I/O framework added in Java
1.4.  This splits I/O into the concepts of _buffers_, _charsets_,
_channels_ and _selectors_, and `java.nio' defines the buffer classes.
As far as native and VM code is concerned, the new package needs
support for low-level efficient buffer operations.

3.7.1 `java.nio.VMDirectByteBuffer'
-----------------------------------

A `ByteBuffer' maintains a buffer of bytes, and allows it to be
manipulated using primitive operations such as `get', `put', `allocate'
and `free'.  A direct buffer avoids intermediate copying, and uses
native data which shouldn't be manipulated by a garbage collector.  The
VM class consists of `static' `native' methods, all of which are given
default implementations by GNU Classpath.

   * `init()' - Creates an instance of an appropriate
     `gnu.classpath.RawData' class.  This class is not garbage
     collected, is created natively and is used in the other methods to
     reference the buffered data.

   * `allocate(int)' - Allocates the memory for the buffer using
     `malloc' and returns a reference to the `RawData' class.

   * `free(RawData)' - Frees the memory used by the buffer.

   * `get(RawData,int)'  - Returns the data at the specified index.

   * `get(RawData,int,byte[],int,int)' - Copies a section of the data
     into a byte array using `memcpy'.

   * `put(RawData,int,byte)' - Puts the given data in the buffer at the
     specified index.

   * `adjustAddress(RawData,int)' - Adjusts the pointer into the buffer.

   * `shiftDown(RawData,int,int,int)' - Moves the content of the buffer
     at an offset down to a new offset using `memmove'.

3.8 java.nio.channels
=====================

Channels provide the data for the buffers with the New I/O packages.
For example, a channel may wrap a file or a socket.  The VM hooks, at
the moment, simply allow the channels to be accessed by `java.io'
streams.

3.8.1 `java.nio.channels.VMChannels'
------------------------------------

`VMChannels' provides the methods that create the channels or streams.
The default implementation is in pure Java and simply wraps the
channels in standard I/O classes from `java.io'.

   * `createStream(Class,Channel)' - Creates a `FileChannel' which
     wraps an instance of the specified stream class, created by
     reflection.  This method is private, and is used by the other two.

   * `newInputStream(ReadableByteChannel)' - Wraps the channel in a
     `FileInputStream'.

   * `newOutputStream(WritableByteChannel)' - Wraps the channel in a
     `FileOutputStream'.

3.9 gnu.java.nio
================

The `gnu.java.nio' class provides Classpath implementations of the
interfaces provided by `java.nio'.  The VM classes provide the native
support necessary to implement _pipes_ and _selectors_.

3.9.1 `gnu.java.nio.VMPipe'
---------------------------

`VMPipe' provides the native functionality for a uni-directional pipe
between a source and a destination (sink) channel.  It consists of one
`static' `native' method, `init(PipeImpl,SelectorProvider)', the
reference implementation of which is currently a native stub.  Ideally,
this should initialise the pipe at the native level.

3.9.2 `gnu.java.nio.VMSelector'
-------------------------------

A `Selector' selects between multiple `SelectableChannel's based on
their readiness and a key set.  The VM hook for the Classpath
implementation of this is `VMSelector', and this allows the actual
`select()' operation to be performed.  This is represented by the
`static' `native' method, `select(int[],int[],int[],long)', and a
default implementation of this is provided.

   Some of the classes you implement for the VM will need to call back
to package-private methods in Classpath:

   * `java.lang.ThreadGroup.addThread(Thread)' Call this method from
     `Thread' when a new `Thread' is created, to add it to the group.

   * `java.lang.ThreadGroup.removeThread(Thread)' Call this method from
     `Thread' when a `Thread' is stopped or destroyed.

4 VM Hooks
**********

VMs need to do some dirty work; there are some things in the VM that
unfortunately are dependent on the internal structure of various
classes.  This is a guide to all of the things the VM itself needs to
know about classes.

   Some of the core classes, while being implemented by GNU Classpath,
provide space for state (in the form of a `vmdata' object) to be stored
by the VM, and can not be constructed normally.

   * java.lang.Class

   * java.lang.ClassLoader

   The default implementations of some VM classes also follow this
methodology, when it is intended that most VMs will keep the default.

   * java.lang.VMThread

   * java.lang.VMThrowable

   Several core classes must be completely implemented by the VM for
Classpath to work, although reference implementations are provided.
These classes are:

   * java.lang.reflect.Constructor

   * java.lang.reflect.Method

   * java.lang.reflect.Field

   The following issues are of note;

   * `java.lang.Class'
     The GNU Classpath implementation of `java.lang.Class' provides an
     object for storing the internal state of the class maintained by
     the VM.  This is the only known place where this matters.  The
     class is constructed with this data by the VM.  Some VMs do not
     create the `Class' object at the point where the class is defined;
     instead, they wait until a `Class' object is actually used.

   * Array Classes
     When you are creating an array class, you should set the
     `ClassLoader' of the array class to the `ClassLoader' of its
     component type.  Whenever you add a class to a `ClassLoader', you
     need to notify the `ClassLoader' and add the new `Class' to its
     internal cache of classes.  To do this, call
     `ClassLoader.addVMCreatedClass(Class)'.  _Note: this is written in
     anticipation of 1.2 support and does not apply just yet._

   * Primordial Class Loader
     When the primordial class loader loads a class, it needs to tell
     Classpath what it has done in order for security stuff to work
     right.  To do this, call the static method
     `ClassLoader.newPrimordialClass(Class)'.

     Even the first few core classes need to do this; in order to do it,
     simply call this method _after_ the initial class loading has been
     done.  No harm will come, as long as you follow the guidelines in
     the Initialization section.

     _Note: this is written in anticipation of 1.2 support and does not
     apply just yet._

   * Top-level Exception Handler
     Exceptions take care of themselves in Classpath; all you need to
     do in the top-level exception handler is call
     `Throwable.printStackTrace()'.

   * Security and Traces
     There will eventually be a feature in the 1.2 security that keeps
     the `AccessController' from having to evaluate _all_ of the
     `ProtectionDomain's every time a security check is made.  I think
     a common case is a single method doing a lot of things that
     require security checks.  However, I don't want to bog down the
     method stack too much, so this feature of the VM will have the
     `AccessController' for a thread calling out to the VM to tell it
     how high it was on the stack when it made the last security
     request.  Every time the stack goes lower than that number, the VM
     will decrement the number.  The `AccessController' will remember
     what the accumulated protection status was at every stack level
     (an `AccessControlContext') and use that aggregated information to
     do the check.  I am not sure, however, whether the savings are
     substantial enough to outweigh the integer check and set after
     every method call.  I will investigate.

   * Threading
     I figured I'd put this here because a VM guy might be wondering
     about it.  We implement `ThreadGroup', but that class is almost
     entirely VM-independent.  The root `ThreadGroup', a static field
     called `ThreadGroup.root', should be initialized by Classpath, but
     if you wish to reinitialize it yourself, there should be no harm.

5 JNI Implementation
********************

Classpath comes with its own implementation of `jni.h'.  This file can
be customized by the VM in a few ways, by defining macros that affect
the interpretation of the file.  These macros are all intended for use
by a VM which uses GNU Classpath and which wants to use a single copy
of `jni.h' for both internal and external use.

   * _CLASSPATH_VM_JNI_TYPES_DEFINED Some VMs like to define JNI
     "object" types in a special way.  If this macro is defined, the
     Classpath `jni.h' will avoid defining these types.  By default,
     these types are defined in `jni.h'.  The full list of types and
     macros treated this way is: `jobject', `jclass', `jstring',
     `jthrowable', `jweak', `jarray', `jobjectArray', `jbyteArray',
     `jshortArray', `jintArray', `jlongArray', `jbooleanArray',
     `jcharArray', `jfloatArray', `jdoubleArray', `JNIEnv', `JavaVM',
     `JNI_TRUE' (macro), `JNI_FALSE' (macro).

   * _CLASSPATH_VM_INTERNAL_TYPES_DEFINED If the VM has its own
     definitions for `jfieldID' and `jmethodID', then it should define
     this macro.  Otherwise, `jni.h' will provide definitions for these
     types.

   * _CLASSPATH_JNIIMPEXP Three functions -
     `JNI_GetDefaultJavaVMInitArgs', `JNI_CreateJavaVM', and
     `JNI_GetCreatedJavaVMs' - must be marked as `JNIIMPORT' when seen
     by user code, but most likely should be marked as `JNIEXPORT' when
     defined in the VM implementation.  This macro can be defined to
     one or the other by the VM as appropriate.  If this macro is not
     defined, it defaults to `JNIIMPORT'.

   * _CLASSPATH_JNIENV_CONTENTS A VM can add fields to the `JNIEnv'
     structure by defining this to be a sequence of field declarations.

6 Miscellaneous VM Requirements
*******************************

Classpath places a few requirements on the VM that uses it.

6.1 JNI Version
===============

Classpath currently uses only JNI 1.1, except for one JNI 1.2 function
in the JNI Invocation API: GetEnv().  And GetEnv() is only used in the
"portable native sync" code, so it's only actually used by Jikes RVM
and Kaffe.

   A future direction will probably be to require that all VMs provide
JNI 1.2.  If this poses problems, please raise them on the classpath
mailing list.

6.2 VM Threading Model
======================

Classpath's AWT peers use GTK+.  GTK+ uses GLIB.  Normally, Classpath
will initialize GLIB's "gthreads" to use the platform's native
threading model(1)

   If the Java runtime doesn't use the native threading model, then you
will want Classpath to tell GLIB to use the Java threading primitives
instead.  Otherwise, GLIB would use the native threading model to
perform operations such as creating thread-local data, and that just
doesn't work on systems (such as Kaffe in some configurations, and such
as Jikes RVM) that use m:n threading.

   Historically, enabling the Java threading primitives had been done at
build time, by configuring classpath with the `--portable-native-sync'
option.  This had bad consequences, though - it meant that the prebuild
GNU Classpath package distributed with Debian GNU/Linux would not be
usable with VMs that could otherwise have used it.  Instead, we
encourage the use of the Java system property
`gnu.classpath.awt.gtk.portable.native.sync'.  A VM that wants GLIB to
use the Java threading primitives should modify
`VMRuntime.insertSystemProperties()' to include code like the following:

     static void insertSystemProperties(Properties P)
   ...
     P.put("gnu.classpath.awt.gtk.portable.native.sync", "true");

   So, the configure option `--portable-native-sync' is deprecated, and
should go away in a subsequent release of GNU Classpath.

   ---------- Footnotes ----------

   (1) The native threading model is pthreads on Linux and AIX, the two
platforms Classpath currently runs on.

6.3 Boot Library Path Property
==============================

As of GNU Classpath 0.15 a system property named
`gnu.classpath.boot.library.path' can be set by the VM to specify the
directories which contain GNU Classpath's native libraries. Usually
this value is given at configuration time and is then hardcoded in the
VM. However for development purposes it is handy to switch to another
installation by overriding the properties' value on the command line.

   A VM that does not support this feature can simply ignore the
property.

   For compatibility reasons we suggest to set the default value of
`java.library.path' to the value of the `LD_LIBRARY_PATH' environment
if it exists on your platform.