Contents
This document contains information on the following topics:
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.
The Java 2 SDK, v1.3 is upwards binary-compatible with
Java 2 SDK, v1.2 except for the incompatibilities listed below.
This means that, except for the noted incompatibilities, class
files built with version 1.2 compilers will run correctly
in the Java 2 SDK, v1.3.
As long as the Javac compiler's '-target 1.2' command-line
option is not used, downward binary compatibility is
generally supported, though not guaranteed. That is, class
files built with a Java 2 SDK compiler, but relying only on APIs
defined in versions 1.0 or 1.1 of the Java platform, will
generally run on 1.0 and 1.1 versions of the Java virtual
machine, but this "downwards" compatibility has not been
extensively tested and cannot be guaranteed. Of course, if
the class files depend on any new Java 2 Platform APIs, those
files will not work on earlier platforms.
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.2, 1.3) 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.
The Java 2 SDK versions 1.2 and 1.3 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 (v1.2 and 1.3).
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 in the Java 2 Platform,
Standard Edition, v1.3
J2SE 1.3 is strongly compatible with J2SE 1.2 and 1.2.2. Almost
all existing programs should run on J2SE 1.3 without modification.
However, there are some minor potential incompatibilities that
involve rare circumstances and "corner cases" that
we are documenting here for completeness.
- New class java.util.Timer
has been added in version 1.3 of the Java 2 Platform, making two
classes named Timer:
- java.util.Timer
- javax.swing.Timer
The introduction of java.util.Timer will cause
a source-level incompatibility in existing code that has these two
import statements:
import java.util.*;
import javax.swing.*;
and refers to javax.swing.Timer by its unqualified name, as
in, for example
Timer t;
The ambiguous reference to class Timer can be resolved
in favor of javax.swing.Timer by adding a third import
statement:
import javax.swing.Timer;
With this third import statement in place, the source code will
compile and have the same behavior as in previous versions of
the platform.
- The implementation of method java.lang.Double.hashcode
has been changed in Java 2 SDK, v1.3 to conform to the API specification.
A typographical error in the specification has also been corrected.
The specification for method hashcode previously contained the
following sentence:
"That is, the hashcode is the value of the expression:
(int)(v^(v>>>32))
where v is defined by:
long v = Double.doubleToLongBits(this.longValue());"
The last line in this sentence has been corrected in the 1.3 API
specification to read
long v = Double.doubleToLongBits(this.doubleValue());
The method's implementation in the SDK has been changed
to return
(int)(bits ^ (bits >>> 32))
in conformance with the specification, where bits is
doubleToLongBits(value). In previous versions of the SDK,
method hashcode returned
(int)(bits ^ (bits >> 32))
This change in implementation is not expected to affect the
behavior of existing applications because
hashcode returns a truncated integer value.
- New Permission class java.sql.SQLPermission
has been added in version 1.3 of the Java 2 Platform.
The SecurityManager will check the SQLPermission when code that is
running in an applet calls any of the following methods:
java.sql.DriverManager.setLogWriter
java.sql.DriverManager.setLogStream (deprecated)
javax.sql.DataSource.setLogWriter
javax.sql.ConnectionPoolDataSource.setLogWriter
javax.sql.XADataSource.setLogWriter
|
Under J2SE 1.3, an exception will be thrown when an applet
without the appropriate SQLPermission attempts to set the
log writer.
- The internal implementation of the Java Sound APIs
(in class com.sun.media.sound.SimpleInputDevice) in version 1.3
checks
javax.sound.sampled.AudioPermission. The new check means that, under 1.3, applets
must be given the appropriate AudioPermission to access audio
system resources, whereas this was not the case in previous versions
of the platform.
- JInternalFrames are no longer visible by default.
Beginning with version 1.3 of the Java 2 Platform, developers need to set the
visibility of each JInternalFrame to true in order
to have it show up on the screen. In previous versions of the
platform, the visibility of
JInternalFrames was true by default.
Why the change? The rule for default visibility in Swing is that only
top-level components, such as JFrame and JDialog, have
default visibility false; the remaining components have default
visibility true. This is so that once a JFrame is
constructed, one call to setVisible(true) on the JFrame will
show it and all of its contents.
Although JInternalFrame is not really a top-level
component, it needs to behave like a JFrame in many ways. In
particular, it needs to fire JInternalFrame events corresponding to
Window events on JFrames. One such event, INTERNAL_FRAME_OPENED, is
fired in response to the initial visibility change from false
to true; with no such change prior to version 1.3, the event
wasn't being fired.
In order to fix this bug, and to make JInternalFrame more compatible
with its heavyweight cousin JFrame, the default visibility of
JInternalFrame has been changed to false beginning with version 1.3
of the Java 2 Platform. Therefore, to show an internal frame, just add
the call to setVisible(true) after adding the frame to its parent.
To ensure that your JInternalFrames are visible on 1.2.x or 1.3, you need
to be sure to call setVisible. There is no penalty for making
this call on 1.2 even though the frames will be visible by default.
- In version 1.3, the TableColumn.getHeaderRenderer
method returns null by default. Because of that, it
cannot be used to get the default header renderer. Instead,
you can use the new
JTableHeader.getDefaultRenderer method to get the default header
renderer.
In cases where you need the same code to work on 1.2.x and 1.3, you
can do so. In places where you were counting on the
getHeaderRenderer method to return the default renderer, you
can instead create a new renderer. An example is shown below. This
will work on 1.2.x and 1.3.
/*Original code*/
DefaultTableCellRenderer hr =
(DefaultTableCellRenderer)column.getHeaderRenderer();
hr.setHorizontalAlignment(SwingConstants.LEFT);
/*Fixed code*/
DefaultTableCellRenderer hr = new DefaultTableCellRenderer();
hr.setHorizontalAlignment(SwingConstants.LEFT);
column.setHeaderRenderer(hr);
|
- Because JTable's default text editor is smarter in version 1.3
about data types, it now gives setValueAt objects of the
appropriate type, instead of always specifying strings. For example,
if setValueAt is invoked for an Integer cell, then the value
is specified as an Integer instead of a String. If you implemented a
table model, then you might have to change its setValueAt
method to take the new data type into account. If you implemented a
class used as a data type for cells, make sure that your class has a
constructor that takes a single String argument.
- In releases 1.2.x it was possible for sufficiently trusted code to modify
final fields by first calling Field.setAccessible(true) and then
calling Field.set(). This was clearly a bug since the
specification for Field.set()
stated that an IllegalAccessException would be thrown in this case.
This bug has been fixed in 1.3, and program code should not attempt
to rely on the improper behavior that was formerly possible because
of the bug.
- A bug (bugID 4250960) in versions 1.2, 1.2.1 and 1.2.2 of the Java 2 SDK
and Java 2 Runtime Environment allowed sufficiently trusted code to
change the value of final fields by first calling
java.lang.reflect.Field.setAccessible(true) and then calling
Field.set(). The ability to modify final fields in
this manner is a bug because it is a violation of the specification for
Field.set(),
which states that an IllegalArgumentException should be thrown
when an attempt is made to modify a final field.
This bug is fixed in version 1.3, and program code should not attempt
to rely on the improper behavior that was formerly possible because of the bug.
Note that non-static final fields can still be set through the
JNI
Set<type>Field routines.
- The specification and behavior of the constructors
BasicPermission(String name) and
BasicPermission(String name, String actions) in class
java.security.BasicPermission have been modified in version
1.3 of the Java 2 Platform. When the name parameter is
null, the constructors now throw a NullPointerException.
When name is an empty string, the constructors now throw an
IllegalArgumentException. This change of behavior is inherited
by subclasses of BasicPermission.
The change also affects the behavior of
java.lang.System.getProperty() and
java.lang.System.setProperty() whose implementations construct
an instance of PropertyPermission, a subclass of
BasicPermission.
Under the change, a call to getProperty or setProperty
with an empty property name (that is, getProperty("") or
setProperty("", value)) will result in an
IllegalArgumentException. In previous versions
of the platform, such a call would return quietly with no exception.
- The behavior of java.net.URL has changed slightly for cases in which a URL instance
is constructed from a String. In previous versions
of the Java platform, a final slash ('/') would be added to a
URL when the URL was constructed without one. For example, consider this code:
URL url = new URL("http://www.xxx.yyy");
System.out.println(url.toString());
In previous releases, this code would produce the following output.
http://www.xxx.yyy/
In 1.3, the trailing slash is not automatically appended, so that
the output of the above code is now
http://www.xxx.yyy
The previous behavior was technically a bug, and it is not expected that
this change will cause any compatibility problems
with previous releases.
- The introduction of a new implementation of the javac compiler
in version 1.3 has the following compatibility ramifications.
- Inherited Members of an Enclosing Class are Now Accessible
The Java Language Specificaton, Second Edition, states that
inherited members of a class are accesible within that class, including any
nested classes. In 1.1 and 1.2 versions of the Java 2 SDK, the compiler
considered a member accessible within a nested class only if it was
actually declared in an enclosing class. The new compiler in
the Java 2 SDK, v1.3 has been brought into conformance with the specification.
- Hiding of Local Variables and Parameters
The Java Language Specification requires that an error be reported when a
local variable or catch clause parameter is declared within the scope of a
like-named method parameter, local variable, or catch clause parameter.
However, the old compiler enforced it somewhat erratically. The
specification has
been clarified so that the rule applies only to variables and parameters
belonging to a single method. Where a method is nested within another
method, e.g., as a member of a local class, local variables and parameters
of the inner method may freely shadow those of the outer method.
- Name Conflicts Between Types and Subpackages
According to section 7.1 of the Java Language Specification, Second
Edition, it is illegal for a package to contain a class or
interface type and a subpackage with the same name. This rule was almost
never enforced prior to version 1.3. The new compiler now enforces this rule
consistently. A package, class, or interface is presumed to exist if there
is a corresponding directory, source file, or class file accessible on the
classpath or the sourcepath, regardless of its content.
- Qualified Names in Constant Expressions
According to section 15.28 of the Java Language Specification, Second
Edition, a qualified name that is a constant expression must
be of the form TypeName.identifier. Thus, regardless of whether the field
foo itself is a constant, an expression x.foo, where x is a variable or any
other expression, may not be used in a context where a constant expression
is required. Prior to version 1.3, javac silently accepted such constructions,
treating x as if had been replaced by its type, and ignoring any side
effects that the expression might peform.
- Member Classes of Interfaces are Now Inherited by Implementing Classes
Prior to version 1.3, member classes of interfaces were not inherited by
implementing classes. This was an oversight in the implementation. The
specification requires that the member classes be inherited, in keeping
with the principle that they should be treated analogously to fields.
- In version 1.3, java.io.ObjectInputStream has been
optimized to buffer incoming data for improved performance. As a
side effect of this change, ObjectInputStream calls the
multi-byte read(byte[], int, int) method of the
underlying stream more often than it did previously. Consequently,
underlying stream classes that implement this method incorrectly
are more likely to trigger serialization failures. To avoid the
possibility of unexpected behavior, it is critical that the
underlying stream implement both the single-byte read() and
multi-byte read(byte[], int, int) methods
properly.
- Version 1.2 of the Java 2 Runtime Environment included a client
side adapter for the Internet-Intranet Input Method Protocol (IIIMP),
a Sun Microsystems technology which enables the use of server-based
input methods over the network. This adapter was included to allow
the evaluation of this protocol at a time when there was no public
interface that would let users install the adapter into a Java
runtime environment as a separate software component. Version 1.3 of
the Java 2 platform provides a public input method engine SPI, so
that the adapter, like other input systems, can now be developed and
distributed as a separate product and installed into any
implementation of the Java 2 platform. A version of the IIIMP adapter
that uses the SPI is currently being developed by Sun Microsystems.
To obtain current information, go to the
Solaris Developer Connection and
search for "IIIM".
Environments set up to allow text entry using a server-based
input method should use instead another solution such as
host input methods or the IIIMP client-side adapter from Sun.
- The previous versions of JVMs and native libraries in the JDK
were compiled in C++ "-compat=4" mode so as to be compatible with
native C++ code that was written in the ARM-based pre-ANSI/ISO
C++ (such as used with Sun Workshop SC4.2 and earlier C++
compilers). Starting from J2SE 1.3.0 onwards, the JVM and native
libraries are compiled using the "standard" mode
corresponding to ANSI/ISO C++. This change means that existing
native C++ source code that uses the old pre-ANSI/ISO C++, and
which used to work with the old versions of the JVMs, will be
incompatible with J2SE 1.3.0, especially if you use C++
exceptions. Such native C++ code should be ported to "standard"
ANSI C++ mode to work with J2SE 1.3.0 and later.
Version 1.3.0 of the Java virtual machine for Solaris Operating
Environment was built under Solaris 2.6 using Sun Workshop 5.0 C++
compiler in "standard" (ANSI/ISO C++) mode using ""classic" iostreams.
- Prior to J2SE 1.3.0, the javac compiler for Microsoft Windows
platforms treated directory names in package paths in a case-insensitve
manner. Beginning with J2SE 1.3.0, the javac compiler treats directory
names in a case-sensitive manner. The javac compiler in J2SE 1.3.0
will emit a "cannot resolve symbol" error if directory names in a
package path are not letter-for-letter case matched to package names.
|