2016/09/19

JavaOne 2016 Day 2

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

JavaOne は iOS と Andoroid 向けの公式アプリがあるのですが、私の iPhone ではまったく動いてくれません >< 動いていても、Web から登録したセッション情報を同期できないなど、できが悪すぎ。

よっぽど、Gluon が JavaFX で作ったアプリの方がサクサク動いてます。セッションの登録情報を表示できれば、Oracle のアプリは使わないんだけどなぁ。

というわけで、今日聴講したセッションです。

  • Adventures with Extreme Types in a Purely Functional Language [TUT1288]
  • JDK 9 Language, Tooling, and Library Features [CON2497]
  • JavaFX: New and Noteworthy [CON2483]
  • A Survey of Memory Footprint Optimizations in Java SE and Java HotSpot VM [CON1938]
  • Introduction to Troubleshooting in JDK 9: Serviceability Tools Are Your Friends [CON3733]
  • Building JavaFX UI Controls [CON2476]
  • Tools for High-Performance Polyglot Programming on the JVM [BOF4837]

今日はかなりマジメにセッション出てました。マジメにセッション出ると、ランチが食べられないというジレンマがあるわけですが、朝ご飯いっぱい食べたので大丈夫です。

Adventures with Extreme Types in a Purely Functional Language [TUT1288]

型の話といいつつ、関数型プログラミングの話。スピーカーは Canoo の Dierk Koenig。

この人、話し方も柔らかいし、発音がはっきりしているので、とても聞きやすい。まだ英語慣れしていないので、聞くのが楽でした。

Extream Type というのは特殊な方ではなくて、immutable value とか pure function とか constraint context などを加えた型についてだそうです。なんで型でを考えるかというと、No Silly Error とか Safe Refactoring とか Less Tricky Error とか Abstraction などの理由から。

Extream Type を使うと、暗黙的な制約を明示的にできます。コードで制約を書くのではなく、型で制約を与える方がいいということなのでしょう。型であれば、まちがいがあってもコンパイル時に分かりますからね。

現在の Java であれば、Stream や JavaFX の一部で Extream Type が使われています。

さて、はじめのサンプルとして、以下のプログラムが示されました。

 

import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import java.util.stream.Stream;

public class RNG {
    static Supplier<Integer> countGen(AtomicInteger i) {
        return (() -> i.getAndIncrement());
    }

    public static void main(String... args) {
        final Supplier<Integer> numbers = countGen(new AtomicInteger(1));
        final Optional<Integer> sum = Stream.generate(numbers)
            .limit(100)
//            .parallel()
            .map(a -> a^2)
            .reduce((a, b) -> a + b);
        System.out.println("sum = " + sum);
    }
}

このプログラム、parallel メソッドのコメントを外すと正しい値になりません。問題は countGen メソッドで作成している Supplier オブジェクトです。Supplier インタフェースは関数型インタフェースなので、あたかも関数のように扱えます。しかし、ここでは countGen メソッドの引数になっている AtomicInteger オブジェクトに依存してしまっています。

つまり、Supplier オブジェクトは純粋関数としては扱えません。純粋な関数だけでプログラミングをしましょというのが、Koenig さんの主張。

そこで、例として取り上げられたのが、Online REPL の try.frege-lang.org です。frege では、ブラウザ上で Haskell の REPL を実行することができます。

その後、関数合成などの関数を用いたプログラミングの説明がされました。

ちなみに、frege は Haskell のコードを Java のコードに変換して、コンパイルしているようです。これもなかなかおもしろそう。

最後に Fizzbuzz を frege で書くのを紹介されたのですが、なかなかおもしろい。でも、Java の Stream には zip がないから難しいなぁ... と思っていたら、隣に座っていた @bitter_fox さんがさっそく Java で書き直してました。もちろん、zip も作ってあります。それが、こちら

さすが、OpenJDK コミッタともなると、やることが早い!

JDK 9 Language, Tooling, and Library Features [CON2497]

Java SE 9 の言語仕様の変更や、ツール類の説明セッション。スピーカーは Joe Darcy です。

