Incompatibilities in J2SE 5.0 (since 1.4.2)

This compatibility page details only 5.0 compatibility with 1.4.2 and not with previous versions. To find how 5.0 is compatible with other versions, look at all compatibility pages.

See the Java Language Specification Maintenance page for a summary of changes that have been made to the specification of the Java programming language since the publication of the Java Language Specification, Second Edition.

Binary Compatibility

JDK 5.0 is upwards binary-compatible with Java 2 SDK, v1.4.2 except for the incompatibilities listed below. This means that, except for the noted incompatibilities, class files built with version 1.4.2 compilers will run correctly in JDK 5.0.

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 JDK'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

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 as follows, except for any incompatibilities listed further below:

  • Maintenance releases (such as 1.4.1, 1.4.2) do not introduce any new language features or APIs, so they maintain source-compatibility with each other.
  • Functionality releases and major releases (such as 1.3.0, 1.4.0, 5.0) maintain upwards but not downwards source-compatibility.

Deprecated APIs are interfaces that are supported only for backwards compatibility. The javac compiler generates 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 APIs, though there are no current plans to remove such APIs – with the exception of JVMDI and JVMPI – 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 Java 2 Platform Standard Edition 5.0 (since 1.4.2)

J2SE 5.0 is strongly compatible with previous versions of the Java 2 platform. Almost all existing programs should run on J2SE 5.0 without modification. However, there are some minor potential source and binary incompatibilities in the JRE and JDK that involve rare circumstances and "corner cases" that we are documenting here for completeness.

  1. - The class was added in 5.0, making two classes named Proxy.
    • java.lang.reflect.Proxy

    The introduction of will cause a source-level incompatibility in existing code if a compilation unit has the following type-import-on-demand declarations:

      import java.lang.reflect.*;
    • and no single-type-import declaration for the name Proxy
    • and attempts to refer to the java.lang.reflect.Proxy class by its simple name

    In this case, a compile-time error occurs, because the reference is now ambiguous.

    The ambiguous reference to the Proxy class can be resolved in favor of java.lang.reflect.Proxy by adding a third import statement:

    import java.lang.reflect.Proxy;

    With this third import statement in place, the source code will compile and have the same behavior as in previous versions.

  2. Generification - Generification is the process of adding generic type parameters and arguments to existing classes and methods in a manner that's consistent with the specifications of those classes. JSR 14 specified the generification of many of the core libraries, in particular the collection classes and the Class class. In the 5.0 Beta 2 release, the effect of the core generification was propagated throughout the rest of the platform wherever possible.

    Most source code that uses generified classes, constructors, methods, and fields will continue to compile in 5.0, though some will not. The simplest workaround for code that fails to compile due to the generification changes is to specify -source 1.4 on the javac command line.

    This item will be updated soon with more details. For information about generics and the core generification, see JSR 14 and the generics tutorial (PDF).

  3. Virtual Machine - Previously, the default virtual machine (VM) for Solaris/SPARC was the client VM. However, many Solaris/SPARC boxes are used as servers, on which the server VM is more appropriate for performance reasons. Thus, as of 5.0, server-class Solaris/SPARC machines run the server VM by default. In general, the throughput of the server VM is much better than the client VM, but the startup time is somewhat worse. A "server-class machine" is currently defined to be one with 2 or more processors and 2 or more gigabytes of memory.

    For more information, see Server-Class Machine Detection and Garbage Collection Ergonomics .

  4. Virtual Machine - To reflect the class sharing feature introduced in 5.0, the property (which is reflected in the text displayed by " java -version") now specifies the sharing mode. Any code that parses all the way to the end of the property value or the output of " java -version" might need to be changed.

    For more information, see bug 4964160 and Class Data Sharing.

  5. Virtual Machine - Previously, evaluating a class literal (for example, Foo.class ) caused the class to be initialized; as of 5.0, it does not. Code that depends on the previous behavior should be rewritten.

    You can use the following code to force initialization of a class:

        //...   Foo.class ... //OLD CODE ... forceInit(Foo.class) ... //NEW CODE
     * Forces the initialization of the class pertaining to 
     * the specified <tt>Class</tt> object. 
     * This method does nothing if the class is already
     * initialized prior to invocation.
     * @param klass the class for which to force initialization
     * @return <tt>klass</tt>
    public static <T> Class<T> forceInit(Class<T> klass) {
        try {
            Class.forName(klass.getName(), true, klass.getClassLoader());
        } catch (ClassNotFoundException e) {
            throw new AssertionError(e);  // Can't happen
        return klass;

    The new behavior is a consequence of the fact that the VM now supports class literals in the constant pool. The old behavior remains in classes compiled with a pre-5.0 compiler or with the -target 1.4 flag, even if run in the 5.0 VM.

    For more information, see Initialization of Classes and Interfaces (section 12.4) in The Java Language Specification . Note that the language specification hasn't changed; it never listed class literal evaluation as an initialization trigger.

  6. Class Loader - Previously, it was possible to specify a non-binary class name to ClassLoader methods that take a String class name argument. This unintended behaviour was not compliant with the long-standing specification of class names. As of 5.0, parameter checking of these ClassLoader methods has been modified to comply with the specification, and any class name that is not a binary name is treated like any other unrecognized class name. Since the APIs that explicitly require or return class names (for example, Class.forName or Class.getName) use the binary name for reference types, it is unlikely that the typical user would have produced a class name that would have returned a Class.

    For more information, see the definition of binary name in the Java Language Specification, Second Edition .

  7. Serialization - Changes in compiler-generated synthetics affect the default serial version UID, and therefore can cause serialization incompatibility when that UID is not explicitly overridden.
  8. Logging - Previously, the java.util.logging.Level(String name, int value, String resourceBundleName) constructor allowed a null name argument, but the parse method did not. In 5.0, the constructor now throws a NullPointerException when the name is null. The compatibility risk is mitigated in that you had to subclass Level to use this constructor and would get a NullPointerException when using a Level name of null for subsequent calls, except for simple calls such as toString.

  9. Apache - The org.apache classes, which have never been supported J2SE APIs but are used by the javax.xml package, have moved in 5.0 to package.internal so that they won't clash with more recent, developer-downloaded versions of the classes. Any applications that depend on the org.apache classes being part of the J2SE release must do one of the following to work in 5.0:

    • Download the org.apache.xalan classes from Apache.
  10. JAXP - The J2SE 1.4 platform included JAXP 1.1 ("Crimson"). The J2SE 5.0 platform includes JAXP 1.3 ("Xerces"). Crimson and Xerces are not simply different versions of the same codebase. Instead, they are entirely different implementations of the JAXP standard. So, while they both conform to the JAXP standard, there are some subtle differences between them.

    Although Crimson was small and fast, it was ultimately less functional than Xerces – an open-source implementation hosted at Apache. In addition, the JAXP standard has evolved from 1.1 to 1.3. These two factors combine to create compatibility issues.

    For details, see the JAXP Compatibility Guide for 5.0.

  11. JAXP - The J2SE 1.4 platform supported the DOM Level 2 API. The J2SE 5.0 platform supports the DOM Level 3 family of APIs. New methods have been added to DOM Level 3 interfaces, so some existing applications using DOM Level 2 will not be able to compile with the new interfaces.

    Many DOM Level 2 applications will run if DOM Level 3 is substituted for DOM Level 2 in the class path; however, a small number will encounter a NoSuchMethodException. Therefore, some applications will not have binary compatibility.

    For details, see the JAXP Compatibility Guide for 5.0.

  12. JAXP - The J2SE 1.4 platform supported the SAX 2.0 API. The J2SE 5.0 platform supports SAX 2.0.2. In general, SAX 2.0.2 is a bug-fix release, with no API changes. However, a few clarifications done as part of SAX 2.0.2 release are possible compatibility issues:

    • ErrorHandler, EntityResolver, ContentHandler, and DTDHandler can now be set to null by applications. SAX 2.0 required the XML processor to throw java.lang.NullPointerException in this case. This change is relevant to the XML processor because most parsers react to null by restoring the default settings.

    • DefaultHandler is a default implementation class for various handlers including EntityResolver. The resolveEntity method implementation in DefaultHandler is now declared as throws IOException, SAXException. Previously it could throw only SAXException.

    • The addition of to the list of exceptions thrown by the resolveEntity method is a source-incompatible change. Specifically, code that invokes resolveEntity might compile successfully with SAX 2.0 but fail compilation with SAX 2.0.2 because it needs to handle IOException along with SAXException.

    For details, see the JAXP Compatibility Guide for 5.0.

  13. JAXP - Previously, Xalan was the default transformer. Since the Apache community has agreed to make XSLTC the default processor for developing XSLT 2.0, XSLTC is the default transformer as of 5.0. Compatibility risks include:

    • Xalan has bugs that XSLTC does not, and vice-versa. Application code that has taken Xalan bugs into account is likely to fail.

    • XSLTC does not support all the extensions that Xalan does. These extensions are beyond the definition of the JAXP and XSLT specifications. For those users impacted by this, the work around of downloading the Xalan classes from Apache is still available. Also, going forward we expect to be supporting more and more extensions in XSLTC.

    For more information, see the JAXP Compatibility Guide for 5.0.

  14. 2D - Previously, passing a null Image parameter to a Graphics.drawImage method resulted in a NullPointerException. As of 5.0, it doesn't. The new behavior allows applications that worked with the Microsoft VM to work with the standard VM. Any applications that depend on the NullPointerException need to be changed so that they'll work in 5.0.

  15. AWT - Previously, only containers that were focus cycle roots could provide a focus traversal policy. As of 5.0, any container can provide a focus traversal policy; the new FocusTraversalPolicyProvider property of Container indicates whether it does.

    The focus traversal policies provided with the Java platform have been changed in 5.0 to accommodate focus traversal policy providers. Specifically, when a policy encounters a focus traversal policy provider during forward (backward) traversal, it should not treat its components as belonging to the provided focus cycle root but should use the focus traversal policy of focus traversal policy provider to get next (previous) component. If the returned component is the same as the first (last) component returned by the focus traversal policy of the focus traversal policy provider, then invoking the policy should get the next (previous) component in the cycle after (before) the focus traversal policy provider. Calculation of "first" and "last" components in focus cycle roots should use the focus traversal policies of focus traversal policy providers when necessary (when a "first" or "last" component is itself a Container and a focus traversal policy provider).

    Because this change doesn't require any new methods in focus traversal policies, third-party focus traversal policies will continue to work, although they will not support the notion of providers.

    If you have written a focus traversal policy and wish to support providers, you need to make changes similar to the ones made to the platform-provided policies in 5.0.

    For more information, see the Focus Traversal Policy Providers section of the focus specification, The AWT Focus Subsystem.

  16. Drag and Drop - Previously, the only drag and drop (DnD) protocol supported on X11 was the Motif DnD protocol. In 5.0, the XDND protocol is also supported, and the Motif DnD protocol has been reimplemented to not depend on the Motif library. It's possible that regressions might be caused by the difference between the new Motif DnD protocol implementation and one provided by the Motif library. However, since the Motif library's implementation is buggy, it's believed that the new implementation is at least as high in quality, as well as better supported.

  17. Swing - Buttons with a customized background color might require code changes to be rendered as intended with the 5.0 Java look and feel theme, Ocean. The reason is that Ocean draws a gradient on buttons, by default. If you don't want the gradient, either set the contentAreaFilled property to true or set the background to a Color that is not a UIResource. In most cases this is as simple as:


    If, for some reason, you are picking up a UIResource you can create a new Color that is not a UIResource like this:

    button.setBackground(new Color(oldColor));

  18. Swing - In JTree and JList it has always been the case that the user manipulates the lead index with the keyboard. For example, if the lead is on row four in a JList and you press the up key, this moves the lead to row three and selects the item there. With these components, then, the lead is considered the "focused" index. They pass information to their renderers indicating whether or not to draw the focus indicator for a given index, and this is based on whether that index is the lead.

    Prior to 5.0, JTable was doing the opposite and using the anchor index in the same manner that JTree and JList use the lead. A request to correct this was made as RFE number 4759422 and eventually fixed as part of 4303294. Now JTable is consistent with JList and JTree. This could affect developers that assumed the previous behavior. For example, consider an application that needs information on what is being shown as the focused cell in a JTable, and it assumes that to be the anchor. While this would be correct pre-5.0, it could now result in determining one index to be focused, when in reality some other index is displaying the focus rectangle.

  19. JVMDI - As of 5.0 the Java Virtual Machine Debug Interface (JVMDI) is deprecated. JVMDI will be removed in the next major release. Any new development should use JVMTI. Existing tools should begin moving to JVMTI.

    For more information, see the JVMTI documentation.

  20. JVMPI - As of 5.0 the Java Virtual Machine Profiling Interface (JVMPI) is deprecated. JVMPI will be removed in the next major release. Any new development should use JVMTI. Existing tools should begin moving to JVMTI.

    For more information, see the JVMTI documentation.

  21. Installation - As of 5.0, the names for directories, bundles, packages, registries, and RPMs have been changed. Scripts that depend on the old pathnames will need to be updated accordingly. The new naming conventions are as follows:

    Old Name New Name
    j2se java
    j2re jre
    j2sdk jdk

    Capitalization is in accordance with platform conventions. Additional platform-specific details follow.


    • The JDK packages install in:

      /usr/jdk/jdk <version>

    • The prefix used for all packages has changed from "SUNWj3" (used in 1.3 and 1.4) to "SUNWj5".


    • The JRE and JDK RPMs install in:

      /usr/java/jre <version>

      /usr/java/jdk <version>

    • The RPM database name is the value displayed in the Name field when doing an RPM query. This value is appended to the Version and Release fields to get the fully qualified name – for example, jre-1.5.0-fcs.

    • The RPM database can be queried to determine what is provided by a given package. The JRE and the JDK both provide "jre" as part of the new naming convention, as well as "j2re" for backwards compatibility. The JDK also provides "jdk" and, for backwards compatibility, "j2sdk". Sun provides the old names in accordance with standard EOL policy, but new third-party scripts and RPMs should use the new convention.


    • The tarball expands to:

      ./jre <version>
      ./jdk <version>

    Microsoft Windows

    • The JRE and JDK install in:

      %ProgramFiles%\Java\jre <version>

      %ProgramFiles%\Java\jdk <version>

    • The registry keys haven't changed. They continue to use the full names of "Java Runtime Environment" and "Java Development Kit".

    For more information, see J2SE 5.0 Name and Version Change.

  22. JDBC - As of 5.0, comparing a java.sql.Timestamp to a java.util.Date by invoking compareTo on the Timestamp results in a ClassCastException. For example, the following code successfully compares a Timestamp and Date in 1.4.2, but fails with an exception in 5.0:

    aTimeStamp.compareTo(aDate) //NO LONGER WORKS

    This change affects even pre-compiled code, resulting in a binary compatibility problem where compiled code that used to run under earlier releases fails in 5.0. We expect to fix this problem in a future release.

  23. Language - With the addition of typesafe enums to the Java language in 5.0, enum is now a keyword and can no longer be used as an identifier.

    A workaround is to specify -source 1.4 on the javac command line. That disables all the language features added in 5.0, allowing code that uses enum as an identifier to compile.

  24. Language - The J2SE 5.0 BigDecimal's toString() method behaves differently than in earlier versions. Also see J2SE 5.0 toString() and J2SE 1.4.2 toString().

    J2SE 5.0 added toPlainString() to BigDecimal, which behaves exactly like the toString() method in earlier versions.