takeda_san’s blog

JavaFXと機械学習を頑張る方向。

EclipseでJigsawしてみる その2

というわけで続きです。

takeda-san.hatenablog.com

jar作成死闘編

ようやくjdk9-eaの設定に成功したので、コードを書いていきましょう。

今回は、ライブラリ用のプロジェクトとそれを使うアプリケーションのプロジェクトの二つを準備しました。
まずは、ライブラリ用のプロジェクト。

f:id:takeda_san:20170523225308p:plain

Lib.java … 外部公開API用のクラス

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はできたので、アプリケーションのプロジェクトにインポートしてみる。

f:id:takeda_san:20170523231602p:plain

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 (BETA) 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>

んで、読み込みなおしのためワークスペース開きなおし。

f:id:takeda_san:20170523233236p:plain

お、若干参照するライブラリの表示が増えている。
もう一度、コンパイル&実行。

Libですよー。
LibUtilですよー。

長い、戦いだった… 肝心のLibUtilのほうが参照できないか確認してみましょう。

f:id:takeda_san:20170523233535p:plain

お、参照できない。
素晴らしい。

まとめ

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』をつける