Browse DevX
Sign up for e-mail newsletters from DevX


Onward and Upward: Porting Apps to Higher JDK Versions : Page 3

Porting an existing Java-based application to a new JDK version is not as easy as many assume. Learn a comprehensive, systematic approach that can ensure a smooth process.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

What Exactly Do I Need to Port?
Once you decide to go ahead with porting, your next step is to finalize what all needs to be migrated and determine their priorities. In order to ensure a smooth porting process, you must decide this and finalize your approach during the early stages of the project.

To help sort out your priorities, JDK changes can be broadly classified into four categories:

  • Incompatibilities
  • Improvements
  • Deprecated API
  • New features in JDK

These changes can be introduced in Sun APIs as well as JDK APIs. Ideally, you should not use sun.* packages because Sun intends them only for their own usage. If you are using or extending a sun.* API in your application, be ready to port the changes or incompatibles introduced in it.

Sun technically classifies the compatibility between two JDK release versions as either binary compatibilities or source compatibilities. Binary compatibilities exist when the compiled code can run with the other version of the JDK. Source compatibility means the source code can comply and run with the other version of the JDK.

Binary compatibility has two types:

  • Upward—when compiled code can run with a higher JDK version
  • Downward—when compiled code can run with a lower JDK version

Similarly, source compatibility also has two types:

  • Upward—when source code can comply and run with a higher version the JDK
  • Downward—when source code can comply and run with a lower version of the JDK

In general, maintenance releases (e.g., JDK 1.4.1 and 1.4.2) support both upward and downward compatibility at the binary and source levels. The functional releases (e.g., JDK 1.3 and 1.4) support upward compatibility at both the binary and source levels, except for Sun's stated incompatibilities. However, they do not guarantee downward compatibility at either level.

Removing the incompatibilities in the targeted JDK release is the top priority when porting your application, and it qualifies as the only MUST DO activity. Some of the incompatibilities you'll find are changes in the existing interfaces, constants, exception handling, introduction of keywords (e.g., JDK 1.4 introduced assert), and removal of some methods and constants (mainly in sun.* packages). In most cases, you can compile and run code written in JDK 1.1 with JDK 1.2, 1.3, 1.4, and 1.5, as long as you don't use any statements/APIs listed as part of the incompatibilities.

For more details about incompatibilities visit java.sun.com. The following are some other helpful links:

JDK improvements could be lumped in the new features category, but for a clear distinction and a better understanding of tasks, it's better to view them as a separate task. Although these activities aren't mandatory for making your application portable, from the performance, optimization, and best practices points of view, all the changes in this category are required. Before performing all the improvement changes, however, you must weigh the trade-off between the time and effort they require and the improvement you expect to get out of them.

A few of the suggested improvements for different JDK versions are:

  • With JDK 1.1, use GregorianCalendar instead of java.util.Date for wider acceptability.
  • With JDK 1.2, use Arraylist instead of Vectors, if you are not required to synchronize.
  • With JDK 1.3, use the Timer class for scheduling future execution in a background thread instead of your own implementation.
  • With JDK 1.4, the Preference API is better than the properties file for managing user preferences and configuration data.

Deprecated API
Deprecation APIs are those that have been restructured and modified with new classes and methods that provide similar functionality. In general, whenever an API is deprecated, an alternative implementation is provided and information about it is offered in the API's javadoc. Sun warns its users to withdraw support for deprecated APIs in future releases. Whenever possible, you should modify your application to remove references to deprecated methods/classes and to use the new alternatives. Deprecated APIs support methods and classes only for backward compatibility, and your Java compiler will generate a warning whenever you use them.

Marking something as deprecated is only one aspect of documentation and is not part of the OO paradigm. Deprecation also is not inherited, so you can still override a deprecated method without treating the subclass methods as deprecated methods. For example, say Class X has a deprecated method called getStringValue(), and Class Y extends Class X, overriding the getStringValue () method. While compiling test client TestX, which creates an instance of Class X and calls getStringValue(), the compiler generates a warning. However, while compiling test client TestY, which creates an instance of Class Y and calls getStringValue (), it doesn't generate a warning.

You could treat a deprecated API as part of source compatibilities, but you should consider it a separate activity. Currently, you don't have to eliminate the usage of deprecated APIs in order to port applications. In fact, the deprecated APIs from JDK 1.1 are still available in JDK 1.5 (J2SE 5). However, Sun still may withdraw their support in future releases.

Click here for a complete list of deprecated APIs still available in JDK 1.5.

New Features in JDK
Every major JDK version release provides new features in the form of new APIs and/or extensions to existing APIs. The following are some of the major features introduced in respective JDK versions:

  1. JDK 1.1 introduced inner classes.
  2. JDK 1.2 introduced swings, JDBC 2.0, and changes in Java security.
  3. JDK 1.3 introduced JNDI, RMI-IIOP, Java Sound, enhanced the Collection framework, and completed swings.
  4. JDK 1.4 introduced the JAAS Preferance API, the Logging API, JDBC 3.0, the assertion facility, and Regular expression.
  5. JDK 1.5 introduces major changes at the language level including autoboxing/unboxing, enhanced for loop, static import, typesafe enums, and varargs.

Figure 2. JDK Releases and the Major Feature They Introduced

For a list of new features in your targeted JDK, refer to its javadoc.

Effectively using the targeted JDK's new features, as well as its enhanced existing features, in your existing application is part of the porting process. Sometimes, using newly added features ends your dependency on third-party software/APIs (e.g., companies that previously used log4j for logging can now use the logging facility in JDK 1.4 instead). However, if you use new features just to enhance your existing application, then it's an enhancement activity rather than a porting activity. Enhancement activities should not be included as part of the porting process because they may lead to some regressions in existing functionality, and then determining whether these problems are because of the porting activity or because of the enhancement becomes very difficult. Still, whether or not to go for the new features is purely dependent on your business requirements. It is not a mandatory part of the porting task.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date