During the last weeks, different ideas came up about what should be the "official JOS API". By "JOS API" I mean the classes and interfaces that are exposed to applications running under JOS. These are two approaches I heard of:
Of course, JOS must support the whole set of Java core classes. But this isn't enough: Many system-near and some not-so-system-near applications require additional functions that java.* doesn't provide.
This is clearly better than the approach above. There is now no limitation for the functionality JOS can provide. But this approach has other severe problems:
Because either approach falls short, I want to propose a different API system. This system matches the following requirements:
(JOS 1 and JOS 2 are imaginary JOS distributions; the point is that JOS 1 is released before JOS 2.)
My idea is to let applications access java.* and org.jos.api.*. (How access to other classes is prohibited is a question for the SecurityGroup.)
The contents of org.jos.api is governed by some rules that will be described now.
private static Jos<i>SomeFunctions</i> implementation = null; public static Jos<i>SomeFunctions</i> getImplementation() { if (implementation == null) String name = "org.jos.api.Jos<i>SomeFunctions</i>"; implementation = (Jos<i>SomeFunctions</i>) org.jos.Registry.getAPIImplementation(name, API_VERSION); return implementation; } public static final org.jos.util.Version API_VERSION = new org.jos.util.Version(1, 0); // or any other version number
API_VERSION
.
Imagine we would want to extend a certain JOS 1 interface in JOS 2. If we added methods to the interface, JOS 1 implementations of that interface wouldn't work in JOS 2 (since they don't implement the new methods).
So I think abstract classes are a much better choice. The only disadvantage I can see is that a given class can only inherit from one abstract class, while it can implement multiple interfaces. But in the presence of (anonymous) inner classes, this drawback is already less important.
For the first release of JOS, this additional rule applies:
For all subsequent releases, these additional rules apply:
An application that wants to use the API executes the following code:
Jos<i>SomeFunctions</i> someFunc = Jos<i>SomeFunctions</i>.getImplementation(); if ( implementation == null || !implementation.getVersion.isLaterThanOrEqualTo(1, 4) ) // the version I need // perform an alternative operation, // do nothing or throw an exception else someFunc.doSomethingForMe(someFunc.giveMeAValue());
As you can see, very easy! :-)
There's one more thing... What if a JOS 2 application runs under JOS 1? Assume a new method has been included in JosSomeFunctions for JOS 2. Then the application could also check the API version:
if (!Jos<i>SomeFunctions</i>.getAPIVersion().isLaterThanOrEqualTo(2, 0)) // error, error Jos<i>SomeFunctions</i> someFunc = Jos<i>SomeFunctions</i>.getImplementation(); if (implementation == null || !implementation.getVersion.isLaterThanOrEqualTo(1, 4)) // the version I need // perform an alternative operation, // do nothing or throw an exception else someFunc.doSomethingForMe(someFunc.giveMeAValue());
The problem here is subtle. The class verifier checks every reference to a method for its validity. So it would check someFunc.giveMeAValue(); given that giveMeAValue() is a JOS 2 method, the check fails in a JOS 1 environment. When is that check performed? The Sun VM does it when the surrounding method is executed for the first time. So in the example above, the check would fail.
There is an easy workaround: place the API version check in a separate method that is called before the method that access the actual API functions. But this workaround depends on the class verifier's specific behavior (I don't think Sun has specified when methods should be verified).
A better solution is this: Upgrade JOS 1 by loading the JOS 2 APIs. Since the API classes are not allowed to import foreign packages and are backwards-compatible, the replacement can be done.
You could bundle the JOS 2 APIs with the application and let the installation script load them into the system.
How to write an API implementation
Writing an API implementation is almost as simple as using the API.
First, of course you have to extend the abstract class and implement all the necessary methods:
package wherever; import org.jos.api.*; class Jos<i>SomeFunctions</i>Impl extends Jos<i>SomeFunctions</i> { public static org.jos.util.Version getImplementedVersion() { return new org.jos.util.Version(1, 0); } [...] }
The class doesn't even need to be public. It is attached to the API through a factory. A factory is an object that knows where the implementation for some or all org.jos.api classes is to be found. This is one way to register the API implementation:
import org.jos.Registry; Registry.SimpleAPIImplementationFactory factory = new Registry.SimpleAPIImplementationFactory(); String name = "org.jos.api.Jos<i>SomeFunctions</i>"; factory.addEntry(name, "wherever.Jos<i>SomeFunctions</i>Impl"); Registry.registerAPIImplementationFactory(factory);
This code has to be executed some time before the corresponding API is used for the first time.
The factory stores strings and not actual references to the classes to delay their loading as long as possible (for some classes may not be needed at all).
I intend to bundle a jos-api.jar archive that is updated regularly and holds the API framework as well as any org.jos.api classes that are developed by any of you or by myself.
I in no way want to "control" the JOS APIs. I just volunteer to bundle the API releases. Having such releases will be increasingly important as more JOS applications are developed.
I hope you don't have too many questions (because I hope to have expressed my concept clearly). But I do hope that you have many comments - agreement or disagreement.
--StefanReich, 31-Mar-98
--StefanReich, 7-Apr-98
VivekVenugopalan 10 Apr 98
It has been difficult to explain the difference between the Java API, your API proposal and a SmartAPI. Starting with some of the issues presented here in your proposal, I am planning to build a map. We have good reasons to stop following Sun Microsystem's example of the Java API and standard extensions. What are those reasons? All members of the JOS project need to discuss this.
The issues of API are fundamental to the strengths and weaknesses of the finished operating system. This discussion is at the heart of JOS. -- GilbertHerschberger (20 July 1999).