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 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, 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, and archive
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
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.
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.