Index
[]
Index
[]
Index
[]
Index
[]
Index
[]
Index
[]
Index
[]
Index
[]
Index
[]
Index
[]
Index
[]
Index
[]
Index
[]
Index
[]
Index
[]
Index
[]
Index
[]subclass [See ]
Index
[]
Index
[]
Index
[]
Index
[]
Index
[]
Appendix A. Application Evolution
With every passing hour our solar system comes 43,000 miles closer to globular cluster M13 in the constellation Hercules, and still there are some misfits who continue to insist that there is no such thing as progress.
Ransom K. Ferm
The Java platform has undergone a number of changes since it was first introduced, but none more significant than those that occurred with the 5.0 release. While in general we try to avoid issues concerning the evolution of the platform, it is impossible to ignore those issues now. For some time to come, there will be applications and libraries that still comply with the older 1.3 version of the platform (as documented in the third edition of this book), those that support the additional features introduced in the 1.4 release, and finally those moving forward to take full advantage of the new features of the 5.0 release. The technical issues involved in application evolution and migration can be complex, and many of the changes to the language and libraries for the 5.0 release were designed with backward compatibility and migration in mind. A full coverage of the technical issues, let alone the management and logistics issues involved, is beyond the scope of this book, but we do want to highlight a couple of areas for your consideration.
The first section gives a brief overview of how the compiler and virtual machine can deal with different versions of the language and runtime. Next, we look at some ways of dealing with the different dialects that language changes produce, using assertions as an example. Finally, we look at some of the issues involving the integration of generic and non-generic code.
A.1. Language, Library, and Virtual Machine Versions
Each new release of the Java platform potentially changes three things:
The language itself, through the addition of new keywords or extensions to the use of existing keywords
The libraries: new types and/or new methods on existing types
The virtual machine, and in particular the format of the compiled classes that the virtual machine expects
Not every new platform release changes all threein particular, changes to the class format occur rarely because of the major impact such changes can have.
The compiler that comes with the Java Development Kit (JDK) tracks changes to the language and virtual machine through the use of "source" and "target" options that can be passed to it. By supplying an appropriate source and target pair you can compile code that will run on current or older versions of the virtual machineassuming the code is compatible with the source version of the language chosen.
The different source versions and their approximate meaning are as follows:
1.1 The oldest recognized definition of the language, which included the original language definition together with nested types and blank final variables. This source version is no longer supported by the compiler in the 5.0 release.
1.2 Introduced the strictfp modifier.
1.3 Same as 1.2; this version number was added for consistency.
1.4 Introduced assert .
1.5 Introduced generics, enums, annotations, and extended for loop. Also uses StringBuilder rather than StringBuffer for string concatenation.
Similarly, the target versions are
1.1 Compliant with the first edition of the Java Virtual Machine Specification ( JVMS )
1.2 Compliant with the second edition of the JVMS . The main change involved the way static member accesses were encoded in the compiled class and resolved at runtime.
1.3 No known change
1.4 No known change
1.5 Compliant with the third edition of the JVMS . This enables support for enums, annotations, and some aspects of generics. It also modifies the way class literals are implemented.
Because some language changes require new library classes, a change in the source version may imply a minimum target value. For example, a source of 1.4 requires a target of 1.4 because an earlier version of the virtual machine won't have the classes or methods that support assertions. Not surprisingly, a source of 1.5 requires a target of 1.5 as well. Naturally, source and target versions that came into existence after a given compiler was released are not supported.
Each target version causes a change in the class file version number that is encoded in the compiled classes. Each virtual machine knows what class versions it supports and will generally refuse to load any class files that have a higher version number. This means, for example, that you can prevent a class from being loaded on an older virtual machine even if there is no missing functionality in the version.
The default settings for the compiler in the 5.0 release are source 1.5 and target 1.5 to enable all the latest features of the language. If you compile code to run on previous versions (which doesn't use the new features of course) you'll need to explicitly set the target to a suitable earlier version.
A.2. Dealing with Multiple Dialects
Adding new keywords to the language runs the risk of breaking existing code, especially if the word is an identifier as common as "assert" or "enum." The choice to add a new keyword creates some interesting and important compatibility issues. Taking assertions as an example, you can choose whether or not assert is recognized in your code by selecting a source version of 1.4 or higher. This allows you to keep your old use of "assert" in one class, while using the language assertions in anotherprovided the different uses are independent. When asserts were introduced in the 1.4 release, the default source version was left at 1.3 so by default nothing changed and you had to explicitly tell the compiler when you were ready to use the new language feature. In the 5.0 release the presumption is that everyone will want to use at least some of the new features, so they are enabled by defaultif you don't want them you must either specify the appropriate source version or use an older version of the compiler.
[1] The keyword strictfp was added to the language in the 1.2 release but caused almost no problems because nearly nobody had ever used it as an identifier.
These side-by-side dialects can create problems. With only one dialect you could use the same compiler, and the same compiler options, on all your source code. With two or more dialects you might have some source files that require assert or enum and others that reject it. You will have to compile your source carefully to handle such a situation. At this point, there are three dialects: with assert and enum (5.0), with assert but not enum (1.4), and without either (1.3 and earlier).
The obvious solution is to use a single dialect for all your source. But you will not always have that kind of control. If you are using source produced by another group they may have moved on while you cannot, or vice versa.
This is deeper than you might hope. Suppose you have two source files, Newer.java which uses the assert keyword and Older.java which uses "assert" as a method name. If the newer class depends on the older and neither has yet been compiled, compiling Newer.java will attempt to compile Older.java as well. With only one dialect this is a feature. But with the incompatible dialects you will be unable to compile Newer.java until you have already compiled Older.java under the non- assert dialect. This complicates your build process because the order in which you compile things has now become significant.