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/10/28

Mazarine Coffee

このエントリーをはてなブックマークに追加
Mazarine Coffee, San Francico

奇跡的に早く起きられたので、最近できた Mazarine Coffee にいってみました。

なかなかいい雰囲気の内装で、落ち着いた感じ。

グラノラ (なぜかヨーグルトパフェになっtましたけど)とクロワッサン。それにラテ。

パンは提携したパン屋さんから提供されているようですけど、なかなかおいしい。こういうクロワッサンを普通のカフェでも食べられるようになったのは、ほんとうれしい。

でも、後から Fig & Ricotta Toast という魅力的なメニューを見つけてしまった。今、SF ではトースト流行っているんだよなぁ。次回はこれたべよう!!

Mazarine Coffee, San Francico
Mazarine Coffee, San Francico

Latte, Mazarine Coffee, San Francico
Croissant, Mazarine Coffee, San Francico
Yogurt Parfait, Mazarine Coffee, San Francico