
Wednesday August 05, 2009
Source, target, class file version decoder ring
Correct usage of javac's -source and -target settings is important to generate class files with the required properties. As Alex has written recently, the compiler's source and target settings interact with various other versioned aspects of the platform.
The primary effect of the -source option is to select which
version of the Java Programming Language to accept and the primary effect of the -target option is to specify the class file version to output.
The first table below summarizes the default source and target settings used by javac in different JDK releases when no explicit -source or -target options are specified. As explained Cross-Compilation Options section of the javc man page, the default target varies depending on the source setting.
In the beginning and through the JDK 1.1 series, javac only had single (implicit) source and single (implicit) target setting.
One feature of how inner
classes were added in 1.1 was that the class file format did not
need to be changed. Therefore, 1.1 and 1.0 share the same target setting. Other subsequent language changes have required later class file versions to be used, sometimes only to force the availability of platform features rather than to intrinsically use new features of the class file format itself.
In JDK 1.2, the strictfp modifier was added to the language and to the new class file format selected with target 1.2. The javac in JDK 1.2 always accepts the new keyword, but only generates the new class files supporting the feature if explicitly requested with the -target 1.2 option. Likewise, the JDK 1.3 releases only accept a single implicit source level, unchanged from 1.2, but accept targets ranging from 1.1 to 1.3, with a default of 1.1.
The 1.4 source version added an assert keyword so there was a practical
need to be able to compile existing code that happened to use "assert"
as an identifier in addition to the new
uses of the assert language construct. Therefore, an explicit -source flag was added in JDK 1.4 and retained in subsequent JDK releases.
In JDKs 5 and 6, new source and target settings were added. The 1.5 and 1.6 target settings correspond to distinct class file versions; the 1.5 and 1.6 source settings are nearly identical. As an operational difference, javac handles encoding problems differently under those two source levels; an encoding problem generates a warning with source 1.5 but is treated as an error with source 1.6. There is a small semantic difference between the handling of the @Override annotation in the two source levels, but fully elaborating the complications around @Override, source settings, and JDK versions is a story for another day.
The default source and target javac applies in JDK 7 were recently
upgraded to source and target 7; previously
the same defaults as in JDK 6 were used.
Default javac Source and Target Settings
† JDK 1.4.0 and 1.4.1 only accepted source 1.3 and 1.4. |
| JDK/J2SDK |
Default Source |
Source Range |
Default Target |
Target Range |
| 1.0.x |
1.0 |
— |
1.1 |
— |
| 1.1.x |
1.1 |
— |
1.1 |
— |
| 1.2.x |
1.2 |
— |
1.1 |
1.1 - 1.2 |
| 1.3.x |
1.2/1.3 |
— |
1.1 |
1.1 - 1.3 |
| 1.4.x |
1.2/1.3 |
1.2† - 1.4 |
1.2 |
1.1 - 1.4 |
| 5 |
1.5 |
1.2 - 1.5 |
1.5 |
1.1 - 1.5 |
| 6 |
1.5 |
1.2 - 1.6 |
1.6 |
1.1 - 1.6 |
| 7 |
1.7 |
1.2 - 1.7 |
1.7 |
1.1 - 1.7 |
Given the same source code, compilers from different releases configured to use the same source and same target
(and same bootclasspath!)
can still generate different class files because of bug fixes or changes to compiler-internal contracts.
An example of a bug fix, javac -target 1.2 in JDK 1.4.2 elides Miranda methods, extra methods synthesized by the compiler to work around early JVM bugs calling interface methods.
Evidence of Miranda methods and other past sins are recorded in javac's
sun.tools.java.jvm.Target class.
One compiler-internal contract that has evolved over time is the idiom used to access private members of an enclosing class.
While often updated in small ways, the fundamental structure of class files has been very stable across many releases. The first new bytecode, invokedynamic, is being added in JDK 7; although the pair of jsr/ret bytecodes was effectively removed as of target 1.6. The most common way to add capabilities to the class file format has been the addition of new predefined class file attributes; see table 4.6 in the draft of the Java VM Specification, Third Edition for more information.
The table below shows the mapping of javac target settings to class file major.minor version numbers.
Mapping of Targets to Class file major.minor numbers
| Target |
Major.minor |
Description |
| 1.1 |
45.3 |
The original shipped version. |
| 1.2 |
46.0 |
Supports the strictfp
modifier. |
| 1.3 |
47.0 |
Small update. |
| 1.4 |
48.0 |
Small update. |
| 5 (1.5) |
49.0 |
New
attributes to support generics and other features. Many more
strings accepted as legal identifiers. |
| 6 (1.6) |
50.0 |
StackMaps
are supported. |
| 7 (1.7) |
51.0 |
invokedynamic
is supported. |
(2009-08-05 19:14:59.0)
Permalink