# Applet Compatibility—Microsoft vs Java 2 Virtual Machine

This document describes all known applet compatibility issues between the Microsoft Virtual Machine (VM) and the Sun Java 2 VM. The term "Java 2" used here refers to the Java 2 Platform Standard Edition version 1.2 or later.

## `
ClassFormatError`

This error is caused by bytecode generated from old JDK 1.0.2 or 1.1 compilers. In the past, a lot of these compilers generated bytecode that does not conform to the Java VM Specification. Since the verifiers in recent J2SE releases are much stricter about bad class format, the `ClassFormatError` is thrown by the VM when these bad class files are loaded.

Some typical problems in some older class files are the following (note that this list is not exhaustive):

- There are extra bytes at the end of the class file;
- The class file contains method or field names that do not begin with a letter;
- The class attempts to access private members of another class;
- The class file has other format errors, including illegal constant pool indices and illegal UTF-8 strings;
- Some early (third-party) bytecode obfuscators produced class files that violated proper class-file format.

You can avoid this type of problem by recompiling your classes with the Javac bytecode compiler from the current JDK. If you choose to use a third-party obfuscator, be sure to use one that produces class files that respect proper class-file format.

To allow some of the applets with bad class files to run in Java 2, Java Plug-in contains a bytecode transformer to transform some of the bad class files to good ones. Currently, only bad class files with the following `ClassFormatError` may be transformed:

- Local variable name has bad constant pool index
- Extra bytes at the end of the class file
- Code segment has wrong length
- Illegal Field/Method name
- Illegal Field/Method modifiers
- Invalid start_pc/length in local var table

Unfortunately, the following `ClassFormatError` problems are not fixable by the bytecode transformer:

- Illegal use of nonvirtual function call
- Arguments can't fit into locals
- Unsorted lookup switch
- Truncated class file

Thus, any class file having any of these problems will not run under Java 2:

## Security exception with `sun.audio`

The `sun.audio` package was accessible by applets in JDK 1.1. However, in Java 2 the applet sandbox was closed up. Thus, applets trying to access any class libraries in the `sun.audio` package will result in `SecurityException`.

To provide maximum applet compatibility, the applet sandbox in Java Plug-in has been opened up to allow applets to again access the `sun.audio` package.

## Unable to find resources from `AppletContext.getAudioClip()` and `AppletContext.getImage()`

For the Microsoft and Sun implementations, the resource lookup sequence in `AppletContext.getImage()` and `AppletContext.getAudioClip()` is different.

In the Microsoft implementation, resources are looked up in the following sequence:

1. Archives specified through HTML `archive` or `cabbase` parameters
2. `codebase` URL

In the Sun implementation, resources are looked up simply by codebase URL.

As a result, some applets relying on the resources lookup sequence of the Microsoft VM may not load resources properly in Java 2.

To provide maximum applet compatibility, the resources lookup sequence in Java Plug-in has been changed as follows:

1. Archives specified through HTML `archive` parameters
2. `codebase` URL

## `ClassLoader` sharing policy

The `ClassLoader` sharing policy is different in the Microsoft and Sun implementations.

In the Microsoft implementation, a `ClassLoader` object is shared between applets if and only if:

- `codebase` values are the same,
- `archive` values are the same, and
- `cabbase` values are the same.

In the Sun implementation, a `ClassLoader` object is shared between applets if and only if `codebase` values are the same.

Some applets relying on the `ClassLoader` sharing policy of the Microsoft implementation may not run properly in Java 2 because of potential class definition conflicts.

To provide maximum applet compatibility, the `ClassLoader` sharing policy in Java Plug-in has been changed. A `ClassLoader` object is now shared between applets if and only if:

- `codebase` values are the same,
- `cache_archive` values are the same,
- `java_archive` values are the same, and
- `archive` values are the same.

## Security model—Java 2 VS Microsoft

Java 2 has a new security model which provides much more capability and flexibility than JDK 1.1, while Microsoft's VM security model is based on JDK 1.1 and its own proprietary technologies.

This issue is not fixable. Thus, an applet that relies on the Microsoft's security model will not run properly in Java 2.

## Applet packaging

Applet packaging in Java 2 and JDK 1.1 is through `.jar` files, whereas the Microsoft VM supports applet packaging through `.jar` files and its own proprietary `.cab` (cabinet) files.

This issue is not fixable. Thus, an applet packaged in Microsoft `.cab` file format will not be loaded in Java 2.

## Java language specification strictness (`null` vs zero-length string)

In JDK 1.1 the Java language specification was loose in dealing with `null` and zero-length strings in the class libraries. Some APIs may treat a zero-length string as `null`, while other APIs may treat `null` as it is. In Java 2, the Java language specification has been tightened up to specify what the exact behavior should be.

This issue is not fixable. Thus, in Java 2 an applet that relies on the APIs to treat `null` as a zero-length string may result in an exception.

## Applet signing—RSA vs Authenticode

In Java 2, applet signing is supported through RSA and the `.jar` file, whereas Microsoft supports applet signing through its own proprietary Authenticode and `.cab` file technologies.

This issue is not fixable. Thus an applet that relies on Microsoft's Authenticode and `.cab` file technologies may not load properly in Java 2.

## Implementation changes in AWT class libraries

In the past, some programmers assumed that AWT was thread safe. Therefore some applets were written using AWT libraries that interacted with the GUI in multiple threads, assuming that the class libraries took care of synchronization issues. In fact, neither AWT nor Swing are thread safe. Therefore, all code that updates the GUI or processes events should occur on the event dispatching thread. Failure to do so may result in a deadlock or race condition. For more information, see How to Use Threads in The Swing Tutorial. Although this tutorial specifically covers Swing, in this instance, the same rules apply to all `Component`s.

## Java/JavaScript communication

In the Microsoft implementation, an applet's methods and properties exposed in JavaScript in an HTML page are exactly the same as the methods and properties of the applet object. In Java Plug-in, an applet's methods and properties are exposed in JavaScript in an HTML page through JavaBeans Introspection, which analyzes methods and properties through naming conventions in the applet object. The side effect is that applet's fields are treated differently.

This problem will be fixed in a future release of Java Plug-in. In the meantime, JavaScript access to fields in the applet object may not work properly in Java 2.

## Microsoft proprietary Java classes, methods, and variables

Microsoft has provided many proprietary class libraries in its VM implementation, including J/Direct, AFC, WFC, etc. For other classes, methods, and variables, see How to avoid potential pitfalls of Microsoft's non-standard SDK for Java.

This issue is not fixable. Thus, applets that rely on any of the Microsoft proprietary Java class libraries will not work properly in Java 2.

## Whitespace characters in strings returned from `Applet.getParameter()`

In the Microsoft implementation, whitespace characters are stripped off before the string is returned to an applet in `Applet.getParameter()`. On the other hand, Sun's implementation returns the string as it is specified in the HTML parameters. As a result, some JDK 1.1 applets refuse to run in Java 2 because the applet's logic doesn't take the whitespace into account.

To provide maximum applet compatibility, the implementation of `Applet.getParameter()` in Java Plug-in has been changed to strip off whitespace characters in the return value.

## Design changes in `java.util.Hashtable.hashCode()`

In JDK 1.1, `Hashtable.hashCode()` was implemented based on the object identity; thus, each `Hashtable` object returns its unique value when `hashCode()` is called. In Java 2, the implementation of `Hashtable.hashCode()` was changed to be value-based as part of the Java Collection Framework. A `Hashtable` object returns its hashcode value based on the objects it contains.

This change breaks some JDK 1.1 applets if they add a `Hashtable` object into itself, which breaks the fundamental design of the Collection Framework and causes `StackOverflowError`. It breaks logic in some applet code that relies on `Hashtable.hashCode()` to return a constant value from the same `Hashtable` object.

To provide maximum applet compatibility, the implementation of `Hashtable.hashCode()` has been changed to check for this special case to avoid stack overflow.

## Accessing frame from applet

To track mouse events or for some other reasons, an applet may sometimes try to access its frame . In the Microsoft and Sun implementations, the number of containers between the frame and the applet is different.

An applet that relies on a frame being at a particular level of containment in the Microsoft VM, without navigating the entire AWT hierarchical component tree, is likely to fail in Java 2. The most common symptom is `ClassCastException` from the AWT Dispatch Event Thread.

This issue is not fixable. Thus, an applet with this issue may not run properly in Java 2.

## `MAYSCRIPT`

In Netscape Navigator and Java Plug-in, an applet accessing JavaScript is required to specify the `MAYSCRIPT` attribute in the applet element. Microsoft's implementation, however, doesn't honor this special parameter; it allows an applet to access JavaScript under all conditions. Since most of Internet applets target Microsoft's VM instead of Netscape's, `MAYSCRIPT` is not specified in these applets.

To provide maximum applet compatibility, the `MAYSCRIPT` check has been removed from Java Plug-in.

## HTTP `User-Agent`

In the Microsoft and Sun implementations, different HTTP `User-Agent` strings are passed to the server when an HTTP connection is requested. Most web sites target Microsoft's VM instead of Sun's and do not recognize Sun's HTTP `User-Agent.`This may result in failure.

For that reason, the HTTP `User-Agent` string used in Java Plug-in has been made similar to the Microsoft one. Thus, most web servers will recognize requests made from applets running in Java Plug-in.

## Events during applet startup and shutdown

In the Microsoft and Sun implementations, the events occurring during applet startup and shutdown may not be exactly the same. For example, the logic in the applet may rely on the applet being visible when `Applet.start()` or `Applet.stop()` is called, which may be true in the Microsoft implementation but not in Sun implementation.

An applet that relies on specific events during applet startup and shutdown in the Microsoft VM may not function properly in Java 2. The most common symptom is `NullPointerException` from the AWT Dispatch Event Thread.

This issue is not fixable.

## Java class libraries compatibility

There are many changes in the Java class libraries and Java 2. Some APIs are clarified, some are depreciated, and some have altered implementations. The following have caused some applets run in the Microsoft VM to fail in Java 2:

- `java.awt.Graphics.drawString()`
  `drawString()` treats `null` as an empty string in the Microsoft VM. In Java 2, `drawString()` treats `null` as it is and throws `NullPointerException`.
- `java.awt.Graphics.drawImage()`
  `drawImage()` ignores `null` image in the Microsoft VM. In Java 2, `drawImage()` treats `null` as it is and throws `NullPointerException`.
- `java.awt.Color` constructors
  In the Microsoft VM, passing over-bound/under-bound values in the `Color` constructor will cause the VM to print out a warning message in the console, but the values will be reset to max/min automatically. In Java 2, `Color` constructor checks for illegal values and throws `IllegalArgumentException`.
- `Thread.stop(), Thread.suspend(), Thread.resume()`
  In the Microsoft VM, stopping, suspending, or resuming a dead thread will cause the call to be ignored. In Java 2, calling these methods on a dead thread will result in `AccessControlException`.

Applets affected by these issues will result in exceptions and may not run properly in Java 2.

## Java Moniker

This is a proprietary Microsoft technology that is not supported by Java 2.

## `object` attribute with `PARAM` element

With the conventional applet format, use of an attribute named `object` with a `PARAM` element will cause an exception with the Sun VM: 'Either "code" or "object" should be specified, but not both.' With the Microsoft VM, no exception will be thrown. This is a compatibility issue. To avoid the exception with the Sun VM, do not use an attribute named `object` with a `PARAM` element in an applet.