2015/12/13

JRE をカスタマイズ - jlink

このエントリーをはてなブックマークに追加

この記事は、Java Advent Calendar 2015 の 13 日目の記事です。

昨日は @cero_t さんのStream APIをつくろう でした。明日は opengl_8080 さんです。

 

JavaOne にいってから、Project Jigsaw で遊ぶことが多くなりました。で、モジュールを作った後の話を紹介します。ちょうど、JavaFX in the Box の方の このエントリー の後の話題のようなものです。

このエントリーでは JavaFX のサンプルのモジュールの依存性を調べたのですが、せっかく依存性を調べたのですから、モジュールを作ってみましょう。

サンプルはこれです。

package fxdemo;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Font;
import javafx.stage.Stage;

public class FXDemo extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        Label label = new Label("Label");
        label.setFont(Font.font(24));
        
        StackPane root = new StackPane(label);
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.setTitle("FXDemo");
        stage.show();
    }
    
    public static void main(String... args) {
        launch(args);
    }
}

このサンプルが依存しているのは、java.base モジュール、javafx.controls モジュール、そして javafx.graphics モジュールです。ですので、module-info.java は次のようにしました。

module fxdemo {
    requires javafx.controls;
    requires javafx.graphics;
}

では、コンパイルして、モジュールを作ってみましょう。ソースは src ディレクトリ、クラスは bin ディレクトリ、モジュールは mods ディレクトリに置くとしましょう。

C:\fxdemo>javac -d bin src\module-info.java src\fxdemo\FXDemo.java

C:\fxdemo>jar --create --file mods\fxdemo.jar --module-version 1.0 -C bin .

これで、モジュールができました。JAR ファイルなので、これだけだとモジュールかどうかよく分からないのが玉にキズ。

では、実行してみましょう。

C:\fxdemo>java -mp mods -m fxdemo/fxdemo.FXDemo
Exception in Application constructor
Exception in thread "main" java.lang.RuntimeException: Unable to construct Appli
cation instance: class fxdemo.FXDemo
        at com.sun.javafx.application.LauncherImpl.launchApplication1(javafx.gra
phics@9-ea/LauncherImpl.java:926)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$138(
javafx.graphics@9-ea/LauncherImpl.java:220)
        at java.lang.Thread.run(java.base@9-ea/Thread.java:747)
Caused by: java.lang.IllegalAccessException: class com.sun.javafx.application.La
uncherImpl (in module javafx.graphics) cannot access class fxdemo.FXDemo (in mod
ule fxdemo) because module fxdemo does not export fxdemo to module javafx.graphi
cs
        at sun.reflect.Reflection.throwIllegalAccessException(java.base@9-ea/Ref
lection.java:452)
        at sun.reflect.Reflection.ensureMemberAccess(java.base@9-ea/Reflection.j
ava:135)
        at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(java.base@9-
ea/AccessibleObject.java:370)
        at java.lang.reflect.AccessibleObject.checkAccess(java.base@9-ea/Accessi
bleObject.java:362)
        at java.lang.reflect.Constructor.newInstance(java.base@9-ea/Constructor.
java:435)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$144
(javafx.graphics@9-ea/LauncherImpl.java:838)
        at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$158(javafx.
graphics@9-ea/PlatformImpl.java:351)
        at com.sun.javafx.application.PlatformImpl.lambda$null$156(javafx.graphi
cs@9-ea/PlatformImpl.java:320)
        at java.security.AccessController.doPrivileged(java.base@9-ea/Native Met
hod)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater$157(javafx.gr
aphics@9-ea/PlatformImpl.java:319)
        at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(javafx.graphics@9-e
a/InvokeLaterDispatcher.java:96)
        at com.sun.glass.ui.win.WinApplication._runLoop(javafx.graphics@9-ea/Nat
ive Method)
        at com.sun.glass.ui.win.WinApplication.lambda$null$130(javafx.graphics@9
-ea/WinApplication.java:191)
        ... 1 more

C:\fxdemo>

あれ、動かない。

まぁ、理由は簡単で、module-info.java に exports の項を書かなかったためです。このサンプルは外部から使うわけではないと思ったわけですが、実行するということは main メソッドを外部から呼ぶことになるため、exports が書いてないと実行できないのです。

ということで、module-info.java を次のように書きかえました。

module fxdemo {
    requires javafx.controls;
    requires javafx.graphics;

    exports fxdemo;
}

これで、同じようにコンパイルして、モジュールを作ったら、無事に実行できました。

Jigsaw で実行する場合は、-modulepath もしくは -mp でモジュールがおいてあるディレクトリを指定し、-m でメインクラスを指定します。この時、[モジュール名]/[クラス名] のようにモジュールとクラス名を / で区切って併記するようにします。

さて、これでモジュールができたので、次にこのサンプルのモジュールと最小限のモジュールを含む JRE を作ってみましょう。

それをやるには jlink コマンドを使用します。

C:\fxdemo>jlink --modulepath mods;"c:\Program Files\Java\jdk-9\jmods" --addmods
fxdemo --output fxdemo

オプションはだいたい分かると思いますが、--modulepath でモジュールのディレクトリを指定します。サンプルのモジュールだけでなく、JDK のモジュールの場所も指定しておきます。--addmods が追加するモジュールです。javafx.controls モジュールなどを追加しないのは、依存性の記述から勝手にやってくれるからです。

