Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[eclipse-dev] Clarification on Java compiler 1.4 compliance

The Eclipse Java Compiler is by default a JDK 1.3.compliant compiler, but
it can be toggled
into a JDK 1.4 compliant one, using a new setting added onto the Java
Compiler preference page
(see Workbench>Preferences>Java>Compiler>JDK Compliance>Compiler Compliance

Eclipse Java Compiler is roughly the union of a JDK1.3 and a JDK1.4
compilers. Using the compliance
level setting, you can choose which one you want to use for building Java
programs. In 1.3 mode, it is
100% JCK1.3a compliant, and in 1.4 mode it is 100% JCK1.4 compliant. Now,
this being said, you have
to understand that these are not equivalent, and in particular may raise
some issues in the following areas:

      a) Source and VM compatibility
      b) Assertions
      c) Default abstract methods
      d) Access to enclosing fields or methods (in innerclass)

As a consequence:
- code which used to compile clear in 1.3 mode may be rejected by the 1.4
- when compiling in 1.4 mode, classfiles will not run on some 1.3 VMs.

NOTE: when compiling in 1.3 (default) mode against 1.4 class libraries
(rt.jar), some new errors
could be diagnosed. This is a bug, which we will soon release a fix for

If you need to know more, then please read below:

a) Source and VM compatibility
      In between 1.3 and 1.4, the language has changed to include a new
keyword 'assert'. Now,
      1.4 compilers can optionally either accept 1.3 or 1.4 sources. This
is the source level setting
      (see Workbench>Preferences>Java>Compiler>JDK Compliance>Source
      Assertions are only available in 1.4 compliant mode, with source
level 1.4 (see (b) for further
      information about assertions).

      Classfiles are tagged with a version number, which will be recognized
by Java VMs, so as to
      deal with compatibility issues. Java VMs are backward compatible with
earlier classfiles, but
      will reject newer ones (e.g. 1.1 VMs will refuse to run 1.4
classfiles). This is reflected by the
      target VM settings which allow to manually target a specific VM level
(see Workbench>
      Preferences>Java>Compiler>JDK Compliance>Generated .class files
      1.3 compilers usually target 1.1 level VMs, but manually you may want
to enforce your classfiles
      to be run onto a 1.3 VM only by changing this setting to 1.3.

      In 1.4 compliance mode, if the source level is also set to 1.4, then
the classfile level must be
      set to 1.4 as well. This is a runtime requirement, since 1.4
assertions needs special runtime
      support. JDK 1.4 libraries are 1.4 classfile level, whereas previous
ones where 1.1 level
      (i.e. JDK1.3.1 class libraries are 1.1 classfile level).

b) Assertions
      In 1.4 compliance mode and source level is 1.4 too, then if your code
contains some #assert(...)
      methods, then they will be reported with syntax errors, since
'assert' is now a reserved keyword
      from 1.4 on. Note that in 1.3 compliant mode, there is an option you
can set so that the compiler
      will highlight usage of 'assert' as an identifier. (see
      JDK Compliance>Report 'assert' as identifier).

      Last but not least, if using 1.4 assertions, you need a 1.4 JRE in
order to run your code (need
      new type AssertionError) and to     specify the VM line argument '
-ea' to enable assertions at runtime.
      Running against a non 1.4

c) Default abstract methods
      Classfile compatible with 1.2 classfile level and above are no longer
containing any default
      abstract methods. These synthetic methods used to be added onto
abstract classes, and
      were abstract declarations of methods declared by implemented

      e.g. when compiling the following program using 1.1 classfile level,
a #foo() abstract method is
            produced onto type A.

            interface I {
                  void foo();

            abstract class A implements I {
                  /* public abstract void foo(); */

      Our Eclipse 1.3 compiler did take advantage of these default abstract
methods when looking
      up method definitions, since they can avoid walking interface
hierarchies when the receiver type
      is not an interface, relying on the default abstract method to be
used instead.
      This is being changed, see bug

d) Access to enclosing fields or methods (in innerclass)
      From 1.4 compliance mode on, inherited members always take precedence
over enclosing
      ones, changing the compiler diagnosis were 1.3 would report

            class X {
                  void bar(int i){}
                  void baz(int i){}

            class Y {
                  void bar(boolean b){}
                  void baz(int i){}

                  void foo(){
                       new X(){
                        void foo(){
                              bar(0);           // ok in 1.4, ambiguous in
                              baz(0);           // ok in 1.4, ambiguous in
                              bar(false); // not applicable in
1.4 and 1.3

Back to the top