Joe はいつもの赤シャツ。Joe は Project Coin のリードだったことからも分かるように、言語仕様の取りまとめを行っている重鎮です。

Joe のセッションではおなじみなのですが、最初に言語仕様を変えるのは大変という話。Java 9 でもバイナリーコンパチが崩れる部分があるようです。

たとえば、AWT の peer が使えなくなるようなのですが、これは AWT 使っている人には結構いたいのじゃないかなぁ。

ツール関係でまず紹介したのが、jshell。Java の REPL です。昨日のキーノートでもやってましたね。

そして、Javadoc 関連。HMLT 5 に対応したり、検索が使えるようになるなど、いろいろ変更されてます。ちなみに、検索はクライアントだけで実行しているので、サーバーはいらいようです。

次に紹介したのが、javac で違うバージョンのソースをコンパイルすること。今までは -target -source そして -bootclasspath を指定しなくてはいけなかったのですが、新たに -release というオプションが導入されました。

-release N と記述した場合、-target N -source N -bootclasspath rtN.jar に相当するそうです。

そして、言語仕様。

まずは Project Coin。Java 7 で導入された Coin ですが、Java 9 でも言語仕様の変更を Coin で行っています。

@SafeVarargs の変更や、try with resources で final もしくは effectively final であれば、try ブロックの外側で記述できるようになったりしています。

また、ダイヤモンド演算子がやっと匿名クラスでも使えるようになりました!

さらに Java 8 で予告されていた、_ を 1 文字でメソッド引数に使用できないようになっています。Java 8 ではラムダ式では使えなかったのですが、Java 9 ではすべてのメソッドでコンパイルエラーになります。

@Deprecated もいろいろ変化しています。@Deprecated に関しては Dr. Deprecator こと Stuart Marks のセッションもありますが、とってないんですよね ^ ^;;; 後で資料をチェックしないと。

その他に、ダイヤモンド演算子やラムダ式で使う型推論を入れ子で使用するとコンパイル時間が長くなる問題があったのですが、それもかなり解消されたようです。

また、コレクションにファクトリメソッドの of が追加されています。Arrays.asList メソッドと同じように変更不可のコレクションを作成できます。

Java 9 は大きい変更は Project Jigsaw だけですが、細かい部分はいろいろと変わっているので、ぜひ資料をチェックしてみてください。

JavaFX: New and Noteworthy [CON2483]

JavaFX のロードマップ的なセッション。今年も、Kevin Rushforth と Jonathan Giles がスピーカー。

このセッション、去年と内容があまり変わっていないのです。なんか、残念。

JavaFX 9 での一番の変更は Jigsaw 対応。特に今まで公開していなかった skin 関連の API を公開するように変更することによって、いろいろ変わっていると (JEP 253)。

ちなみに、Jigsaw 対応の中で exports private というキーワードが出ていたけど、後で Jigsaw のセッションで確認します。

それと、今まで使用できていた impl_* のメソッドは全部使えなくなります。まぁ、しかたないか。ハックするときは impl_* から辿ることが多かったので、ちょっと残念なのですが ^ ^;;

それ以外の機能としては Hi DPI 対応。Mac はすでに対応済み、Windows では部分的に対応されていましたが、Linux でも Hi DPI をサポートします。これ以外にも小さな変更があるようですが、小さいんですよね。

去年のセッションでは Java 9 のリリース時期が伸びたからもうちょっと機能を追加できるかもといっていたのですが、あまり追加できなかったようです。

さて、Java 9 以降の話をちょっとだけ。

まだ計画段階なので、実際にどうなるかわからないですけど、たとえば AWT を必要としなくなるなどの変更を計画しているようです。でも、大きな変更はあまりないような気が... シェーダーはやっぱり入れてくれないのかなぁ....

A Survey of Memory Footprint Optimizations in Java SE and Java HotSpot VM [CON1938]

JVM のメモリ関連のまとめ的なセッション。でも、GC については触れないのです。スピーカーは Charlie Hunt。

Charlie は Salesforth に転職していたのですが、また Oracle に復職していました。全然知りませんでしたよ。

