EclipseでJigsawしてみる その2
というわけで続きです。
jar作成死闘編
ようやくjdk9-eaの設定に成功したので、コードを書いていきましょう。
今回は、ライブラリ用のプロジェクトとそれを使うアプリケーションのプロジェクトの二つを準備しました。
まずは、ライブラリ用のプロジェクト。
package lib; import lib.util.LibUtil; public class Lib { public static void outputTextLib() { System.out.println("Libですよー。"); LibUtil.outputTextUtil(); } }
LibUtil.java … 外部には公開したくない、Lib.javaが参照するユーティリティクラス(という設定
package lib.util; public class LibUtil { public static void outputTextUtil() { System.out.println("LibUtilですよー。"); } }
module-info.java … 公開パッケージを記載する
これ、module lib のlibのところはモジュール名なので、適当な名前をつけてよいらしい。
(偶然パッケージ名とおなじになっているだけ)
module lib { exports lib; }
んで、module-info.javaをsrc直下に置くわけだけども、EclipseのNew→New Java Classで作成すると
『Type name is not vaild』って怒られるのね。(クラス名に"-"が入っているから当たり前か)
なので、New→New Fileで作りました。
このページにも、そうせよと書いてある。
Eclipse and Jigsaw modules - Eclipsepedia
で一通り、ファイルはできたのでコンパイルしてjarにまとめたいんだけど jarのExportが、下のエラーでどうあがいてもできないわけですよ。
『JAR creation failed. See details for additional information. Class files on classpath not found or not accessible for: 'Lib/src/module-info.java'』
クラスファイルがないだと・・・?
と、binフォルダの下を見るとしっかりmodule-info.classがあるわけですよ。
しばらく調べてもよくわからなかったので、悔しいけれど、コマンドでjarを作ります。
いつものjarコマンドとは違うやり方が必要だった気がするので、jar --helpでコマンドを調べてみます。
# 2つのクラス・ファイルを含むclasses.jarというアーカイブを作成する: jar --create --file classes.jar Foo.class Bar.class # foo/のすべてのファイルを含む、既存のマニフェストを使用したアーカイブを作成する: jar --create --file classes.jar --manifest mymanifest -C foo/ . # モジュラjarアーカイブを作成する。モジュール・ディスクリプタはclasses/module-info.classに # ある: jar --create --file foo.jar --main-class com.foo.Main --module-version 1.0 -C foo/ classes resources # 既存の非モジュラjarをモジュラjarに更新する: jar --update --file foo.jar --main-class com.foo.Main --module-version 1.0 -C foo/ module-info.class # 複数リリースjarを作成し、一部のファイルをMETA-INF/versions/9ディレクトリに配置する: jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes
うーん、ようわからん。
とりあえず--createを付ければいいんかな。
C:\Users\takeda\eclipse-workspace\Lib\bin>"C:\Program Files\Java\jdk-9\bin\jar.exe" --create --file=lib.jar .
動作確認編
とりあえず、jarはできたので、アプリケーションのプロジェクトにインポートしてみる。
App.java … メインクラス
package app; import lib.Lib; public class App { public static void main(String[] args) { Lib.outputTextLib(); } }
module-info.java … 依存するモジュール名を記載する (偶然パッケージ名とおなじになっているだけ)
module app { requires lib; }
で、コンパイル後に実行するわけだけれどもlibパッケージが見えなくてエラーが出ている。
そういえば、設定を一つ忘れていたな…
Java 9 Support for Oxygen | Eclipse Plugins, Bundles and Products - Eclipse Marketplace
added to the .classpath manually: <classpathentry kind="con" path="org.eclipse.jdt.MODULE_PATH"/>
モジュールの依存関係をクラスパスに追加せよとのこと。
プロジェクトフォルダ直下の.classpathファイルに追記する。
<?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="src"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-9"/> <classpathentry kind = "con" path = "org.eclipse.jdt.MODULE_PATH" /> <classpathentry kind="lib" path="C:/Users/takeda/eclipse-workspace/App/lib/lib.jar"/> <classpathentry kind="output" path="bin"/> </classpath>
んで、読み込みなおしのためワークスペース開きなおし。
お、若干参照するライブラリの表示が増えている。
もう一度、コンパイル&実行。
Libですよー。 LibUtilですよー。
長い、戦いだった… 肝心のLibUtilのほうが参照できないか確認してみましょう。
お、参照できない。
素晴らしい。
まとめ
2017/5/23時点での内容です。
Java 9、Eclipse Oxygen共に正式リリースまでには、もっと使いやすくなると思います。
・Eclipseの現行バージョンNEONでは、Jigsawできないので開発中の次バージョンOxygenを使う
・Oxygen単体では、Java9が使用できないので『Java 9 Support (BETA) for Oxygen』プラグインを入れる
・そのうえで、モジュール化するなら、クラスパスに追加設定が必要
・Eclipseからは、module-infoを使ってのjar作成は無理(?)なので、コマンドでつくる
・コマンドでjarを作成する場合は、いつものコマンドに『--create』をつける
2017/10/7追記
ようやくOxygen a1でJava9対応するらしいので、試してみました。
完結編です。