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.

Copyright (C) 1998-2002, 2004, 2005, 2006, 2007 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.

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://jikesrvm.sourceforge.net/) 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.

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.

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.

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.

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, boolean, ClassLoader) -- 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.  The supplied class loader is recorded as that which loaded the class, and the boolean specifies whether or not to run the class initializer.

       * 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.

  * 1.5

       * isSynthetic(Class) -- Returns true if the flags for this class mark it as synthetic.

       * isAnnotation(Class) -- Returns true if the flags for this class mark it as an annotation.

       * isEnum(Class) -- Returns true if the flags for this class mark it as an enumeration.

       * getSimpleName(Class) -- Returns the simple name of the class. A default implementation is provided, but a more efficient version may instead be provided by the VM.

       * getCanonicalName(Class) -- Returns the canonical name of the class.  A default implementation is provided, but a more efficient version may instead be provided by the VM.

       * getEnclosingClass(Class) -- Returns the immediately enclosing class (null for a top-level class).

       * getEnclosingConstructor(Class) -- Returns the constructor which immediately encloses the supplied class.

       * getEnclosingMethod(Class) -- Returns the method which immediately encloses the supplied class.

       * getClassSignature(Class) -- Returns the generic signature of the class or null if there isn't one.

       * isAnonymousClass(Class) -- Returns true if the class is an anonymous class.

       * isLocalClass(Class) -- Returns true if the class is an local class.

       * isMemberClass(Class) -- Returns true if the class is an member class.

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.

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 auxiliary 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.

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.

       * getenv() -- Returns a list of `name=value' pairs which correspond to the environment variables.

  * 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.

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.

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.

java.lang.VMDouble
------------------

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

  * doubleToRawLongBits(double) -- Converts the double to the IEEE 754 bit layout, preserving 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.

java.lang.VMFloat
-----------------

VMFloat provides native support for the conversion of floats.

  * floatToRawIntBits(float) -- Converts the float to the IEEE 754 bit layout, preserving 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.

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,boolean) -- 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.  The boolean argument maps to the redirectErrorStream property of java.lang.ProcessBuilder.  When true, the output and error streams are merged.

  * 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.

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)

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 interned. A VM may implement this differently by implementing this method, which is static and the only one in VMString.

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 occurring 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.

       * getState() -- Returns the VM's impression of the current state of the thread.  The applicable states are supplied by the State enumeration in java.lang.Thread.

  * 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.

java.lang.VMMath
----------------

The VMMath class provides a series of native methods for some of the mathematical functions present in java.lang.Math. Classpath provides a default implementation of these which maps the functions to those provided by fdlibm.  VM implementors are welcome to replace this with more efficient implementations, as long as the accuracy contract of these methods, specified in java.lang.Math, is maintained.

  * 1.0

       * sin(double) -- Returns the sine value for the given angle.

       * cos(double) -- Returns the cosine value for the given angle.

       * tan(double) -- Returns the tangent value for the given angle.

       * asin(double) -- Returns the arc sine value for the given angle.

       * acos(double) -- Returns the arc cosine value for the given angle.

       * atan(double) -- Returns the arc tangent value for the given angle.

       * atan2(double,double) -- Returns the arc tangent of the ratio of the two arguments.

       * exp(double) -- Returns the exponent raised to the given power.

       * log(double) -- Returns the natural logarithm for the given value.

       * sqrt(double) -- Returns the square root of the value.

       * pow(double,double) -- Returns x to the power of y.

       * IEEEremainder(double,double) -- Returns the IEEE 754 remainder for the two values.

       * ceil(double) -- Returns the nearest integer >= the value.

       * floor(double) -- Returns the nearest integer <= the value.

       * rint(double) -- Returns the nearest integer or the even one if the distance between the two is equal.

  * 1.5

       * cbrt(double) -- Returns the cube root of the value.

       * cosh(double) -- Returns the hyperbolic cosine value for the given angle.

       * expm1(double) -- Returns the exponent of the value minus one.

       * hypot(double,double) -- Returns the hypotenuse corresponding to x and y.

       * log10(double) -- Returns the base 10 logarithm of the given value.

       * log1p(double) -- Returns the natural logarithm of the value plus one.

       * sinh(double) -- Returns the hyperbolic sine value for the given angle.

       * tanh(double) -- Returns the hyperbolic tangent value for the given angle.

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.

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.

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.

gnu.classpath.Unsafe
--------------------

The Unsafe class provides access to some low-level unsafe operations as required by the addition of the java.util.concurrent classes.  These focus on direct memory access to the fields within the VM and providing atomic update methods.

  * objectFieldOffset(Field) -- Provides the caller with the memory offset of a particular field.

  * compareAndSwap*(Object,long,*,*) -- One of these methods is provided for each of int, long and Object (hence the *s).  The value of a field pointed to by the given Object and offset is compared with the first value and replaced with the second if they are the same.  The reason for this method is to make this change operation atomic.

  * put/get*(Object,long,*) -- These are like the last set of methods, handling integers, longs and Objects, but the field is always changed on a put.  Different methods are provided for different semantics. Ordered variants perform a lazy put, in that the change does not immediately propogate to other threads, while the others provide volatile or 'normal' semantics.

  * arrayBaseOffset(Class) and arrayIndexScale(Class) -- These two methods allow an array class to be traversed by pointer arithmetic, by gaining the address of the first element and then scaling appropriately for the later ones.

  * park(boolean,long) and unpark(Thread) -- These methods block and unblock threads respectively, with an optional timeout being provided for the blocking.  unpark is unsafe as the thread may have been destroyed by native code.

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.

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.

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.

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.

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.

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.

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

The java.security package provides support for Java's security architecture.

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 ProtectionDomains 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.

java.security.VMSecureRandom
----------------------------

The VMSecureRandom class is used to provide access to cryptographically secure random numbers.  The default implementation of the class runs eight threads that increment counters in a tight loop, and XORs each counter to produce one byte of seed data. This is not very efficient, and is not guaranteed to be random (the thread scheduler is probably deterministic, after all). VM implementors should provide a version of this class, which implements the method generateSeed(byte[],int,int), so that it fills the buffer using a random seed from a system facility, such as a system entropy gathering device or hardware random number generator.  The parameters are the usual set of buffer, offset and length and the method returns the number of bytes actually generated, which may be less than that requested.

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.

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.

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.

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.

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.

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.

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.

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.

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.

gnu.java.nio.VMSelector
-----------------------

A Selector selects between multiple SelectableChannels 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.

java.lang.reflect
=================

java.lang.reflect provides the interface to Java's reflection facilities.  Via reflection, programmers can obtain type information about a particular instance at runtime or dynamically create new instances.

java.lang.reflect.VMArray
-------------------------

The VMArray class provides a hook, createObjectArray, which the VM uses to generate a new non-primitive array of a particular class and size.  The default implementation simply passes the job down to the standard JNI function, NewObjectArray.

gnu.java.lang
=============

gnu.java.lang provides VM interfaces for the GNU implementations of features in java.lang.  Currently, this includes the implementation of instrumentation.

gnu.java.lang.VMInstrumentationImpl
-----------------------------------

The gnu.java.lang.VMInstrumentationImpl and gnu.java.lang.InstrumentationImpl classes provide an implementation of the java.lang.instrument.Instrument interface. A InstrumentationImpl object should be created by the VM when agents are given in the command line (see the java.lang.instrument package documentation). The VM has to set the static field VMClassLoader.instrumenter to this object. The VM should implement the static native methods of the VMInstrumentationImpl class.

  * isRedefineClassesSupported() -- Returns true if the JVM supports class redefinition.

  * redefineClasses() -- Gives a set of classes with new bytecodes. The VM must redefine the classes by reading the new bytecodes.

  * getAllLoadedClass() -- Returns an array of all loaded classes.

  * getInitiatedClass() -- Returns an array of all classes loaded by a specific class loader.

  * getObjectSize() -- Gives the size of an object.

Instrumentation allows to modify the bytecode of a class before it gets read by the VM. In GNU Classpath, the ClassLoader.defineClass method calls the VMClassLoader.defineClassWithTransformers method which first checks if VMClassLoader.instrumenter is null. If it's the case, it directly calls VMClassLoader.defineClass. If it's not the case, the method calls at first the InstrumentationImpl.callTransformers method, which calls each transformer registered to the InstrumentationImpl object and returns a new bytecode array. Then, it calls the VMClassLoader.defineClass method with this new bytecode array.

The second use of instrumentation is to redefine a class after it has been loaded by the VM. This is done in the Java application by calling the Instrumentation.redefineClasses method of the standard interface on a Instrumentation object. The InstrumentationImpl.redefineClasses method calls the VMInstrumentationImpl.redefineClasses native method which must be implemented by the VM. The implementation should call the InstrumentationImpl.callTransformers method.

gnu.java.lang.management
========================

gnu.java.lang.management provides the VM interfaces for the GNU implementations of the management beans.

gnu.java.lang.management.VMRuntimeMXBeanImpl
--------------------------------------------

The gnu.java.lang.management.RuntimeMXBeanImpl provides an implementation of the java.lang.management.RuntimeMXBean interface, and is supported by VM functionality in the form of gnu.java.lang.management.VMRuntimeMXBeanImpl.  This provides a series of methods, which should be implemented by the virtual machine in order to provide the required information for the bean.  The VM methods are generally representative of information that is only available from the virtual machine, such as the command-line arguments it was given at startup.

The methods are as follows:

  * (getInputArguments()) -- The VM should supply a String array containing each of the command-line arguments, excluding those that are directed at the main() method.  The reference implementation expects this to be a native method.

  * (getName()) -- The VM developer should choose an appropriate name for the virtual machine.  This name can be instance-specific e.g. it can include things like the process identifier or host name of the machine, which only apply to the current running instance.  Thus, the intention is that this name refers to the entity that the other information refers to, rather than the VM in general.  The reference implementation supplies a default concatenation of the VM name and version.

  * (getStartTime()) -- This should return the number of milliseconds at which the virtual machine was started. The uptime property of the bean is provided relative to this value.  Again, the reference implementation also expects this method to be native.

The virtual machine also needs to provide either the sun.boot.class.path or java.boot.class.path property in order to support the optional boot class path retrieval functionality.

gnu.java.lang.management.VMClassLoadingMXBeanImpl
-------------------------------------------------

The gnu.java.lang.management.ClassLoadingMXBeanImpl provides an implementation of the java.lang.management.ClassLoadingMXBean interface, and is supported by VM functionality in the form of gnu.java.lang.management.VMClassLoadingMXBeanImpl.  This provides a series of methods, which should be implemented by the virtual machine in order to provide the required information for the bean.  Implementing this bean requires the VM to monitor when classes are loaded and unloaded, and provide the option of verbose class loading output.

The methods are as follows:

  * (getLoadedClassCount()) -- This should return the number of classes that are currently loaded by the VM.

  * (getUnloadedClassCount()) -- This should return the number of classes that have been loaded by the VM, but have since been unloaded.

  * (isVerbose()) -- This should return true or false, depending on whether verbose class loading output is turned or not, respectively.

  * (setVerbose(boolean)) -- This should allow the verbose class loading output to be turned on and off.

gnu.java.lang.management.VMThreadMXBeanImpl
-------------------------------------------

The gnu.java.lang.management.ThreadMXBeanImpl provides an implementation of the java.lang.management.ThreadMXBean interface, and is supported by VM functionality in the form of gnu.java.lang.management.VMThreadMXBeanImpl.  This provides a series of methods, which should be implemented by the virtual machine in order to provide the required information for the bean.  Implementing this bean requires the VM to monitor thread-related statistics such as how often the blocked and waiting states have been entered, as well as additional optional support for time and contention monitoring.

Optional support is determined by the following properties:

  * gnu.java.lang.management.CurrentThreadTimeSupport -- This property should be present if the VM supports monitoring the time used by the current thread.  If time monitoring for all threads is supported, this need not be provided.

  * gnu.java.lang.management.ThreadTimeSupport -- This property should be present if the VM supports monitoring the time used by all threads.

  * gnu.java.lang.management.ThreadContentionSupport -- This property should be present if the VM supports thread contention monitoring.

  * gnu.java.lang.management.MonitorUsageMonitoringSupport -- This property should be present if the VM supports the monitoring of object monitor usage.

  * gnu.java.lang.management.OwnableSynchronizerUsageMonitoringSupport -- This property should be present if the VM supports the monitoring of ownable synchronizer usage.

In addition, the property gnu.java.lang.management.ThreadTimeInitallyEnabled may be set to the String value, "true", if time monitoring is enabled at startup.

The methods are as follows:

  * (findDeadlockedThreads()) -- This should return an array of thread identifiers which match threads involved in deadlock cycles (where each thread is waiting to obtain a lock held by one of the others) on object monitors or ownable synchronizers.  This is specified as a native method in the reference implementation, and is optional.  It is only called when the VM supports ownable synchronizer monitoring.

  * (findMonitorDeadlockedThreads()) -- This should return an array of thread identifiers which match threads involved in deadlock cycles (where each thread is waiting to obtain a lock held by one of the others) on object monitors.  This is specified as a native method in the reference implementation.

  * (getAllThreads()) -- This should return an array of all live threads and set the filled variable to the number found.  A default implementation is provided.

  * (getAllThreadIds()) -- This should return an array of all live thread identifiers.  An implementation is provided against getAllThreads() by default.

  * (getCurrentThreadCpuTime()) -- This should return the approximate number of nanoseconds of CPU time the current thread has used.  This is an optional native method, which is used by VMs supporting time monitoring.

  * (getCurrentThreadUserTime()) -- This should return the approximate number of nanoseconds of user time the current thread has used.  This is an optional native method, which is used by VMs supporting time monitoring.

  * (getDaemonThreadCount()) -- This should return the number of live daemon threads.  A default implementation is provided, based on getAllThreads().

  * (getLockInfo(ThreadInfo)) -- This is an optional native method called when the VM supports ownable synchronizer usage monitoring and the user has requested information for a particular thread.  The supplied ThreadInfo object should be filled out with an array of LockInfo objects, providing details on each lock.

  * (getMonitorInfo(ThreadInfo)) -- This is an optional native method called when the VM supports object monitor usage monitoring and the user has requested information for a particular thread.  The supplied ThreadInfo object should be filled out with an array of MonitorInfo objects, providing details on each lock.

  * (getPeakThreadCount()) -- The VM should maintain a record of the peak number of live threads, and return it when this method is called.  This is specified as a native method in the reference implementation.

  * (resetPeakThreadCount()) -- This should reset the record of the peak number of live threads to the current number of live threads.  This is specified as a native method in the reference implementation.

  * (getThreadCount()) -- This should return the number of live threads.  A default implementation is provided, based on getAllThreads().

  * (getThreadCpuTime(long)) -- This should return the approximate number of nanoseconds of CPU time the specified thread has used.  This is an optional native method, which is used by VMs supporting time monitoring.

  * (getThreadUserTime(long)) -- This should return the approximate number of nanoseconds of CPU time the specified thread has used.  This is an optional native method, which is used by VMs supporting time monitoring.

  * (getThreadInfoForId(long, int)) -- This return an instance of java.lang.management.ThreadInfo for the specified thread. The class includes a private constructor which VMs should use to initialise it with the appropriate values for the thread.  The second argument given here specifies the depth of the stack trace supplied on construction of the instance.  Special values are 0 (return an empty array) and Integer.MAX_VALUE (return the maximum depth possible).  This is specified as a native method in the reference implementation.

  * (getTotalStartedThreadCount()) -- This should return the total number of threads that have been started by the VM, including ones that have died.  This is specified as a native method in the reference implementation.

gnu.java.lang.management.VMMemoryMXBeanImpl
-------------------------------------------

The gnu.java.lang.management.MemoryMXBeanImpl provides an implementation of the java.lang.management.MemoryMXBean interface, and is supported by VM functionality in the form of gnu.java.lang.management.VMMemoryMXBeanImpl.  This provides a series of methods, which should be implemented by the virtual machine in order to provide the required information for the bean.  Implementing this bean requires the VM to monitor the levels of heap and non-heap memory, and provide the number of objects which are eligible for garbage collection.

The methods are as follows:

  * (getHeapMemoryUsage()) -- This should return an instance of java.lang.management.MemoryUsage with values pertaining to the heap.  A default implementation is provided, based on java.lang.Runtime's methods.

  * (getNonHeapMemoryUsage()) -- This should return an instance of java.lang.management.MemoryUsage with values pertaining to non-heap memory.

  * (getObjectPendingFinalizationCount()) -- Returns the number of objects which are no longer referenced, and which will thus be garbage collected on the next run of the garbage collector.

  * (isVerbose()) -- This should return true or false, depending on whether verbose memory management output is turned or not, respectively.

  * (setVerbose(boolean)) -- This should allow the verbose memory management output to be turned on and off.

gnu.java.lang.management.VMCompilationMXBeanImpl
------------------------------------------------

The gnu.java.lang.management.CompilationMXBeanImpl provides an implementation of the optional java.lang.management.CompilationMXBean interface, and is supported by VM functionality in the form of gnu.java.lang.management.VMCompilationMXBeanImpl.  This provides a single method for returning the number of milliseconds the virtual machine's Just-In-Time (JIT) compiler has spent compiling.  Even if a JIT compiler is available and an instance of the bean supplied, this method is still optional.

Optional support is determined by the following properties:

  * gnu.java.lang.compiler.name -- This property should specify the name of the JIT compiler.  Classpath also uses this, within java.lang.management.ManagementFactory, to determine whether a bean should be created.  If this property is set to a non-null value, a bean will be created and its getName() method will return this value.

  * gnu.java.lang.management.CompilationTimeSupport -- This property should be present if the VM supports monitoring the time spent compiling.

Time support is implemented by the following method:

  * (getTotalCompilationTime()) -- This should return the number of milliseconds the JIT compiler has spent compiling.

gnu.java.lang.management.VMMemoryPoolMXBeanImpl
-----------------------------------------------

The gnu.java.lang.management.MemoryPoolMXBeanImpl provides an implementation of the optional java.lang.management.MemoryPoolMXBean interface, and is supported by VM functionality in the form of gnu.java.lang.management.VMMemoryPoolMXBeanImpl.  Providing this interface requires implementing a number of methods for each supported pool.  These return statistics on memory usage, and, optionally, allows monitoring of when memory usage exceeds a preset threshold.

Optional support is determined by the following properties:

  * gnu.java.lang.management.CollectionUsageThresholdSupport -- This property should be present if the VM supports setting a collection usage threshold and monitoring when it is matched or exceeded.  Collection usage thresholds are related to the remaining memory usage following a garbage collection cycle.

  * gnu.java.lang.management.UsageThresholdSupport -- This property should be present if the VM supports setting a usage threshold and monitoring when it is matched or exceeded.

The methods are as follows (all take a pool name as their first parameter):

  * (getCollectionUsage(String)) -- Returns a java.lang.management.MemoryUsage object, containing the memory usage statistics following a garbage collection cycle for the specified pool.  This may also return null if the pool isn't an appropriate pool for this particular task.

  * (getCollectionUsageThreshold(String)) -- Returns the pool's collection usage threshold, if supported.

  * (getCollectionUsageThresholdCount(String)) -- Returns the number of times the specified pool has matched or exceeded its collection usage threshold, if supported.

  * (getMemoryManagerNames(String)) -- Returns a list of names of memory managers which manage the specified pool.

  * (getPeakUsage(String)) -- Returns a java.lang.management.MemoryUsage object for the peak usage level of the specified pool.

  * (getType(String)) -- Returns a string containing either "HEAP" or "NON_HEAP" which indicates the type of memory used by the specified pool.

  * (getUsage(String)) -- Returns a java.lang.management.MemoryUsage object for the current usage level of the specified pool.

  * (getUsageThreshold(String)) -- Returns the pool's usage threshold, if supported.

  * (getUsageThresholdCount(String)) -- Returns the number of times the specified pool has matched or exceeded its usage threshold, if supported.

  * (isValid(String)) -- Returns true if the pool is still in use by the virtual machine.

  * (resetPeakUsage(String)) -- Resets the peak usage levels to the current usage levels for the specified pool.

  * (setCollectionUsageThreshold(String, long)) -- Sets the pool's collection usage threshold, if supported.

  * (setUsageThreshold(String, long)) -- Sets the pool's usage threshold, if supported.

gnu.java.lang.management.VMMemoryManagerMXBeanImpl
--------------------------------------------------

The gnu.java.lang.management.MemoryManagerMXBeanImpl provides an implementation of the optional java.lang.management.MemoryManagerMXBean interface, and is supported by VM functionality in the form of gnu.java.lang.management.VMMemoryManagerMXBeanImpl.  Providing this interface requires implementing two methods (each takes the name of the manager as the first argument):

  * (getMemoryPoolNames(String)) -- Returns a list of the memory pools that the manager maintains.  A default implementation which scans the results of getMemoryManagerNames() for each pool is provided.

  * (isValid(String)) -- Returns true if the specified manager is still valid, i.e., it is still in use by the virtual machine.

gnu.java.lang.management.VMGarbageCollectorMXBeanImpl
-----------------------------------------------------

The gnu.java.lang.management.GarbageCollectorMXBeanImpl provides an implementation of the optional java.lang.management.GarbageCollectorMXBean interface, and is supported by VM functionality in the form of gnu.java.lang.management.VMGarbageCollectorMXBeanImpl.  Providing this interface requires implementing two methods (each takes the name of the garbage collector as the first argument):

  * (getCollectionCount(String)) -- Returns the number of times the specified garbage collector has run.

  * (getCollectionTime(String)) -- Returns the accumulated number of milliseconds for which the garbage collector has run.

Note that each garbage collector is also a memory manager, and so an implementation of the gnu.java.lang.management.VMMemoryManagerMXBeanImpl methods for its name should also be provided.

java.lang.management
====================

gnu.java.lang.management provides the VM interfaces for the GNU implementations of the management beans.

java.lang.management.VMManagementFactory
----------------------------------------

This VM interface provides the names of the memory pools, memory managers and garbage collectors for use by the java.lang.management.ManagementFactory in creating lists of appropriate beans for these types of managed object.

The methods are as follows:

  * (getMemoryPoolNames()) -- Returns a list of the names of the current memory pools in use by the virtual machine.

  * (getMemoryManagerNames()) -- Returns a list of the names of the current memory managers in use by the virtual machine.  This should not include those that are also garbage collectors.

  * (getGarbageCollectorNames()) -- Returns a list of the names of the current garbage collectors in use by the virtual machine.

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.

  * gnu.java.lang.management.MemoryMXBeanImpl.fireThresholdExceededNotification(String, long, long, long, long) If the monitoring of memory usage thresholds is supported, this method should be called when the normal usage of a memory pool crosses the threshold, in order to emit a notification.  Another notification should not be emitted until there is an intermittent period where the usage is again below the threshold.  The parameters are the memory pool name, the usage levels (init, used, committed and max) and the number of times the threshold has been crossed.

  * gnu.java.lang.management.MemoryMXBeanImpl.fireCollectionThresholdExceededNotification(String, long, long, long, long) If the monitoring of memory usage thresholds is supported, this method should be called when the usage of a memory pool after a garbage collection cycle crosses the threshold, in order to emit a notification.  Another notification should not be emitted until there is an intermittent period where the usage is again below the threshold.  The parameters are the memory pool name, the usage levels (init, used, committed and max) and the number of times the threshold has been crossed.

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 see 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 ProtectionDomains 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.

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.

JVMTI Implementation
********************

Classpath comes with its own implementation of jvmti.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 for use by a VM which uses GNU Classpath and which wants to use a single copy of jvmti.h for both internal and external use.

  * _CLASSPATH_VM_JVMTI_TYPES_DEFINED Some VMs like to define JVMTI ``object'' types in a special way.  If this macro is defined, the Classpath jvmti.h will avoid defining these types.  By default these types are defined in jvmti.h. The full list of types and macros treated this way is: jthread, jthreadGroup, jlocation, and jrawMonitorID.  By default jrawMonitorID is defined as an opaque pointer which must be defined by the VM.

  * _CLASSPATH_JVMTIENV_CONTENTS A VM can add fields to the jvmtiEnv structure by defining this to be a sequence of field declarations.

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

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

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 now deprecated ``portable native sync'' code.

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.

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

VM authors can implement a number of different threading models. When native code is also threaded there is the potential for one threading model to deadlock the other. The Java Native Interface Programmer's Guide and Specification (http://java.sun.com/docs/books/jni/html/other.html#29406) suggests consulting VM documentation in such situations. Classpath uses existing libraries, for example the AWT peers can use the GTK+ graphics library. As these libraries assume a different threading model, there is the potential for the native code to deadlock a VM.

The different threading models available to a VM author are:

 1. Native threads: Map a Java thread to an underlying operating system thread (normally a POSIX compatible pthread). This approach reduces the potential for deadlock as there is only one thread scheduling mechanism.

 2. Green threads 1: Green threads are threads scheduled by the VM, typically by switching swapping registers. In early VMs green threads were seen as advantageous as they didn't require the operating system to reschedule, save and swap all of a threads registers. The green thread 1 model switches thread on an externally created event, such as a timer interrupt. An example of a VM using this approach is Kaffe configured with its jthreads model.

 3. Green threads 2: The essential difference with this model is to not switch threads on an event, but at fixed points in the code being executed by the VM. Points chosen could be backward branches (loops) or method calls. This approach can be advantageous to nonconservative garbage collectors, as non-running threads would be at known points and can have fixed register maps. It can also reduce the number of registers it is necessary to swap when switching threads.

 4. M:N threading: a flaw to green threading is that it is unable to use multiple processors. M:N threading fixes this problem by running groups of green threads on multiple underlying native threads. An example of a VM using this approach is the Jikes RVM, which uses M:N threading combined with the green thread 2 model.

An example of the problem of mixing threading models is:

  * A Java thread calls a native method. The native method acquires a lock.

  * The native method calls back into the VM.

  * An event triggers the VM to reschedule the currently running thread.

  * A new VM thread, executing on the same underlying native thread, calls a native method.

  * The native method tries to acquire the lock already acquired earlier. As the lock is busy the thread waits and allows the operating system to reschedule native threads.

  * The operating system reschedules the VM thread again, but the lock is still busy and in some threading models will remain busy forever (the VM is deadlocked).

VMs that don't use the underlying operating system thread scheduling mechanism need to avoid deadlock. One now deprecated approach was to build Classpath and VMs on top of a wrapper thread library (aka portable native sync). The wrapper thread library used was GLIB's gthreads. This approach has been deprecated because:

 1. The wrapper library is only in use by some native libraries. For example, GTK+ uses the gthread library but QT does not.

 2. The wrapper library can't be in use prior to the VM starting as the VM must replace the wrapper libraries functions with its own. This prevents the VM from running as a plugin in an application that already uses the wrapper library.

An alternative approach is for the VM to detect deadlocked native code and swap Java threads off of that native thread. The VM can't, however, swap two blocked native threads that are potentially deadlocking each other on a lock. The lock will be associated with the native thread. To prevent this from happening the VM must hijack functions that operate on locks. This is done by redefining the lock functions inside the VM and configuring the linker so that it uses the VMs symbol in preference to that of the external thread support library. The VM's lock function can then reschedule Java threads if it must wait for the lock.

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.