ちなみに、最近 Charlie は共著で Java Perfomance Companion という本を出しています。G1GC のチューニングに関してかなり書かれているので、G1GC を使うのであれば、必読ではないかと思います。

さて、なぜメモリのフットプリントが大事なのかということからセッションは始まりました。メモリは CPU に比べるとパフォーマンスが向上していません。このため、CPU やネットワークとのギャップがどんどん開いてしまっているわけです。

このため、キャッシュやメインメモリのフットプリントがダイレクトにパフォーマンスに直結することになっているわけです。

さて、メモリを調べるには、いくつかの方法があります。Java のヒープであれば、jmap や Mission Control のプラグインである JOverflow が使用できます。

次に、Java のヒープを削減するために取り入れられた手法の紹介。

たとえば、Java 6 で導入された Compressed Ordinary Object Pointer。多くのオブジェクトに対するポインターを効率よく表すために、64bit を使用せずに、もっと少ないビット数で表す手法です。

また、Java 8 で導入された Metadata やアプリケーションのクラスデータの共有なども。

Java 9 ではアスキー文字を 16bit を使わずに 7 bit で表す Compact String が導入されます。

最後に WebLogic のリソースマネージメントの説明があったのですが、よくわかりません。メモリ使用量がかなり減るらしいですよ。

Introduction to Troubleshooting in JDK 9: Serviceability Tools Are Your Friends [CON3733]

久保田さん、末永さん、高尾さんのセッション。去年は BOF だったのですが、今年はカンファレンスセッションに格上げです。

この 3 人のセッションなのですから HeapStats の紹介セッションなのかと思ったら、それほど HeapStats には触れず。なんかもったいない。

jcmd と jhsdb と HeapStats の 3 本立て。でも、トピックがありすぎて、焦点がちょっとぼけちゃったかな。単にコマンドの紹介だけのようになってしまった感じです。

とはいえ、久保田さんは去年に比べればかなり落ち着いてしゃべってましたね。

Building JavaFX UI Controls [CON2476]

JavaFX で部品を作る話。スピーカーは Jonathan Giles。

開口一番、このセッションは 2014 年にやったけど、Java 8 や 9 のアップデートを加えてあるよと。でも、あまり変わらなかった。そりゃそうか。

このセッションでは JavaOne ボタンを以下の 4 種類の方法で作成していきます。ソースコードは Bitbucket で公開されてます。

  1. 既存のコントロールを CSS でカスタマイズ
  2. 既存のコントロールのスキンを置き換え
  3. 既存のコントロールを組み合わせて新しいコントロールを作成
  4. Control クラスを派生させて新しいコントロールを作成

数字の若い方が簡便な方法です。

でも、作るとしたら、結局は 3 か 4 だろうな。

Tools for High-Performance Polyglot Programming on the JVM [BOF4837]

複数の言語を Java プラットフォームで扱いやすくする Graal VM のセッション。スピーカーは OpenJDK の Graal Project のリードの Michael Van de Vanter。

Graal VM は JVM Compiler Interface 上に Graal コンパイラを作成し、動的にコンパイルすることができます。

このセッションでは NetBeans 上で Graal 使ってデモしてました。デモでは、NetBeans 上で Java のコードと Ruby のコードを示し、Ruby のコードでもデバッガでトレースできることを示してました。デバッガは Truffle とよばれているものです。

パフォーマンスも Ruby ではかなり向上しているようす。Scala などはあまり変わらないようでしたが。

Graal コンパイラでは Instrumentation を使用して、AST を操作して最適化や部分評価を行っているようです。なかなかおもしろい。こういう話が効けるのが、JavaOne の醍醐味の 1 つですね。

おまけ

去年の JavaOne では、セッションのアンケートの代わりに、赤黄青を入力できる JavaFX のアンケートマシンが使われていました。

今年はそのアンケートマシンがパワーアップ。画面が大きくなってます。でも、裏を見ると、やっぱり Raspberry Pi。でも、去年のむき出し状態とはことなり、ちゃんとケースに入ってましたよ。

