タグ「Presentation」が付けられているもの

[Presentation] How to use MicroProfile and ...

I made presentation at Oracle Code Tokyo (18th May 2017) and JJUG CCC 2017 Spring (20th May 2017) about introduction to MicroProfile. The slides are following;

Microservice Architecture is recently attending in Japan. But MicroProfile is known only few Japanese developers. Thus I mainly explained the basis of MicroProfile and Microservice Architecture. In addition to show a use case that replace Japanese End-user computing (it's often unreliable) by Microservice.

In Japan, almost server-side Java developers look at Spring Framework but ignore Java EE. (I don't understand why they hesitate Java EE so much...) If as many people as notice MicroProfile, I'm glad.

[Presentation] Payara Micro の設計と実装

この記事は Payara Advent Calendar 2016 の 4 日目です。昨日は「Payara クイック・スタート・ガイド」です。

昨日開催された JJUG CCC 2016 Fall (もう 12 月なのに Fall というのも妙ですが、諸般の事情があったのでしょう...) で同じタイトルの発表を行いました。詳しくは、以下のスライドを参照してください。

50 分という時間制限の中では Payara Micro のすべてを解説することはできないため、ブートストラップとシャットダウン、Hazelcast による自動クラスタリング、アプリケーションのデプロイ、Uber Jar の生成に内容を絞りました。いずれも Payara Micro 独自の機能であり、深く解説するには好都合なトピックでした。また、いくつかの機能については多くのアプリケーション・サーバーで共通しているものであり、アプリケーション・サーバー一般論を理解する上でも何からのヒントになったのではないかと思っています。

今回、一番伝えたかったことは、多くの Java アプリケーション開発者にとってブラックボックスとなっている Java EE アプリケーション・サーバーであっても、結局は main メソッドを持つ Java アプリケーションに過ぎないということです。Payara Micro だけでなく Tomcat、WildFly、GlassFish のブートストラップに関する情報をスライドに載せたのも、そのことを意図しています。このことさえ分かれば、Java EE アプリケーション・サーバーはもはやブラックボックスとは思えなくなります。

Hazelcast に関する説明は、一応自分なりには頑張りましたが、やはり「CLOVER を参照せよ」が最終的な解答です。かずひらさん (@kazuhira_r) には申し訳ないのですが、これからも頼らせて頂きます。

JJUG CCC 2016 Spring で発表しました

5 月 21 日に開催された JJUG CCC 2016 Spring で Java EE の Web Profile について発表してきました。恒例の資料はこちらです。

今回は聴講してくださったなかやまさんがセッションのメモをイラストにまとめてくださいました。ありがとうございます!(なので今回は解説なしです)

なかやまさんのイラストにある、ハスヌマの横の女の子は誰だ?というツッコミが Twitter のどこかであったような気がしますが、待ち時間用のスライドに使っていた多田李衣菜だと思われます...

11 月 28 日に開催された JJUG CCC 2015 Fall で Payara Micro のお話をしてきました。まずは発表資料から。

今回、補足事項はあまりないのですが、API の PayaraMicro.bootStrap() の戻り値は 4.1.153 から PayaraMicroRuntime になりました。それ以前は void だったので API でも起動後の状態変更はできませんでした。

リハーサルの段階でセッションが 35 分で収まることが分かって、残りの時間は長めの質問タイムにするか、デモにするか、会場の皆さんの意見を聞いて決めることにしていました。まあ、会場の圧倒的多数がデモを選ぶだろうことは容易に予想が付いたのですが、まさか全員デモを選ぶとは...。会場の VGA が 1 系統と見越して)、iPad から Surface Pro 2 への切り替えでもたつく前提で 1 つだけデモを用意していました。ところが本編がまさかの30分以内で収まり、VGA の切り替えもすぐにできてしまったので時間が大幅に余り、予定になかった Hazelcast でのクラスタリングと自動バインド機能をご覧いただきました。即興でデモを追加するのは、非常に心臓に悪いです...。

最後に 5 分ほど質問タイムができたので、そのおさらいです。

  • Payara Micro は、埋め込み GlassFish をラップして、マイクロサービス向けに特化した実行環境です。基本的には開発環境ですべて設定を済ませ、変更が生じるときは新しいインスタンスを作成する運用になります。そうでない運用では通常の Payara Server を選択するのが良いです。補足ですが、Payara は大雑把に言うと有償サポート付きの GlassFish なので、バグの修正が早いことを除けば実運用で大きな違いは出ないと考えられます。
  • Payara Micro の JDBC データソース設定は、主にアプリケーション側で行うことになります。具体的には glassfish-web.xml と glassfish-resources.xml への記述となります。代替手段として、データソース設定済みの config.xml を用意できればオプションで差し替えて使用することも可能です(手間はかかります)。API 使用時は asadmin のサブコマンドを呼び出す方法も採れます。
  • 自動バインドは --port / --sslPort で指定したポートから順番にチェックして空いているポートで待ち受けをする仕組みなので、Payara Micro を次々と起動すれば順番にポートを埋めていきます。この機能は Hazelcast の待ち受けポート割り当てを模して作られたもので、「あったらいいな」的なものを実装しただけです。現在のロードバランサーは静的に設定されたポートでリクエストを振り分けるものが多く、今のところ自動バインド機能の実効性については未知数です。

今回の JJUG CCC は、あまりにも体調が悪くて発表がなければ休んでいたくらいなので、うらがみさんのセッションを聴いて、自分のをやって、資料の公開を確認してから撤収しました。そういう運命だったと思って、今回は諦めました。

第十二回 #渋谷java にて発表をしてきました。昨年夏の GlassFish Internals #1 : Introduction to Nucleus に続く、一応シリーズものになります。今回は GlassFish のモジュラー・アーキテクチャがテーマです。テーマ故に難易度はかなり高めに設定していて、GlassFish の初級コミッタレベル、あるいは Payara のコミッタレベルの内容になっています。

内容自体は会場の圧倒的多数を置き去りにするハイレベルなものですが、本当のことを言うと glassfish4/glassfish/modules/*.jar と glassfish4/glassfish/lib/*.jar の違いが理解できれば発表内容の 6~7 割程度は理解したことになります。残り 2~3 割は分かっていなくても GlassFish エバンジェリストを名乗れます (そのくらい難しい内容です)。

まず、発表内容の訂正ですが、Felix Gogo は GlassFish 4.0 以降にはバンドルされており、さらに asadmin に統合されています。GlassFish 3.x では発表通り別配布となっています。GlassFish のドメイン起動中に asadmin osgi help と入力することでヘルプを参照できます。リンク先がソースコードのため適切とは言いがたいですが https://svn.java.net/svn/glassfish~svn/trunk/main-docs-l10n/man/nucleus/osgi-platforms/osgi-cli-remote/src/main/resources/org/glassfish/osgi/cli/remote/ja/osgi.1 に日本語のヘルプがあります。

発表内容だけでは GlassFish の起動直後は数個しか OSGi バンドルが Active になっていないような印象を受けますが、実際には約 300 のバンドルのうち 100 弱が Active になります (これは GlassFish 4.1 Full Platform の場合であり、バージョンやディストリビューション等により変動します)。その多くは Auto-start bundles にカテゴライズされている Java EE 実装で、他のバンドルと依存関係にあるため Active になっているものも少なくありません。むしろ約 300 あるバンドルのうち 3 分の 2 が Lazy Loading となることに注目してください。

通常、ここまで高度な内容を取り上げることはしないのですが、今回は実験的にコミッタ級の難易度で発表をしてみました。予想通り皆さんを置き去りにするような結果となりましたが (これも織り込み済み)、今回の発表は以下のことだけ覚えておいていただければ OK です。

  • glassfish4/glassfish/modules -- OSGi 管理のモジュールが配置されている
  • glassfish4/glassfish/lib -- 非 OSGi 管理のモジュールが配置されている

※modules と lib は構造上、クラスローダーが異なります。例えば JDBC ドライバは lib に配置しないと機能しません (JDBC ドライバは通常、非 OSGi のため)。

7 月 11 日 (土) に大阪で開催された「Java 8徹底再入門」(主催: 関西 Java エンジニアの会) にて、Date and Time API のお話をしました。同 API の包括的な解説は JJUG で何回かやっているのですが、大阪でお話しするのは今回が初めてになります (大阪にまとまった時間滞在すること自体が初めてだったりする)。

今回のプレゼンでは、以下の 2 点を目標としました。うまく達成できていたでしょうか?

  • 初めての方 (もしくは一度挫折してしまった方) には、これを機会に Date and Time API を使ってみようと思ってもらえること。
  • 既に使っている方には、ZonedDateTime 一択という使い方について本当に妥当かどうか考え直してもらえること。

発表資料を以下に示します。JJUG CCC 2013 Fall の「JSR 310 "Date and Time API" への招待 II」のストーリーをベースにしながら、2014 年 3 月の Java 8 ローンチ・イベント、#渋谷java での発表内容を盛り込んだものに仕上げました。

これは何度も言っていますが、Date and Time API は ISO 8601 (コンピュータ間でデータのやりとりをする際の、日付と時刻の書式に関する国際規格) をモデリングして作られたもので、ISO 8601 について知らないと API が「なぜ」そのように設計されたのかわからず、適切でない使い方をしてしまうケースが少なくありません。その結果、「Date and Time API は使い勝手が悪い」と早とちりしてしまいがちです。とは言っても、実際に知っておかなければならない ISO 8601 の予備知識は今回の発表スライドに挙げた程度で、それ以上細かい規定については知らなくても大丈夫でしょう。

Date and Time API は public なクラスだけでも 69 個ありますが、そのうち常時使うのは多くても 20 個程度です。これについては、API を扱うプログラマ、あるいはアプリケーションの要求によって異なってくるため、自分自身の感覚でプライオリティを付けておくことが大切です。最初のとっかかりとしては LocalDate を集中的に勉強するとよいでしょう。LocalDate は標準的な操作が一通り揃っており、かつそれほど複雑ではありません。

ある程度慣れてきたら、多くの例を見ておくとよいでしょう。Angela Caicedo が Java Day Tokyo 2015 のセッションで使用した資料は、サンプル集としておすすめです。


今回は筆者のセッションと、@bitter_fox さんの Lambda/Stream API ハンズオンの二本立てでした。

本当にわかっている人がやる説明って、こういうものなのですよ。参加された方は、本当にツイてます!


今回は、何気ない連投ツイートがきっかけで @backpaper0 さんが企画してくださり、@bufferings さん、@s_kozake さん、@irof さん、@yukieen さん、@haljik さんにはスタッフとして勉強会の進行や懇親会の企画、さらには宿探しや当日の道案内まで買って出てくださいました。さらには持ち時間の 50 分を大幅に超過しても (自分で言うのも何ですが、今回レベルの大幅超過は極めて稀です) 会場の皆さんは最後までお付き合いくださいました。皆さんのおかげで、がんばりました。がんばれました。ありがとうございました。

この記事は JavaFX Advent Calendar 2014、8 日目の記事です。昨日は @backpaper0 さんの「どうやってApplicationサブクラスの名前取ってきてんの?」でした。

Java SE 8 Update 40 より、JavaFX にダイアログが導入されることになりました。既に Update 40 の Early Access Build のインストーラー配布が公開されていますので、興味のある方はダウンロードして新機能を確かめてみることをお勧めします(ただし Early Access は本番環境への適用が禁止されているため、あくまで個人の範囲で)。

今回ご紹介するサンプルは https://github.com/btnrouge/javafx-dialogs にあります。JDK 8u40 以降でないと実行できないため、実行環境の JDK 8 のバージョンにはくれぐれもご注意ください。

JavaFX 8u40 のダイアログについては、11 月 25 日に開催された JavaFX Night にてセッションを担当しました。導入部分についてはセッション資料をご覧頂くのが一番かと思いますので、以下に掲載します。

JavaFX Night では、時間の都合で十分な量のサンプルを提示できなかったことと、ダイアログのカスタマイズについて「その気になればカスタマイズもできるよ!」のひとことで済ませてしまったため、この記事では主にそれらを中心にお話ししようと思います。

JavaFX 8u40 で導入予定のダイアログは、サードパーティのライブラリ ControlsFXDialog を参考にしていると思われます。その証拠に、画面レイアウトもよく似ています。

1. 2 通りのダイアログ表示方法

JavaFX のダイアログには 2 通りの表示方法があります。JavaFX Night でも取り上げた、Dialog#show() と Dialog#showAndWait() です。どちらもダイアログを表示し入力を待つ動作は同じですが、Dialog#show() はそれ以降に続く処理がすぐに実行されるのに対し、Dialog#showAndWait() はユーザー入力後に続く処理を実行します。

具体例を挙げましょう。まずは Dialog#show() の場合です。

Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Show");
alert.getDialogPane().setHeaderText("Header Text");
alert.getDialogPane().setContentText("Content Text");
alert.show();
System.out.println("message after alert#show()");

alert.show(); でダイアログを表示し、すぐに次の処理が実行されるため、ユーザーの入力を待つことなくコンソールに "message after alert#show()" と表示されます。

Dialog#show() はユーザー入力を待たないため、ダイアログからの応答を受け取るタイミングが存在せず、従って戻り値も void として宣言されています。

続いて、Dialog#showAndWait() の場合を見てみましょう。

Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Show and Wait");
alert.getDialogPane().setHeaderText("Header Text");
alert.getDialogPane().setContentText("Content Text");
alert.showAndWait();
System.out.println("message after alert#showAndWait()");

alert.showAndWait(); でダイアログを表示するところまでは同じですが、ユーザーの入力があるまで(ダイアログを閉じるまで)コンソールに "message after alert#showAndWait()" は表示されません。

基本的な使い分けとしては、

  • いわゆる従来型のダイアログとして使用する場合は Dialog#showAndWait()
  • Windows 8 のトースター通知のように処理を止めたくない場合は Dialog#show()

といった形になるでしょうか。

2. DialogPane の使い方

DialogPane は Dialog が保持できる唯一のコンテナーで、Dialog の dialogPane プロパティーを通じて操作することができます。DialogPane にはさらにいくつかのプロパティーが存在し、それらの調整だけでもダイアログのカスタマイズが可能です。

DialogPane のルック・アンド・フィールを制御するプロパティーの一覧を下記に示します。

DialogPane の主なプロパティー
プロパティークラス概要
graphic Node アイコン
headerText String ヘッダー文字列
header Node ヘッダー(headerText より優先)
contentText String メッセージ
content Node コンテンツ(contentText より優先)
expandableContent Node 詳細情報
expanded boolean 詳細情報の表示/非表示

headerText と header の関係、contentText と content の関係については JavaFX Night では触れませんでしたが、headerText と contentText がヘッダーとメッセージをそれぞれテキスト(内部的には Label にラップして header / content に設定)するのに対して、header と content はあらゆる Node ツリーを設定できるため自由なレイアウトが実現できます。header と content はデフォルトでは null となっており、header / content に Node を設定すると headerText / contentText の内容は無視される仕様になっています。多くの場合、凝ったダイアログを必要とするケースは多くないので、headerText と contentText を押さえておけば良いでしょう。

一般にエラーを通知するダイアログでは、初期表示ではエラーの詳細を隠し、必要に応じて詳細を表示する形式が多く見られます。そのようなダイアログを実現するために expandableContent と expanded が用意されています。expandableContent はデフォルトでは null になっています。expandableContent が null でない場合は expanded が有効になり、詳細情報の表示/非表示の制御ができるようになります。

expandableContent の想定される使い方としては、Alert ダイアログの AlertType.ERROR に原因となったエラーの詳細(例外スタックトレースなど)を表示するための領域を追加するような用途です。

なお、Dialog 自体にも headerText / contentText プロパティーが存在しますが、これらは DialogPane の headerText / contentText を呼び出しているだけです。

3. Alert のカスタマイズ

3.1. expandableContent プロパティ

Alert は DialogPane のプロパティを調整することで簡単にカスタマイズすることができます。ここでは expandableContent プロパティを設定して、エラー詳細情報を表示できるようにしてみましょう。

// error message
final String stackTrace = 
    "Exception in thread \"main\" java.lang.UnsupportedOperationException\n"
    + "\tat java.sql.Date.toInstant(Date.java:304)\n"
    + "\tat samples.time.Unsupported.main(Unsupported.java:6)";

Alert alert = new Alert(AlertType.ERROR);

// prepare expandable content
TextArea textArea = new TextArea(stackTrace);
alert.getDialogPane().setExpandableContent(textArea);

alert.setTitle("ERROR");
alert.setHeaderText("Error");
alert.setContentText("An exception was thrown in the application");
Optional result = alert.showAndWait();

ダイアログの実行イメージです。

exception.png

「詳細の表示」をクリックすると、expandableContent プロパティで設定した内容が表示されます。

exception-expanded.png

3.2. header プロパティおよび content プロパティ

headerText や contentText では単純な文字列しか出力できませんでした。しかし、出力したい内容を header または content に設定しておけば、任意の内容をダイアログに表示させることができます。

ここでは Alert の content に TextFlow(リッチテキスト)とイメージを設定したダイアログの例を見てみます。ソースコード中に contentText を設定していますがそれが無視されていることにも注目してください。

Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Custom content");
alert.setHeaderText("Header Text");
alert.setContentText("Content Text");

// Set content property
Text text1 = new Text("It's content Text ");
Text text2 = new Text("as Rich Text");
text2.setFill(Color.RED);
TextFlow textFlow = new TextFlow(text1, text2);
ImageView imageView = new ImageView(new Image(getClass().getResourceAsStream("someimage.png")));
VBox vbox = new VBox(4.0, textFlow, imageView);
alert.getDialogPane().setContent(vbox);

Optional result = alert.showAndWait();

ダイアログの実行イメージです。

custom-content.png

なお、header の場合も手順は同様です。

3.3. graphic プロパティ

Alert ダイアログのアイコンはコンストラクタ引数(AlertType)によって決まりますが、graphic プロパティを設定することで任意のイメージに差し替えることができます。この方法は AlertType.NONE の場合でアイコンを表示する場合にも用います。

では、アイコンを差し替えてみましょう。以下にソースコードを示します。

Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Custom icon");
alert.setHeaderText("Header Text");
alert.setContentText("Content Text");

// Set graphic property
ImageView imageView = new ImageView(new Image(getClass().getResourceAsStream("newicon.png")));
imageView.setFitWidth(48.0);
imageView.setFitHeight(48.0);
alert.getDialogPane().setGraphic(imageView);

Optional result = alert.showAndWait();

ダイアログの実行イメージです。

custom-graphic.png

4. TextInputDialog と ChoiceDialog のカスタマイズ

前章で示したように、Alert は比較的簡単にカスタマイズすることができます。しかし、TextInputDialog と ChoiceDialog については content をカスタマイズすることができません(contentText は可能)。これらのダイアログは content にあらかじめレイアウト(GridPane)が設定されており、かつレイアウトの設定タイミングをダイアログ側がコントロールしているため、拡張の余地がないのです。

なお、header プロパティおよび graphic プロパティについては、Alert 同様に設定が可能です。

5. 独自ダイアログの実装

Dialog のサブクラスを独自に作成することで、全く新しいダイアログを作成することもできます。こちらは Dialog クラスのサブクラスを直接作成するため手間はかかりますが、出来合いのダイアログに比べると自由度が高い利点があります。

注意点として、Dialog クラスのメソッドはすべて final 宣言されており、オーバーライドすることができません。ダイアログ内部のイベント取得タイミングを変更するなど、ダイアログの動作そのものを変えてしまうことはできないのです。

当初の予定では、Dialog から直接派生させた独自のダイアログを作成しようと考えていたのですが、ユースケースが思いつかなかったため割愛させていただきます。現在は JavaFX のソースコードも標準で添付されるようになったため、Alert などのソースを参考に各自工夫してみてください。

6. Dialog と Stage の関係

最後に Dialog と Stage の関係についてお話します。

実用上は、Dialog と Stage は似てはいるが別物として扱った方がわかりやすいでしょう。Dialog には Stage にも存在するプロパティーやメソッドをいくつも持っています。新たなウィンドウを開くという点でも同じです。

厳密に言うと、Dialog と Stage は "has-A" の関係にあります。ここから先は Dialog の実装に深く踏み込んだ話になるため、初見の方は読み飛ばしていただいて構いません。

Dialog は下請けクラス FXDialog のインスタンスを保持しています。FXDialog は抽象クラスであり、実際にはサブクラスの HeavyweightDialog のインスタンスとなります。そして HeavyweightDialog が DialogPane を root とする Scene を構築し(dialogPane に null を設定した場合は必ず新規の DialogPane が生成される)、Scene とダイアログの共通属性(リサイズ不可と画面中央への表示)を設定して Stage を作成します。

FXDialog とそのサブクラスは、Stage のメソッドとプロパティのうちダイアログのカスタマイズに利用可能なものを外部に提供しています。Dialog と Stage で共通のプロパティが多いのはこれが理由です。

Dialog は FXDialog(HeavyweightDialog)のコンストラクタに自身のインスタンスを設定し、ダイアログの Stage を生成してもらいます。Dialog のメソッドとプロパティは FXDialog が提供するメソッドとプロパティをほぼそのまま呼び出すだけです。

あまり多くのことを覚えたくなければ、Dialog と Stage は分けて考えた方が分かりやすいでしょう。

7. まとめ

JavaFX 2.x 時代から望まれていたダイアログが、来春には JavaFX 8 に追加されます。仕様策定に予想以上の時間がかかりましたが、まずまずの出来ではないでしょうか。2015 年 3 月には JavaFX 8u40 のリリースと共に標準でダイアログが利用できるようになるため、それまでの間に習熟しておくと良いことがありかもしれません。

最後になりましたが、今回サンプルで提示したソースコードは GitHub https://github.com/btnrouge/javafx-dialogs にホスティングしています。必要に応じて参照してください。


明日は気鋭の学生プログラマー @orekyuu が何か書いてくれると思います。大いに期待しましょう。