Microsoft's Internet Explorer (IE) 4.0 has been out for a little over a week now, and the company now is shipping the 2.0 version of its Software Development Kit (SDK) for Java. According to Microsoft's Win32 Virtual Machine for Java Release Notes (see the Resources section below for links to this document and other information related to this article), the virtual machine (VM) for Java that ships with IE 4.0 is the same as the one in the new SDK. Using the Java class files that come with the SDK and comparing them to the Java class files that come with Sun's Java Development Kit (JDK) 1.1.4 release reveals exactly why Alan Baratz, president of Sun's JavaSoft division, said, "Microsoft deceptively altered key classes and inserted them into their SDK." (This was during the conference detailing Sun's October 7 announcement of Sun's suit against Microsoft alleging breach of contract. For more information on this lawsuit, see "Sun-Microsoft dispute gets ugly," in the October 1997 issue of JavaWorld.)
I have analyzed the classes and have run across seven areas that should be of great concern to developers if they want to develop solutions with Microsoft's SDK for Java that will work in other Java 1.1 certified environments. These areas of concern are:
- new classes (Hey, what's that class doing there?)
- new methods (And where did these methods and instance variables come from?)
- new variables (And where did these methods and instance variables come from?)
- modified interfaces (What about the interface changes?)
- the com.ms packages (Inside com.ms)
- missing methods (What's missing in the SDK)
- behavioral differences (And what's different)
These go far beyond the often-cited concern over Microsoft's lack of JNI and RMI support, as mentioned in my October 1997
Baratz used the word "deceptively" in Sun's announcement of the lawsuit because the (javadoc) documentation for the Java classes that comes with the SDK makes no mention of these changes. To find these differences, it is necessary to use either the ClassVue tool that comes with the SDK or manually examine the source code. Your best bet is to rely on ClassVue, as the source files provided with the SDK are not always the ones used for the generated classes. For those unfamiliar with ClassVue, the equivalent tool that comes with the JDK from Sun is javap, a class file internals examiner.
As much as I'd like to claim that what follows is an exhaustive list of changes to the SDK, it is possible that something was missed. With several items, there is a pattern -- so if you avoid similarly named things you should be okay. All of the problems identified here are in the java.lang, java.io, java.awt, java.util, and java.security packages/sub-packages.
So, what changed in each package?
- java.awt: New classes, New methods, New variables
- java.lang: New methods, New variables
- java.io: Dropped methods
- java.security: Modified interfaces
- java.util: New methods, New variables
The first set of changes in Microsoft's SDK for Java is new classes, methods, and variables that were added to the system packages. A system package, or core Java API, is anything that begins with java.* in its fully qualified class name. So, as far as new classes go, 16 new ones were added into java.awt. These are:
|Microsoft's new Java classes for AWT peers|
With the exception of the last one, all the classes are peer classes for AWT components, where a peer is the platform-specific representation of a graphical component like a button or menu. Normally, these classes would go into a different package like sun.awt.windows or sun.awt.motif. Since you aren't supposed to use them anyway, they should be easy to avoid. The
WUIPeer class also is a peer, but it supports a Microsoft-specific behavior. Stay away from that too. Additional package-private (also called friendly, for when no access specifier keyword is specified) classes were added, like
__UIMenuRoot. Because these are inaccessible outside of java.awt, you cannot directly use them.
The most commonly added method is called
getBaseName(). Thankfully, it too is package-private, although it should be just plain private. Other changes, like making
loadClassInternal() method private, instead of package private, are due to implementation differences and should have no effect on developers.
I don't mean to downplay the package-private changes that Microsoft made, but unless developers are extending the key Java class libraries themselves, they cannot access these changes. Since developers seeking cross-platform solutions know better than to inject their own changes into the key Java class libraries, this isn't an issue. (See Rule 3 of SunTest's "100% Pure Java Cookbook," referenced in the Resources section.)
The real problems appear with the public methods that Microsoft introduced:
|Public methods added into key Java libraries|
|java.awt.image.ColorModel||finalize() [was protected]|
Locale(String, String, String, int, int)
getLCID() [was private]
You will need to avoid all of the above methods, unless you want your Java programs to run only with Microsoft's environment. In addition to these new methods, you have access to three new instance variables and lots of new Locales for internationalization:
|Instance variables incorporated into Java API|
PUBLIC_DECLARED is brand new to
appWorkspace is brand new to
pData was private and is now public. As with everything else, avoid them. As far as the Locale objects go, Microsoft's environment seems to understand a few additional languages, that JavaSoft doesn't. While the intention is good, instead of using the new constants, you should create a Locale object yourself, with the necessary parameters, although not using the new Locales may require some extra work when formatting messages.
For each Locale added, there are two public classes added into the java.text.resource package. Because Sun's documentation specifically states that you should not directly call any API in text.resource, I do not view these additions as a problem.
An interface defines a partial template that a class must follow. Microsoft seems to have modified the templates of some of the security interfaces:
|Additional methods in Java security interfaces|
The way interfaces work, when you create a class that implements an interface, you define a method for each method declared in the interface. By increasing the number of methods in the interfaces, Microsoft is breaking every class that implements each original interface. If you need to create programs to work in both Microsoft and non-Microsoft environments, it is necessary to always implement the additional behavior, whenever you implement either interface in a class.
com.ms is a grouping of classes delivered with Microsoft's proposed Java implementation. All the classes within com.ms.* packages normally are inaccessible to people using Netscape Navigator/Communicator and Java 1.1 environments. If you choose to use something from a class in a com.ms.* package, more than likely you are moving outside the realm of portability. One example in which this may prove tricky for the uninformed is getting
FontMetrics from the
Toolkit class (via
getFontMetrics()). While the method signature is the same "
public FontMetrics getFontMetrics()," what you get back is an instance of
com.ms.awt.FontMetricsX. If you treat it as a
FontMetricsX object, your program will work only with the Microsoft virtual machine for Java; if you stick with
FontMetrics, then you're portable.
There is an exception to this com.ms avoidance rule though: Microsoft's Application Foundation Classes (AFC) in com.ms.ui (see Resources) are written in Java. So you can use them. However, if your users are not using IE 4.0, you will need to provide them separately.
(Until Microsoft bundles the AFC classes into something that is usable in a non-MS Java environment, providing AFC separately isn't an option as the AFC classes included with IE4 and their SDK rely on Microsoft Java VM specifics. There should soon be a bundling of the AFC classes usable in other browsers like Netscape Navigator 3.0. Watch Microsoft's website for details.)
Out of all the classes I searched, the only thing missing from Microsoft's proposed implementation of Java 1.1 is one method. Now, one missing method is still one too many, but the fact is, the missing method is relatively minor. Specifically, the
toString() method of
ByteArrayOutputStream that accepts a character encoding name as a parameter isn't present. A character encoding permits localized display of text messages. The workaround for this omission is to ask for the byte array of the stream (
toByteArray()) and then use the
String constructor that accepts an encoding name. By always taking these two steps, even with the JDK, you'll be sure your programs will work when used with Microsoft's runtime environment.
The last bunch of changes I'll be discussing here actually has nothing to do with new classes or missing methods. It has to do instead with behavior differences. Whenever a new environment comes out, you need to learn how it behaves differently from what you expect. As an example, when Netscape Navigator 3.0 beta 5 came out, the browser reported additional AWT events to programs. If your programs weren't ready for these additions, the programs didn't behave appropriately. Now, with the new SDK, it appears that kind of upheaval is once again upon us.
First and foremost, Microsoft's Win32 virtual machine for Java reports itself as Java 1.1 (notice no point anything after the second one in "1.1"). Currently, Sun is shipping the Java 1.1.4 release of the JDK. That means your favorite bug fix may not be included in the Microsoft JVM. Now, it is possible the bug fix isn't necessary because of implementation differences or it's possible that Microsoft corrected the problem on its own. However, if you glance through the source and do comparisons, you will notice obvious functional differences. If you expect the JDK behavior and don't get it, your program still needs to function appropriately.
For example, when using
java.awt.BorderLayout, if you add a component with no quadrant name, it goes in the center quadrant when run with the JDK or Java Runtime Environment (JRE). If you add a component with an illegal quadrant name, like "Top,"
BorderLayout throws an
IllegalArgumentException. On the other hand, try the same program with no quadrant name on Microsoft's environment, and the component is not displayed anywhere. (This affects the Swing JFrame component, making it unusable.) Another difference is that the
Dialog class will accept a null parent
Frame parameter for Microsoft, while the Sun JDK throws an
IllegalArgumentException. As people run more programs under IE 4.0, more of these differences will emerge.
For the more technically inclined readers, here are some details on even more changes. Other behavioral differences, some of them improvements, are invisible to developers. For example, object locking may be done at different levels, sometimes favoring one environment over the other. Hopefully, any improvements made by Microsoft will make their way back into the JDK and vice versa. There are additional performance benefits within Microsoft's environment that should be incorporated into the JDK. For example, in Microsoft's environment, if you ask to change a component color or font, it checks to see if the new value is different from the old value. If they are the same, no change is made. With Sun's environment, the change is blindly made, even when unnecessary. Lots of little modifications like these can lead to dramatic performance improvements.
It seems without question that Microsoft (and Netscape -- see the sidebar below) has made changes to key Java class libraries. Whether or not Microsoft legally can, based on a contract with Sun, is now in the court's hands. While, as a whole, the changes appear relatively minor, they are changes. If the courts say these alterations are okay because they are insignificant, what is there to stop a licensee from altering other capabilities?
Let's take a quick look at the different changes, and see where they leave developers and users:
Missing RMI and JNI support: If programs need these capabilities, they will be missed. Developers will need to deliver programs with Sun's Java Runtime Environment (JRE) to ensure a compatible environment. Hopefully, users shouldn't notice, although some programs, which would function better when run as an applet within a browser, may need to be converted into a standalone application.
Added classes, methods, and variables: For developing 100% Pure Java solutions, developers will need to avoid them. While the task is generally easy, there is no tag similar to @deprecated warning developers when they slip and use a non-portable feature. If developers aren't careful, users will notice when programs stop running or never start if run outside of a Microsoft Win32 Virtual Machine.
Added methods to interfaces: Along with the next point, this is probably one of the biggest faults. If you currently have classes that implement the modified interfaces, the likelihood of them working in Microsoft's environment are slim. You would have had to introduce methods identically named with identical functionality in order for the classes to work. Now, in order to create solutions that work in both Microsoft and non-Microsoft environments, developers need to define methods with the names and behavior introduced by Microsoft's extended interfaces. Until then, any prior working solutions that utilized these interfaces will not work on a Microsoft Win32 Virtual Machine.
Missing ByteArrayOutputStream method: While this missing method appears relatively minor, it is probably one of the biggest faults. A 100% Pure Java program that runs perfectly well within Netscape Navigator/Communicator or with the JDK/JRE just won't work in Microsoft's environment. Yes, developers can work around the missing method easily, unless something indirectly uses the method. For any product that has already shipped, however, this could force endless wasted technical support hours, with the possible need to update product and reship to support Microsoft's incompatible environment.
Using com.ms classes: While Microsoft seems to be ignoring the standard package-naming conventions (rather than employing the reverse-domain-name nomenclature, Microsoft uses "ms.com," which is the domain of Morgan Stanley), this type of enhancement is encouraged. While using most of these capabilities locks you into Microsoft's environment, it is a choice developers can clearly make. Unlike the previously mentioned modifications, a developer cannot accidentally access something that isn't portable. As long as Microsoft-specific Java programs are properly flagged, users should have no problems. This does bring up the possibility of a program similar to the 100% Pure Java initiative for those programs that are Microsoft-specific.
- Regarding behavior differences: Unfortunately, these things happen. Living to the letter of the Application Programming Interface (API) permits behavior differences based upon implementations. While some of the differences seem to be Microsoft's attempts to reduce the number of incompatible changes in the 1.1 AWT, other changes are not. There are also welcome performance improvements. While some of these differences may prove to be annoying for both developers and users, if a developer is relying on a specific implementation that is a problem, Microsoft should be thanked for fleshing this out now.
The Java world is unfortunately diverging. With the first beta-release of Java 1.2 imminent, and Microsoft promising not to support pieces of that, visions of IBM vs. Apple (PC vs. Mac) are becoming more commonplace. Developers only want to get a job done, while Microsoft and Sun argue over what's in the Java toolbox. Who eventually wins in court, only time will tell. Until then, developers need to understand the disputed technologies and make informed decisions. Until the contentious companies are together again, users and developers are caught in the middle of a closing vice with some tough decisions to make. While most of the differences between platforms are minimal, they are there. So, do you abandon Java's "write once, run anywhere" philosophy and use Microsoft's VM-specific extensions, or do you make a commitment to Sun's 100% Pure Java philosophy? If your task doesn't require JNI and RMI, it isn't an easy choice.
Thankfully, with Microsoft's SDK you can still create 100% Pure Java solutions. By avoiding the new classes, methods, and variables injected into the key Java class libraries and the non-portable com.ms packages, you can create cross-platform Java programs. By working around the added/missing behavior, you also can create programs that will work within IE 4.0 from certified Java 1.1 tools like Sun's JDK, JBuilder, VisualAge for Java, or Visual Cafe 2.0. Good luck.
Learn more about this topic
- Sun Microsystems, Inc. v. Microsoft Corp. http://home.dti.net/bdpc/java.htm
- "Sun-Microsoft dispute gets ugly," JavaWorld, October 1997 http://www.javaworld.com/jw-10-1997/jw-10-sunsuit.html
- "What does Sun's lawsuit against Microsoft mean for Java developers?", JavaWorld, October 1997 http://www.javaworld.com/jw-10-1997/jw-10-lawsuit.html
- Microsoft's Win32 Virtual Machine for Java Release Notes http://microsoft.com/java/sdk/20/relnotes/vm.htm
- Rule 3 of SunTest's "100% Pure Java Cookbook" http://www.suntest.com/100percent/cpd/doc/cbook/cookbook.html#8592
- Microsoft's Application Foundation Classes http://microsoft.com/java/sdk/20/relnotes/afc.htm
- Internet Explorer 4.0 http://microsoft.com/ie/ie40/
- Microsoft's SDK for Java http://microsoft.com/java/sdk/20/relnotes/intro.htm
- Microsoft does provide RMI (along with other unsupported tools, utilities, and libraries) -- via an FTP server ftp://ftp.microsoft.com/developr/msdn/unsup-ed/rmi.zip
- Borland's JBuilder http://www.borland.com/jbuilder/
- IBM's VisualAge for Java http://www.software.ibm.com/ad/vajava/
- Symantec's Visual Cafe http://www.symantec.com/domain/cafe/deved/index.html
- Should Microsoft be allowed to alter the key class libraries of Java? Take our latest poll http://nigeria.wpi.com/cgi-bin/gwpoll/gwpoll/ballot.html
- A review of platform-neutral Java development tools in NC World, JavaWorld's sister publication http://www.ncworldmag.com/ncw-10-1997/ncw-10-jvtools.html
- Nick Petreley's commentary about the Sun/MS lawsuit, also in NC World http://www.ncworldmag.com/ncw-10-1997/ncw-10-straypackets.html
- Alex Chaffee's analysis of Java implementation differences http://www.stinky.com/java/