というか、画面が大きくなったことと、ケースに入ったことぐらいしか違いはないわけです。

やるんだったら、もうちょっと新しいことをやればいいのに。

2016/09/18

JavaOne 2016 Day 1

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

今年も JavaOne の季節がやってきました。

直前になって、Java SE 9 のリリース延期が提案されていたりして、あんまり期待はできないのですが、実際のところは....

さて、今日はコミュニティが主催しているセッションとキーノートです。とはいえ、はっきりいってコミュニティ主催のセッションはクオリティが低い。審査も何もないし、しかたないとは思うんですけどね。

それでも、1 つだけセッションをとってみました。ということで、今日聴講したのはこちら。

  • UGF7875 Refactoring Your Code with Java 8: Functional Programming to the Rescue
  • KEY7967 Java Keynote

UGF7875 は朝 8 時のセッション。早すぎ!

UGF7875 Refactoring Your Code with Java 8: Functional Programming to the Rescue

なぜ、このセッションに出ようと思ったかというと、関ジャバ会長の @jyukutyo がスピーカーだから。

メインのスピーカーは Red Hat の Eder Ignatowicz。Red Hat といっても US のではなくて、ブラジルの Red Hat だそうです。

で、朝の 8 時前に会場の Moscone Center にいってみたら..... @jyuktyo が見当たらない!!

結局、@jyukutyo なしでセッションは進んでしまいました。

内容的にはデザインパターンと関数を使ってモダンなコード書こうねという内容。Template Pattern など関数を使いやすいパターンがあるので、そういうのに組み合わせていこうというものでした。

まぁ、取り立てて言うことはないです。

後から @jyukutyo に聞いてみたら、寝坊したらしいですww

ちなみに、今日は JJUG 会長もスピーカーに名を連ねていたのですが、そちらは壇上にはいたらしいものの、しゃべらず。

日本の 2 大 JUG の会長がスピーカーに名を連ねるものの一言も話をしなかったということは、日本の Java の歴史に確実に刻まれることでしょうww

KEY7967 Java Keynote

メインは火星でした。以上。

ということで終わらせることはできないですよね ^ ^;;

それにしても新味に欠けるキーノートでした。Oracle 前に Intel のキーノートがあったのですが、よっぽどそっちの方がちゃんとしてましたよ。

予算がないのは分かるけど、もうちょっと工夫しようよ。

詳しい内容はまた後で写真と共に追加します。

Java SE のパートはいつもの Mark Reinhold。

彼が紹介したのは Project Kulla と Project Jigsaw。

Kulla は Java で REPL を実現する jshell を提供しています。で、jshell のデモをしようとするのですが、画面がなかなか切り替わらずにイライラする Mark。

REPL だからデモは地味だよね。でも、しかたない。

で、そのまま Jigsaw へ。Jigsaw の機能も jshell で紹介します。

ところが、画面の縦横比があってなくて、スクリーンの右側が見切れてしまっていました。Mark がスタッフにどうにかしてくれというのですが、誰も出てこないし、誰も直そうとしない。

イライラした Mark は舞台裏に戻ってしまいます。まさか、怒って出て行ってしまった?

でも、スタッフとともに戻ってきました。よかった、よかった。

Jigsaw もあまり新しいことはなし。exports private というキーワードが出ていたけど、後で Jigsaw のセッションで確認します。

途中から Brian Goetz が出てきて、Project Valhalla と Project Panama の話。ここも去年とほとんど変わらず。唯一、var がさらっと紹介されていましたww

Java EE もあれだけ Guardian に責められていたのに、これでいいのという内容。まぁ、久しぶりに Garr さんが技術の話をしてましたけど。結局、まだ何も決まっていないんだろうなぁ。その割には 2017 年に Java EE 8、2018 年に Java EE 9 をリリースするというのは、誰も信じてないと思います。

最後にデモをやろうとしたのですが、時間切れで終了。Larry のキーノートが次に控えているので、時間厳守です。

個人的には、Java EE は役目が終わったと思うのですが、どうなんでしょうね。

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 を作成することができました!