そして、fxdemo ディレクトリにイメージを作成します。このディレクトリには bin、conf、lib のディレクトリを作成します。

bin ディレクトリには java コマンドがあるので、どういうモジュールがあるか調べてみましょう。

C:\fxdemo\fxdemo\bin>java -listmods
fxdemo@1.0
java.base@9-ea
java.datatransfer@9-ea
java.desktop@9-ea
java.instrument@9-ea
java.logging@9-ea
java.management@9-ea
java.naming@9-ea
java.prefs@9-ea
java.rmi@9-ea
java.security.sasl@9-ea
java.xml@9-ea
javafx.base@9-ea
javafx.controls@9-ea
javafx.graphics@9-ea
jdk.jfr@9-ea
jdk.vm.ci@9-ea

javafx.controls モジュールなどの依存性も解決することで、必要最低限のモジュールを導入した JRE を作成することができました!

2015/11/20

現場で使える[最新]Java SE 7/8 速攻入門

このエントリーをはてなブックマークに追加

Java に関する本をはじめて書きました!

内容は Java SE 7 と Java SE 8 の主要な新機能である以下のトピックだけに特化して紹介した本です。

  • Project Coin
  • NIO.2
  • Project Lambda
  • Date and Time API

今まで続けてきた ITpro の連載の中から、Java SE 7 と Java SE 8 のトピックをまとめたような内容ですが、実際にはすべて書き下ろしです。

でも、連載と掛け持ちしていたり、講演などをしていたりすると、すぐにスケジュールが遅延してしまって... 当初の予定だと去年の今ごろ出版されていたはずなんですが ^ ^;;;

ほんとうに編集の方にはご迷惑をおかけしました。

たまたまなのですが、ITpro の連載が 5 月に終わったので、その後はかなり集中して書くことができました。

とはいうものの、JavaOne に旅立つ成田空港でもまだ校正をやっていたりと、ほんとにギリギリまであがいていました。徹夜して飛行機に乗って、サンフランシスコ着いたら体調悪化して寝込んだりしてました。飛行機の中では爆睡していたんですけど、寄る年波には勝てないです。

まぁ、それでも無事に出版することができてほんとよかったです。

Java SE 8までカバーしている本は何冊かあると思いますが、Project Lambda についてここまで書いた本は他にはないと自負しております。

今まで、いろいろなところで Project Lambda の講演やハンズオンをやってきました。参加された方たちからは、その場ではなんとなく分かったような気になっても、いざ自分でラムダ式や Stream API を使って書くという時には困難さを感じていたというようなことを聞いています。この本によって少しでもラムダ式や Stream API を使うためのハードルが下がってくれれば幸いです。

もちろん、他の Coin や NIO.2、Date and Time API も参考になるはずです。

ぜひ書店でお手にしていただいて、とりあえずはパラパラとめくっていただければ思います。もちろん、Kindle や Kobo、PDF などの電子書籍版もあります。

 

ちなみに、発売前にタイポがすでに見つかっています。技術評論社のサイトに正誤表がありますので、ぜひそちらをご参照ください。

サポートページ

また、タイポや間違いなどがありましたら、技術評論社もしくは櫻庭までご報告いただければ幸いです。

 

とうぶん、本を書くことはないと思いますが、次は JavaFX の本にしたいなぁ... 需要があるかどうか微妙なのですけどね。

2015/04/10

JJUG Night Seminar "Raspberry Pi Night Seminar"

このエントリーをはてなブックマークに追加
2015.04.10 JJUG Night Seminar "Raspberry Pi Night"

明日は CCC なのですが、基調講演をしてもらう予定の Stephen Chin さんが Raspberry Pi のイベントをやってくれるということで、急遽開催することになりました。

私は受付業務。もうちょっと誰か来てくれるかと思ったら、誰も来てくれなくて JJUG の幹事は私だけ。Oracle の伊藤さんが手伝ってくれたので、どうにかなりましたが...

今回はほんとにデモだけです。明日の基調講演でデモする予定のものや、その他のデモを比較的ゆっくりとお見せすることができたのではないかと思います。

そして、お子さんが多かったのが、今回の特徴でした。デモを見るだけだったら、プログラミング技術は必要ないし、英語の勉強にもなるので、ちょうどよかったのかもしれません。

とはいうものの、中には実装の説明がないことにがっかりして、帰られてしまった方もいらっしゃいました。主催者側もどういう内容になるか当日までちゃんと把握できていなかったことが、問題だったと思っています。デモだけだと分かっていれば、イベントページにもその諭旨が記載できたはずでした。

それでも、ほとんどの参加者に楽しんでいただけたようでよかったです。

2015.04.10 JJUG Night Seminar "Raspberry Pi Night"
2015.04.10 JJUG Night Seminar "Raspberry Pi Night"
2015.04.10 JJUG Night Seminar "Raspberry Pi Night"
2015.04.10 JJUG Night Seminar "Raspberry Pi Night"
2015.04.10 JJUG Night Seminar "Raspberry Pi Night"
2015.04.10 JJUG Night Seminar "Raspberry Pi Night"
2015.04.10 JJUG Night Seminar "Raspberry Pi Night"