Eclipseで古いJava用のプログラムを開発する?

通常は、開発環境としてJava8を選択しているのだが、時としてJava6を選択したい場合もある。Java6でも動作するプログラムとしてリリースしたいからだ。このような時にはEclipseをどう設定すれば良いのだろうか?

今現在、Eclipseの環境としてJava8が選択されているものとし、次のようなコードを書いてみる。

  String sample() {
    test(()-> {});
    return Arrays.stream(new String[] { "A", "B" }).collect(Collectors.joining());
  }

  void test(Runnable run) {    
  }

問題としては、Java6に準拠すること。つまり、

  • ラムダ式は使えなくなるはず
  • ストリームは使えなくなるはず

ラムダ式を使えなくする

まずは、プロジェクトプロパティのJava CompilerのJDK Complianceの値を変更する。図では1.8になっているが、これを1.6にする。

すると、次のようにラムダ式に対して文句を言い出すことになる。

しかし、相変わらず、ストリームライブラリは使えてしまうようだ。

ストリームを使えなくする。

これには、いわゆる「言語設定」だけではなく、ライブラリを変更しないといけないようだ。つまり、言語設定を変えただけでは、相変わらずJava8のライブラリが使えてしまい、文句を言われることは無い。

これを行うには、あらかじめ、Window>PreferencesメニューでJDKを登録しておかないといけない(後からもできるのだが、ここで行う方がよいだろう)

その後に、当該プロジェクトのJava Build Pathを開き、Add Library>JRE System Libraryを選択し、Java6のライブラリを追加する。

ビルドパスが以下のような状態になるので、後はJava8の方を削除すればよい。

すると、ストリームライブラリの方もエラーになる。

わざとエラーにするというのも不思議なものだが。。。。

ついでにgradleをJava6に準拠させる。

これは簡単だ、単純に以下のように書けばよい。

sourceCompatibility = 1.6
targetCompatibility = 1.6

しかし、なぜ二つも指定があるのだろうか?理由がわからない。同じ疑問を持つ人はいるものだ。

Gradle, “sourceCompatibility” vs “targetCompatibility”?

要するにソースコードのバージョンと生成バイトコードのバージョンということらしいが、これを別の物にする理由は無いと思うだが。。。

ちなみに、これらを設定しても、コンパイル時のライブラリとして上位のJavaを使っていれば、相変わらず問題なくコンパイルできてしまい。実行時にはじめてMethodNotFoundException やClassNotFoundExceptioが出るようだ。

が、gradleのコンパイル時にライブラリを明示的に指定する方法はまだ見ていない。Eclipse側でライブラリをJava6にしておけば、何にしても上位のライブラリ機能は使えないので。