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):
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
SE, 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:
Unfortunately, the following ClassFormatError
problems are not fixable by the bytecode transformer:
Thus, any class file having any of these problems will not run under Java SE:
sun.audio
The sun.audio
package was accessible by applets in
JDK 1.1. However, in Java SE 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.
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:
archive
or
cabbase
parameterscodebase
URLIn 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 SE.
To provide maximum applet compatibility, the resources lookup sequence in Java Plug-in has been changed as follows:
archive
parameterscodebase
URLClassLoader
sharing policyThe 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, andcabbase
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
SE 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, andarchive
values are the same.Java SE 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 SE.
Applet packaging in Java SE 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 SE.
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 SE, the Java language specification has been
tightened up to specify what the exact behavior should be.
This issue is not fixable. Thus, in Java SE an applet that
relies on the APIs to treat null
as a zero-length
string may result in an exception.
In Java SE, 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 SE.
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
Concurrenecy in Swing in The Swing
Tutorial. Although this tutorial specifically covers Swing, in
this instance, the same rules apply to all
Component
s.
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 SE.
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 SE.
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
SE 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.
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 SE, 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.
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 SE. 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 SE.
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.
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.
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
SE. The most common symptom is NullPointerException
from the AWT Dispatch Event Thread.
This issue is not fixable.
There are many changes in the Java class libraries and Java SE. 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 SE:
java.awt.Graphics.drawString()
drawString()
treats null
as an empty
string in the Microsoft VM. In Java SE, drawString()
treats null
as it is and throws
NullPointerException
.java.awt.Graphics.drawImage()
drawImage()
ignores null
image
in the Microsoft VM. In Java SE, drawImage()
treats
null
as it is and throws
NullPointerException
.java.awt.Color
constructorsColor
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 SE, Color
constructor
checks for illegal values and throws
IllegalArgumentException
.Thread.stop(), Thread.suspend(),
Thread.resume()
AccessControlException
. Applets affected by these issues will result in exceptions and may not run properly in Java SE.
This is a proprietary Microsoft technology that is not supported by Java SE.
object
attribute with PARAM
elementWith 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.