How to avoid potential pitfalls of Microsoft's non-standard SDK for Java

Find out exactly which methods, classes, and variables have been added to, or omitted from, the key Java class libraries in Microsoft's implementation of Java 1.1

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 source files that come with the SDK and comparing them to the Java source 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 this month's issue of JavaWorld.)

I have analyzed the source files and have run across six issues 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 six concerns are: new classes, methods, and variables; the com.ms packages; missing methods; and behavioral differences. They go far beyond the often-cited concern over Microsoft's lack of JNI and RMI support, as mentioned in my other JavaWorld article this month, "What does Sun's lawsuit against Microsoft mean for Java developers?"

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.

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, and java.awt packages/sub-packages.

Hey, what's that class doing there?

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. As for classes, 16 new ones were added into java.awt. These are:

WButtonPeerWCheckboxMenuItemPeerWCheckboxPeerWChoicePeer
WLabelPeerWListPeerWMenuBarPeerWMenuItemPeer
WMenuPeerWPopupMenuPeerWScrollbarPeerWScrollPanePeer
WTextAreaPeerWTextComponentPeerWTextFieldPeerWUIPeer

With the exception of the last one, all of the classes above are peer classes for AWT components. Normally, these classes would go into a 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 __AwtUIBand and __UIMenuRoot. Because these are inaccessible outside of java.awt, you cannot directly use them.

And where did these methods and instance variables come from?

The most commonly added method is called getBaseName(). Thankfully, it too is package private, although it should be private. Other changes, like making ClassLoader's 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 classes libraries, this isn't an issue. (Sun may disagree through its compatibility tests. See Rule 3 of SunTest's "100% Pure Java Cookbook," referenced in the Resources section below.)

The real problems appear with the public methods that Microsoft introduced:

ClassNew Method(s)
java.awt.EventQueue_postEvent (AWTEvent)
java.awt.FontgetNativeData()
java.awt.image.DirectColorModelgetToolkitData()
java.awt.image.IndexColorModelgetToolkitData()
java.awt.SystemColorgetWin32Index()
java.lang.Class

getInterface(String)

getMethods(int[])

getMethodFromSignature(String,String)

getDeclaredMethodFromSignature(String,String)

java.lang.RuntimegetNativeServices()
java.lang.SecurityManager

checkFileDialog()

checkRegistry(int,String)

checkSystemStreams(int)

checkMultimedia()

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 two new instance variables:

ClassNew Variable
java.awt.FontpData
java.awt.SystemColorappWorkspace

The appWorkspace is brand-new to SystemColor, while pData was private and is now public. As with everything else, avoid them.

Inside com.ms

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

What's missing in the SDK

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

And what's different

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.

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

Conclusion

It is possible to create 100% Pure Java solutions with Microsoft's new SDK for Java. 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 missing behavior, you also can create programs that will work within IE 4.0 from certified Java 1.1 tools such as Sun's JDK, JBuilder, VisualAge for Java, and Visual Café 2.0. Good luck.

John Zukowski is a Software Mage with MageLang Institute, author of Java AWT Reference from O'Reilly & Associates and Borland's JBuilder: No experience required from Sybex, as well as the Focus on Java guide at the Mining Company.

Learn more about this topic

Join the discussion
Be the first to comment on this article. Our Commenting Policies