Java 2 Platform, Standard Edition
Version 1.4.0
Compatibility with Previous Releases
|
SDK Documentation

|
Contents
This document contains information on the following topics:
For information about incompatibilities between versions 1.3 and 1.2
of the Java platform, see the compatibility documentation for
the Java 2 Platform, v1.3.
For information about incompatibilities between versions 1.2 and 1.1
of the Java platform, see the compatibility documentation for the Java 2 Platform, v1.2.
For information about incompatibilities between versions 1.0 and 1.1
of the Java platform, see the compatibility documentation for
the JDK 1.1 software.
See the Clarifications and
Amendments document for a summary of changes that have been made to
the specification of the Java programming language since the publication
of the original Java Language
Specification.
Binary Compatibility
The Java 2 SDK, v1.4 is upwards binary-compatible with
Java 2 SDK, v1.3 except for the incompatibilities listed below.
This means that, except for the noted incompatibilities, class
files built with version 1.3 compilers will run correctly
in the Java 2 SDK, v1.4.
In general, the policy is that
Maintenance releases (for example 1.2.1, 1.2.2) within a
family (1.2.x) will maintain both upward and downward
binary-compatibility with each other.
Functionality releases (for example 1.3, 1.4) within a
family (1.x) will maintain upward but not necessarily
downward binary-compatibility with each other.
Some early bytecode obfuscators produced class files that
violated the class file format as given in the virtual
machine specification. Such improperly formatted class files
will not run on the Java 2 SDK's virtual machine, though some of them
may have run on earlier versions of the virtual machine. To
remedy this problem, regenerate the class files with a newer
obfuscator that produces properly formatted class files.
Source Compatibility
The Java 2 SDK versions 1.2, 1.3, and 1.4 are upwards
source-compatible with JDK software versions 1.0 and 1.1, except for
the incompatibilities listed
below. This means that, except for the noted incompatibilities,
source files written to use the language features and APIs defined
for 1.0 and 1.1 can be compiled and run in the Java 2 SDK (all versions).
Downward source compatibility is not supported. If source
files use new language features or Java 2 Platform APIs, they
will not be usable with an earlier version of the Java platform.
In general, the policy is that:
Maintenance releases do not introduce any new language
features or APIs, so they maintain source-compatibility in
both directions.
Functionality releases and major releases maintain
upwards but not downwards source-compatibility.
Deprecated APIs are methods and classes that are supported
only for backwards compatibility, and thecompiler will generate a warning message whenever one of these
is used, unless the -nowarn command-line option is
used. It is recommended that programs be modified to
eliminate the use of
deprecated methods and classes, though there are no current
plans to remove such methods and classes entirely from the system.
Some APIs in the sun.* packages have changed. These APIs are
not intended for use by developers. Developers importing from
sun.* packages do so at their own risk. For more details,
see Why Developers Should Not Write Programs That Call sun.* Packages.
Incompatibilities Between Java 2 Platform,
Standard Edition, v1.4.0 and v1.3
J2SE 1.4.0 is strongly compatible with previous versions of the Java 2 Platform.
Almost all existing programs should run on J2SE 1.4.0 without modification. However,
there are some minor potential incompatibilities with 1.3 that involve rare circumstances
and "corner cases" that we are documenting here for completeness.
Beginning with version 1.4 of the Java 2 Platform, class
javax.swing.tree.DefaultTreeModel allows a null root node.
In previous versions, DefaultTreeModel would not allow a
null root, even though the specification for TreeModel
indicated a null root was valid. DefaultTreeModel now allows
setting a null root, as well as a null root in the constructor. As
part of this change, the specification for
DefaultTreeModel.setRoot() has been revised.
The old specification for DefaultTreeModel.setRoot() was:
Sets the root to root. This will throw an
IllegalArgumentException if root is null.
The new DefaultTreeModel.setRoot() specification says:
Sets the root to root. A null root implies
the tree is to display nothing, and is legal.
If a serializable nested class contains explicit references to a class
object (for example, "Foo.class"), then the computed value of the
default serial version UID for both the nested class and its enclosing
class will be different in J2SE 1.3 and J2SE 1.4. The difference is due to
the fact that the computation of the serial version UID is sensitive to
modifications made in the javac compiler between J2SE 1.3
and J2SE 1.4.
To avoid this problem affecting your applications, we recommend that
you add an explicit serial version UID to your serializable classes.
You can use the serialver tool to obtain the serial version UID of
classes compiled with the J2SE 1.3 javac compiler.
Beginning with J2SE 1.4.0, public static field
DefaultPainter
in class javax.swing.text.DefaultHighlighter is final.
In previous versions of the Java 2 Platform, Standard Edition, this
field was non-final.
The way in which HTML forms are modeled internally in the
implementation of the Java 2 Platform has changed in J2SE 1.4.0.
Previously, any attributes of a form would be stored in
the attributeset of all of the children character elements. In
J2SE 1.4.0, an element is created to represent the form, better
matching that of the html file itself. This allows for better
modeling of the form, as well as consistant writing of the form.
This change was made to address bug
4200439.
This change will effect developers who relied on forms being handled
loosely. As an example, pre-1.4.0 implementations would previously treat
the following invalid html
<table>
<form>
</table>
</form>
as
<form>
<table>
</table>
</form>
J2SE 1.4.0 instead treats it as:
<table>
<form>
</form>
</table>
While this change likely will not impact many developers, there is the
possibility you will need to update your code. If you had previously
been expecting the attributes of the leaf Elements to contain the
Form's attributes, you will now have to get the attributes from the
Form Element's AttributeSet.
The value of static final field
MOUSE_LAST
in class java.awt.event.MouseEvent has changed to 507
beginning in J2SE 1.4.0. In previous versions of the Java 2
Platform, the value of MOUSE_LAST was 506.
Because compilers hard-code static final values at compile-time,
code that refers to MOUSE_LAST and that was compiled
against a pre-1.4.0 version of java.awt.event.MouseEvent will retain
the old value. Such code should be recompiled with the version 1.4.0
compiler in order to work with J2SE 1.4.0.
Changes have been made to make the APIs for the CORBA technology shipped in J2SE 1.4.0 compliant to the CORBA 2.3 mapping as specified by the OMG documents referenced in CORBA Compatibility Information. Follow the link for information regarding all of the API changes related to CORBA functionality between J2SE v1.3 and v1.4.0, as well as a listing of all OMG specifications with which J2SE 1.4.0 complies.
Beginning with J2SE 1.4.0, ObjectOutputStream's
public
one-argument constructor requires the "enableSubclassImplementation" SerializablePermission
when invoked (either directly or indirectly) by a subclass which overrides
ObjectOutputStream.putFields
or ObjectOutputStream.writeUnshared.
Also beginning with J2SE 1.4.0, ObjectInputStream's
public one-argument constructor requires the
"enableSubclassImplementation" SerializablePermission when invoked
(either directly or indirectly) by a subclass which overrides
ObjectInputStream.readFields or ObjectInputStream.readUnshared.
This change will not affect the great majority of applications.
However, it will affect any ObjectInputStream/ObjectOutputStream
subclasses which override the putFields or readFields
methods without also overriding the rest of the serialization infrastructure.
The Javac bytecode compiler in J2SE 1.4.0 is more strict than
in previous versions in enforcing compliance with the
Java Language Specification. The new compiler may not compile
existing code that does not strictly conform to the Java Language
Specification, even though that code may have compiled with earlier
versions of the compiler.
The following are some examples of situations in which the J2SE 1.4.0
compiler is stricter.
The compiler now detects unreachable empty statements as required
by the language specification. Here are two examples of fairly common
cases that the compiler now detects and rejects.:
return 0;/* exit success */;
and
{
return f();
} catch (Whatever e) {
throw new Whatever2();
};
|
Note the extra semicolon in both cases, which the compiler now
correctly regards as unreachable empty statements. In addition,
some automatically generated source code may generate unreachable
empty statements.
The compiler now rejects import
statements that import a type from the unnamed namespace. Previous
versions of the compiler would accept such import declarations, even
though they were arguably not allowed by the language (because the type
name appearing in the import clause is not in scope). The specification is
being clarified to state clearly that you cannot have a simple name in
an import statement, nor can you import from the unnamed namespace.
To summarize, the syntax
import SimpleName;
is no longer legal. Nor is the syntax
import ClassInUnnamedNamespace.Nested;
which would import a nested class from the unnamed namespace.
To fix such problems in your code, move all of the classes from the
unnamed namespace into a named namespace.
As of J2SE 1.4.0, the javac bytecode compiler uses "-target 1.2" by
default as opposed to the previous "-target 1.1" behavior. See the
reference page for the javac
compiler for descriptions of these
behaviors. One of the changes involved in targeting 1.2 is that the
compiler no longer generates and inserts method declarations into
class files when the class inherits unimplemented methods from interfaces.
These inserted methods, like all other non-private methods, are included in
the default serialVersionUID computation. As a result, if you define
an abstract serializable class which directly implements an interface
but does not implement one or more of its methods, then its default
serialVersionUID value will vary depending on whether it is compiled
with the J2SE 1.4 version of javac or a previous javac.
For background information on these methods inserted by earlier versions
of javac, see bug 4043008.
Source incompatibility - The JDBC 3.0 API, included as
part of the J2SE 1.4 platform,
introduces two new interfaces and adds several new methods
to existing interfaces. Drivers and applications that use
earlier versions of the JDBC API are binary compatible with
the J2SE 1.4 platform and will run with no problem.
However, the changes made in the JDBC 3.0 API are not source compatible.
Drivers and applications that implement the JDBC interfaces must be
updated to reflect the changes in order to build successfully.
Chapter 6 of
The JDBC 3.0 Specification gives a complete list
of what must be done to be compliant with the
JDBC 3.0 API, and thereby be source compatible with the
J2SE 1.4 platform.
Prior to J2SE 1.4, a FileNotFoundException would be
thrown if the file type was known and the response code was
greater than or equal to 400. Otherwise no exception would be
thrown.
The correct behavior as implemented in J2SE 1.4 is for
URLConnection.getInputStream to throw an
IOException for all http errors regardless of the
file type and throw FileNotFoundException, which is
a subclass of IOException, only if the http response
indicates that the resource was not found. In other words, the
FileNotFoundException is thrown only if the response
code is 404 or 410.
As part of this change, HttpURLConnection.getErrorStream now can be used to read the error page returned from the server.
Prior to J2SE 1.4, getErrorStream always returned null.
Also, method HttpURLConnection.getResponseCode
works correctly in J2SE 1.4.
The assert keyword has been added to the Java Programming Language
in J2SE 1.4. Because of the new keyword, existing programs that use
"assert" as an identifier will not be in conformance with J2SE 1.4.
The addition of this keyword does not, however, cause any
problems with the use of preexisting binaries (.class files).
In order to ease the transition from pre-J2SE 1.4 releases in which
assert is a legal identifier to J2SE 1.4 where it isn't, the
Javac bytecode compiler supports two modes of operation in J2SE 1.4.
In the normal mode of operation, the compiler accepts programs
conforming to the specification for the previous release (J2SE 1.3).
Assertions are not permitted, and the compiler generates a
warning if the assert keyword is used as an identifier.
In an alternate mode of operation, the compiler accepts programs
conforming to the specification for J2SE 1.4. Assertions are
permitted, and the compiler generates an error message if the
assert keyword is used as an identifier.
To enable assertions, use the following command line switch.
-source 1.4
In the absence of this flag, the behavior defaults to "1.3" for maximal
source compatibility. Support for 1.3 source compatibility is likely to be
phased out over time.
The API specification for interface AppletContext
has been modified to enable applet developers to stream data and objects
for persistent use during a browser session. This eliminates the need
for developers to use static classes to cache data and objects, but it
introduces a potential binary incompatibility. Any existing applications
containing classes that implement the AppletContext interface
will not be compatible with the new AppletContext specification.
Such classes will have to be modified to implement the revised
AppletContext API. In practice,
the only applications that commonly implement AppletContext are
those that act as applet containers, such as Java Plug-in and appletviewer.
The impact of this potential incompatibility is therefore expected to be
minimal.
J2SE 1.4 introduces significant
changes in the Socket API, one of which is the addition of a new abstract
method to the
SocketImpl abstract class.
Because of the new method, if a subclass of SocketImpl was
created prior to J2SE 1.4, then compilation against the 1.4 javac will
fail because there is no implementation provided for the new method.
Note that binary compatibility is enforced, and existing class
files for such a subclass will still work as expected.
Few applications subclass SocketImpl, and the impact of this
potential incompatibility is expected to be minimal. Developers who do
subclass SocketImpl have two ways to deal with this change:
Use a class file compiled on J2SE 1.3.x (or earlier).
Provide an implementation for the new methods. An simple example
that assumes a straight TCP/IP implementation and ignores the
timeout value is provided below. Of course, we recommend use of a
proper implementation that respects the timeout value. A simple
implementation for sendUrgentData() that throws an
exception is all that is needed provided that
supportsUrgentData() hasn't been overwritten to
return "true".
/**
* Creates a socket and connects it to the specified address on
* the specified port.
* @param address the address
* @param timeout the timeout value in milliseconds, or zero for no timeout.
* @throws IOException if connection fails
* @throws IllegalArgumentException if address is null or is a
* SocketAddress subclass not supported by this socket
* @since 1.4
*/
protected void connect(SocketAddress address, int timeout)
throws IOException {
if (address == null || !(address instanceof InetSocketAddress))
throw new IllegalArgumentException("unsupported address type");
InetSocketAddress addr = (InetSocketAddress) address;
if (addr.isUnresolved())
throw new UnknownHostException(addr.getHostName());
this.port = addr.getPort();
this.address = addr.getAddress();
try {
connect(this.address, port);
return;
} catch (IOException e) {
// everything failed
close();
throw e;
}
}
/**
* Send one byte of urgent data on the socket.
* The byte to be sent is the low eight bits of the parameter
* @param data The byte of data to send
* @exception IOException if there is an error
* sending the data.
* @since 1.4
*/
protected void sendUrgentData (int data) throws IOException {
throw new IOException("Unsupported operation");
}
|
The J2SE 1.4 platform includes the Java Secure Socket Extension (JSSE) API.
In J2SE 1.4, the JSSE implementation recognizes system property
com.sun.net.ssl.dhKeyExchangeFix, and this variable has a
default value of "true" in J2SE 1.4. In the previously released
JSSE 1.0.2 optional package, the default value
of the property was "false". Cypher suites that use the DH key
exchange will be affected by this change in property value. Such suites
are used comparitively rarely, so this potential incompatibility is
not expected to have a large impact.
Background: The orignally released optional package version of
the JSSE API contained a bug that caused incorrect encoding of
DSA signatures when those signatures were used as part of
the server key exchange message. This bug meant that JSSE was
not in conformance to the key exchange specification, and it
was the source of incompatibilities between JSSE and SSL
implemenations from other vendors. In an attempt to fix this
situation, optional package JSSE 1.0.2 introduced system property
com.sun.net.ssl.dhKeyExchangeFix. Setting this property to
"true" meant that JSSE 1.0.2 would operate with the bug fixed
and thus be compatible with other SSL implementations. When the
property value was "false", JSSE 1.0.2 would operate with the bug
not fixed so as to be compatible with previous JSSE releases.
In JSSE 1.0.2, the default value of the property was "false";
in J2SE 1.4, the default value is "true", ensuring compatibility
between J2SE 1.4 and other SSL/TLS implementations.
Beginning with version 1.4 of the J2SE platform,
policy files used by the default policy implementation
must be encoded in the UTF-8 character encoding.
Existing policy files with non-ASCII characters
(which would have been encoded in some platform
character encoding) must be converted to UTF-8.
The Java 2 SDK, Standard Edition's native2ascii tool
can be used to assist with this conversion.
A change in behavior was introduced in J2SE 1.4.0 as a fix for
4395290. The changed behavior is also part of J2SE 1.4.1. In the new
behavior, dragExit() is called on the DropTarget and on the
DropTargetListener registered with it only when the mouse pointer has
exited the operable part of the drop site for this DropTarget during a
drag operation. Prior to J2SE 1.4.0, these methods were also called
immediatelly before drop() is called on the DropTarget or the
DropTargetListener respectively.
The old behavior was documented in the
Drag and Drop Specification for J2SE 1.3, but was inconsistent
with the
Java 2 Platform API Specification.
The old behavior was also inconvenient and imposed a significant
impact on the usability of Drag and Drop in Swing.
Starting with J2SE 1.4.0, the behavior matches the Java 2 platform API
Specification and the Drag and Drop Specification was updated to
reflect this change.
A change in behavior was introduced in J2SE 1.4.0 as a fix for
4426794 and 4435403. The changed behavior is also part of J2SE 1.4.1.
Prior to J2SE 1.4.0, drag notifications were always dispatched to the
top-most Component under the mouse cursor. If this Component does not
have an associated drop target, these notifications are discarded.
This design has two major flaws:
We have to ignore a Swing glass pane during drag notification targeting,
because it would consume all drag notifications otherwise. This prevents
developers from using a Swing glass pane as a drop target.
To implement drop support on a compound Component, such as a JColorChooser,
such that the Component would accept a drop anywhere inside of it,
developers are forced to install drop targets on all descendants of the
compound Component. This is unwieldy and inefficient.
In the new behavior, drag notifications are dispatched to the top-most
Component under the mouse cursor with an active drop target.
- As a result of the new focus architecture introduced in 1.4.0,
the following incompatibilities were introduced:
- As of release 1.4.0, when the last window is disposed of and no
more events are in the event queue, the event-dispatching thread
may exit, which causes the program to exit. See bug #4030718
for more information, including a workaround.
|