Home   Info   DevZone   Wiki  
UsersWeb  |  MainWeb  |  InfoWeb  |  DevZoneWeb  |  SupportWeb
StefansAPIStructureProposal ] [ not logged in ] [ Web: Imported ] goto:  options
[ get info on or edit ] login or new user ] [ list of topics, hubs & nodes, or recent changes ]

An API Structure Proposal

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:

Requirements

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

Description

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.

Design rules for org.jos.api

You may have wondered why we use abstract classes rather than interfaces. The reason is extensibility. (We can't think about extensibility early enough! This has to be done before JOS is first released.)

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:

How to use the API

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

To come

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.

Any questions?

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


Nice design Stefan. This is quite similar to the Facade pattern and the AbstractFactory pattern. I will read those again and see if there is anything more we can take from there. In the meanwhile why the Josxxx? That is similar to MS's CObject both are a bad idea!
Yes, please see if there is anything we can add from the book (where can I get it?). The "JosXXX" naming convention is introduced so that you can immediately tell if and where JOS classes are used. It also helps reduce name clashes. Any other thoughts on this?

--StefanReich, 7-Apr-98


Stefan, The concept of Packages have been created to handle name clashing issues in a real nice way. I dont think we need to qualify all our classes by the josXXX thing since they will be unique inside org.jos.api.XXX

VivekVenugopalan 10 Apr 98


Stefan,

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


Content of these pages are owned and copyrighted by the poster.
Hosted by: