torutkのブログ

ソフトウェア・エンジニアのブログ

jpackageで作る自己完結型アプリケーションの設定ファイル書式がJDK 14と15で変わっていた

JDK 14にてincubatorの位置づけで導入された jpackage(自己完結型アプリケーションパッケージを作成する等のツール)の設定ファイルが、JDK 15では認識されない事象が発生しました。

jpackageコマンドで自己完結型アプリケーションを作成すると、アプリケーションの属性、JavaVMオプション、コマンドラインオプション等を記載する設定ファイルが生成されます。(アプリケーション名に拡張子.cfgを付けたファイル)

JDK 14で作成したときの設定ファイル例を次に示します。

[Application]
app.name=AnalogClock
app.version=0.6.0
app.runtime=$ROOTDIR\runtime
app.identifier=com.torutk.gadget.analogclock
app.classpath=
app.mainmodule=com.torutk.gadget.analogclock

[JavaOptions]
-Xms32m
-Xmx128m
-Xss256k
-XX:TieredStopAtLevel=1
-XX:CICompilerCount=2
-XX:CompileThreshold=1500
-XX:InitialCodeCacheSize=160k
-XX:ReservedCodeCacheSize=32m
-XX:MetaspaceSize=12m
-XX:+UseSerialGC

[ArgOptions]
--x=-144
--y=-240
--scale=0.7
--fps=5
--on-top=true

JDK15で作成したときの設定ファイル例を次に示します。

[Application]
app.mainmodule=com.torutk.gadget.analogclock/com.torutk.gadget.analogclock.AnalogClockApp

[JavaOptions]
java-options=-Xms32m
java-options=-Xmx64m
java-options=-Xss256k
java-options=-XX:TieredStopAtLevel=1
java-options=-XX:CICompilerCount=2
java-options=-XX:CompileThreshold=1500
java-options=-XX:InitialCodeCacheSize=160k
java-options=-XX:ReservedCodeCacheSize=32m
java-options=-XX:MetaspaceSize=12m
java-options=-XX:+UseSerialGC
java-options=--module-path
java-options=$APPDIR\mods

[ArgOptions]
arguments=--x=-144
arguments=--y=-240
arguments=--scale=0.7
arguments=--fps=5
arguments=--on-top=true

[JavaOptions]と[ArgOptions]の項のプロパティの記述がJDK 14のjpackageで生成したものと、JDK 15のjpackageで生成したものとが変わっています。

jpackageは、近日リリース予定のJDK 16で正式導入となります。現在JDK 16のリリース候補版が公開されています。それに含まれるjpackageで作成してみたところ、JDK 15変更と同じ形式となっていました。

Java読書会 会場とオンラインの併用を試みる(実施)

1月度のJava読書会は、会場での開催にオンライン参加を実現しました

昨日1月30日(土)に開催した Java読書会では、通常の会場での開催に、リモートからの参加を併用しました。

リモートからの参加にあたり、構成と準備作業は次に書きました。 torutk.hatenablog.jp

今回利用した会場には、インターネット接続可能なWiFi環境が備わっていたので、それを利用してTeams会議でリモートからの参加を受け入れました。 会場では、Web会議用のマイク・スピーカーと広角カメラ(ノートPC搭載カメラに被せて広角にするタイプ)を用意しました。

結果は、会場から発する音声が切れ切れになるという状況がありましたが、なんとか実施には耐えたようです。

音声が切れ切れになる状況のメモ

会場からの音声は、マイクから50cm程度の距離であれば良好ですが、1mから2mに離れると音声が途切れ途切れになります。また、会場で議論発生時にバラバラな方向から発声があると音声が切れ切れになるようです。

大き目にしゃべるといいようです。

「データ指向アプリケーションデザイン」を読む(第4回)

Java読書会BOF では現在、書籍「データ指向アプリケーションデザイン」 を読んでいます。 昨日の内容は、5章 レプリケーション の途中(マルチリーダーレプリケーション)から始まり、リーダーレスレプリケーションを読み、6章 パーティショニングを読み進め、7章 トランザクションの途中まででした。

Java読書会 会場とオンラインの併用を試みる(準備)

今月のJava読書会で会場での開催にオンラインで参加できるようにしたい

Java読書会BOF は、明日1月30日(土)に「データ指向アプリケーションデザイン」を読む会(第4回)を開催します。

今回は、コロナ禍の2回目の緊急事態宣言発令下での開催となり、会場の定員も半分に削減することとされています。ただし、参加に不安を感じる人もいますので、会場だけでなくリモートからも参加できるよう試みることとしました。

Java読書会BOFでは、以前にコロナ禍の対応として2020年4月、5月、6月の3回をオンライン読書会として実施しました。

昨年のオンライン読書会との違い

昨年は、全員がオンライン参加としたので、参加者がそれぞれマイク・スピーカーを揃えてTeams会議に参加する形でした。今回、会場でのリアル開催とオンラインをつなぐので、会場にリアル参加の会話とオンライン参加の会話がつながるようにする必要があります。

読書会は朝10:00から夕5:00までと長丁場でその間音声・動画を流すので、時間やパケット量に制限のあるインターネット接続サービス(携帯電話や上限のあるモバイルルータ)は不適です。また、利用するWeb会議サービスも参加人数や利用時間が読書会開催に足りることも必要です。

今回利用する会場には、インターネットと接続できるWiFiサービスが提供されているので、オンラインとつなぐことはできそうです。

Web会議サービスは、昨年のオンライン読書会と同様 Microsoft Teams(無償版)としました。これは参加人数と利用時間が読書会開催に十分足りています。

アイテムの準備

続いて、次のアイテムを準備することにしました。

  1. 会議用のマイク・スピーカー
  2. 会場全体を映すカメラ
マイク・スピーカー

Java読書会は、参加者が順番に書籍を朗読し、随時議論を行うので、無指向性のマイクを真ん中に置く構成とします。といってもJava読書会は手弁当で開催しているので高いアイテムを買うのは厳しいのでなるべく廉価でそこそこ使えそうなものを探しました。

この中から、価格と無線接続が可能なLunaを選び購入しました。バッテリー搭載で無線でPCと接続できるので、会議室の真ん中に、電源やPCとの有線接続をせずに置くことができる点を評価しました。

カメラ

ノートPCのカメラで会場を映すと画角が狭く正面の参加者しか映りません。そこで、広角のカメラを用意すべく探してみたところ、スマフォのカメラに被せて広角にするレンズなら安価に用意できそうでした。

1000円未満の格安帯と、1000~5000円当たりの帯と、さらに高価な帯とがありました。格安なものはケラレという現象が出るとかがあり、その上を狙いました。

広角なカメラは120度が多いようですが、中に165度という超広角がありました。会場で自席に置いたノートPCからなので、この超広角を選び購入しました。

Teams(無料版)

今回もTeamsを使う想定です。

Microsoftアカウント

Teamsは、参加者もアカウントが必要です。アカウントは、Microsoftアカウントです(無料で作成可能)。 次のリンク先で作成します。 https://account.microsoft.com/account/

メールアドレスがキーとなります。作成、使用時にはキーとしたメールアドレスにセキュリティコードが送られるので、そのメールアドレス宛のメールを読み取れる環境が必要です。

Microsoftアカウントを作成し、Teamsアプリを起動すると、「まだTeamsに登録していませんが、組織でセットアップできます」のメッセージと[Teamsに新規登録]ボタンが表示されてしまいます。これは

参加に必要なこと
  • Microsoftアカウントを保有している
  • 会議への招待のリンクを開く
会議の作成(管理者)

最近のTeams(無料版)は、「今すぐ会議」機能だけでなく、「会議のスケジュール設定」機能が追加され、事前に未来の会議を作成し招待リンクを事前配布することができるようになりました。

動作確認

自宅のデスクトップPCとノートPCとでMicrosoftアカウントを別にしてTeamsに接続、会議を作成し、招待リンクを辿って会議に参加し、eMeetのマイクが使えることまで確認しました。

あとは明日会場で確認することとなります。

Java読書会 今月から読む本

はじめに

前回の本と台風とコロナ禍と

Java読書会BOF 主催のJava読書会は、昨年2019年11月から毎月1回のペースで「The Java Module System」(洋書)を読む会を開催し、先月2020年9月に読了しました。

この本の読書会期間中には、台風直撃とコロナ禍と大きな出来事が重なりました。

台風による中止

まず、予定していた第1回(2019年10月12日)は関東に台風19号が直撃し、中止としました。この台風では、鉄道の運休、多摩川の氾濫が発生するといった状況のため翌月に延期となりました。Java読書会BOF主催の読書会は毎月開催をしていますが、これが途切れたのは2001年6月以来で18年ぶりのことでした。

オンライン(Web会議)開催

また、2020年4月7日にはコロナ禍による緊急事態宣言が発出され、4月11日(土)に予定していた第6回は会場での開催ができなくなり、初のオンライン開催となりました。

緊急事態宣言の発出がほぼ確実視された時点でオンライン読書会を実施するためのサービスを調べました。当時の調査結果は次です1

Java読書会オンライン開催検討 - ソフトウェアエンジニアリング - Torutk

この中から、読書会参加人数の平均である11人程度をカバーし、開催時間である朝10:00~夕17:00までの7時間をカバーするサービスで無償なものとなると、Microsoft Teamsの無償版がほぼ一択でした。そこで、第6回~8回(4月、5月、6月)はTeamsを利用したオンライン開催としました。

読書会開催データ

2019年9月時点での読書会開催に関するデータです。

項目
開催回数 257回
書籍数 39冊
総ページ数 15,183ページ
1回の平均ページ数 59ページ
平均参加人数 11人
のべ参加人数 2,821人

10月からの本

Java読書会の継続に影響を及ぼす事象は自然災害だけではなく、Java技術に関する読書会向きな書籍の候補がでないという事象もあります。世の中的に出版不況や技術書籍の刊行が(初心者向けの入門本を除くと)不調というのがあるのかもしれません。

このような中、課題図書の候補のリストアップと投票を実施したところ、「データ指向アプリケーションデザイン」に決まりました。

投票の状況は次のとおりです。1票差と接戦でした。

書籍名 投票数
データ指向アプリケーションデザイン 9票
マイクロサービスパターン 8票
テスト駆動開発 2票
実践テスト駆動開発 1票
Design It!ープログラマーのためのアーキテクティング入門 1票

著者(Martin Kleppmann氏)について

著者の自己紹介ページ https://martin.kleppmann.com/

著者のMartin Kleppmannは現在英国ケンブリッジ大学で分散システムの研究者(Senior Research Associate/Affiliated Lecturer)。以前はソフトウェアエンジニア&起業家として活動。 また、オープンソースプロジェクト automerge、apache avro、apache samza の貢献者。 分散システムに関するカンファレンスのスピーカー。

内容(超概要)

分散システムにおいて主にデータを扱うシステムを構築するための様々な技術(原理)を解説しています。 データモデル、ストレージ、レプリケーション、パーティショニング、トランザクション、一貫性と合意、バッチ処理、ストリーム処理といった章題が並びます。

この書籍の感想ブログへのリンク

この書籍について感想を書かれているブログが多数ありました。 検索で見かけたものをいくつかピックアップします。

hydrakecat.hatenablog.jp

kuromt.hatenablog.com

takezoe.hatenablog.com

takuti.me


  1. 2020年4月10日時点の情報で、その後コロナ禍対応のためそれぞれのサービスが向上しています。

Androidアプリで使用するロギング考

Androidアプリケーションから使用するロギングの種類と選択

プログラミングをしてデバッグをする際、ロギングは欠かせません。Androidアプリケーションも昨今は規模が大きくなってきており(なんせGUIからデータベースからネットワーク、そしてデバイスを扱うところまで含まれますから)、デバッグは単純ではなくなってきています。

昔はワークステーションと呼ばれたUNIX計算機や、PC等でデスクトップアプリケーションやサーバーアプリケーション を開発してきた経験上、しっかりとしたロギング機構を使うことが不可欠です。

Androidアプリケーション開発では、標準ライブラリに含まれる android.util.Log を使ってロギングをすることが多いようです。Androidの標準ログ機構に記録されたログを読み出す開発ツールが logcat ですが、ロギングのことを logcat と呼んでいる記事等も数多く見かけます。では、Android アプリケーションのプログラミングではAndroid標準ログ(logcat)を使えば十分でしょうか? ちょっと調べてみました。

Android標準ログ(logcat)を調べたところ

  • AndroidJavaアプリケーション用に提供される標準APIに含まれる
  • 設定不要で、複数のレベルから1つを選択してログ出力する
  • 引数にはTAGと呼ぶ識別子(文字列)と、メッセージ文字列を指定する
  • ログを見るときは、adbシェル経由でlogcatコマンドを実行するが、昨今のIDEにはlogcatに気の利く機能が追加され便利につかえる
  • ログはAndroid上で動作するプログラムやOSからの出力が混ざっている。logcatを実行するとデフォルトでは大量のログが表示されるので、logcatのコマンドラインオプションでフィルターすることが多い
  • Android StudioなどのIDEではlogcatが常時実行されログが表示される
Android標準ログの問題点

ところが、このAndroid標準ログには問題もあります。

android.util.Log へログを出力すると、JNI呼び出しでネイティブコードからliblogdの関数が実行され、Android端末上にいるlogdプロセスにソケット通信でログエントリが渡され、リングバッファのデバイス(/dev/log/*)に格納されます。UNIXLinux での syslog に出力するイメージでしょうか。これは気軽にログを出すと性能が著しく劣化しそうです。

また、このLogは基本全てのログ出力呼び出しをだだ流しします。Javaアプリケーション側でログ出力を設定で抑制する手段がないので、if文でログ出力を制御するしかありません。それは避けたい・・・。

Googleのドキュメントにも、アプリケーションをリリースビルドするときはログ出力を削除しようと書かれています。でも、ログはアプリケーションが実際に使われている環境で生じた問題点を追究するほぼ唯一の手がかりです。ログを出さないということは考えにくいことです。

また、ログをためるバッファはそれほど大きくなく、端末により異なりますが手元のPixel 3の場合は256KBです。一日運用してトラブルがあった場合にログファイルを取得するといったことが難しいです。

Android以外の環境と共通化したいモジュールの作成では、Android固有のAPIを使えません。

代替のロギング手段

まずは、Android上でロギングを行うことができるライブラリをざっと調べてみたところ、次がでてきました(2,3年内にリリースがあったもの)。

  1. Java SE の標準ロギングである java.util.loggingパッケージが利用できる模様
  2. Timber というオープンソースライブラリを利用する
  3. SLF4J と Logback for android を組み合わせて使う
  4. SLF4J と Timber を組み合わせて使う

Timberは、Android標準ログをラッパーしたものです。

ログの出力の抑制がJavaアプリケーション内でif文等の制御をせずにでき、性能がそこそこでリリース時にファイルにログが取れ、他のプラットフォームと共用できるものは、1と3になります。

Androidアプリケーションプログラミングを5年振りに

はじめに

Androidアプリケーションのプログラミングは5年前に半年ちょっと程の期間取り組んで以来となります。

2015年初頭のAndroid開発環境は、最新OSがAndorid 4.4(KitKat)から 5.0(Lollipop)になった頃で、開発環境はそれまで主流のEclipseからAndroid Studioに移行が始まった頃です。

Javaは、Java SE 8仕様のJDK 8がリリースされ1年、ラムダ式が導入された等話題となりましたが、Android開発環境へのJava SE 8は進展がほとんどありませんでした。

2015年のAndroidアプリケーション・アーキテクチャ

画面レイアウトをXMLで記述し、アクティビティ、ブロードキャストレシーバ、サービス、コンテンツプロバイダと4種類のコンポーネントを必要に応じて組み合わせてAndroidアプリケーションを構成していました。

画面レイアウトがView、ActivityがController、コンテンツプロバイダがModel1となるMVCアーキテクチャと認識されていたようです。ただ、Activityがかなり頑張るファットコントローラーになっていました。

Activityの肥大化を抑制するため、Butter Knife、EventBusなどのライブラリが作られ割と広まっていたようです。 Modelのデータを永続化する際は、SQLiteアクセスを簡単にするORM(Object Relation Mapper)ライブラリがいくつかありました(例:Active Android)。

画面遷移を伴うアプリケーションでは、Activityを複数用意してIntentで切り替えるのではなく、Fragmentを導入して画面の一部を切り替えることが推奨でした。

この頃のアプリケーション実行はDalvik VMで、DEXファイルにはメソッド総数の制限等がありました。

5年振りのプログラミング(リハビリ期)

まず、開発環境としてAndroid Studioをインストールします。現時点での最新リリースバージョンは4.0.1でした。

アプリケーション実行はDalvik VMに替わりARTとなっていますが、ARTも初期のAOT(Ahead Of Time Compile)だけではなく、JITも取り入れたハイブリッドとなっていました。

Java SE 8(JDK 8)対応も進んでおり、ラムダ式(メソッド参照)、デフォルトメソッド等のJava SE 8言語仕様やJava SE 8の標準ライブラリを取り込みつつあります。これは朗報です。

また、Kotlin言語の使用も随分浸透しているように見えます。

いい感じに成熟してきているではないですか。

2020年のAndroidアプリケーション・アーキテクチャ

それでは、次はアプリケーションの構成をどうしようかと考えはじめてみたところ、

MVP、MVVM、DataBinding、LiveData、Jetpack、Room、DDD、Clean Architecture、‥‥と怒涛のようにキーワードが噴出してきました。

MVPとMVVMは、GUIアプリケーションを作成する際のアーキテクチャパターンで、Windows等のデスクトップアプリケーションでは以前から登場していたパターンです。DDDはドメイン駆動開発の略ですし、Clean Architectureはロバート C. マーチン氏の著になる書籍です。これらがAndroidアプリケーションのアーキテクチャの文脈に揃って出てきているのに驚きを覚えました。いったい何が起きているんだろう?

状況を整理するには、Jetpackを中心に調べるのがよさそうです。というのは、JetpackはGoole I/O 2018で発表された、次世代のコンポーネント、ツール、アーキテクチャガイダンスであり、今後のAndroidアプリケーション開発の指針およびライブラリ集となる存在です。DataBinding、LiveData、Room2 といったライブラリもJetpackに含まれています。 ViewModelライブラリも含まれ、これはどうやらMVVMパターンを構成するようです。その他お馴染みの Support Libraryも含まれます。

ということで、今後のAndoridアプリケーション・アーキテクチャはこのJetpackに沿っていくものと思われます。これから新規にアプリケーションを作成する際は、Jetpackのガイダンスとライブラリ集を利用するのがよいようです。

参考資料

developer.android.com

developer.android.com


  1. 別なアプリケーションとModelを共有せず、そのアプリケーション内で使うだけならばコンテンツプロバイダでなくPOJO(ふつうのJavaクラス)で実装する

  2. RoomはSQLiteを利用するORMで、@Entity、@Dao、@Database の3つのクラスでデータベースアクセスを実装

jlinkのオプション指定でカスタムJREのサイズ削減

jlinkのオプション指定でカスタムJREのサイズ削減

はじめに

先週のJava読書会BOF主催「The Java Module System」を読む会(第10回)では、jlinkコマンドで実行イメージを生成する章を主に読みました。 そこには、生成する実行イメージのサイズを小さくする幾つかのオプションが紹介されていました。 そこで、オプションを指定するとどれだけ実行イメージが小さくなるのか、手元の環境で確認しました。

確認環境

項目 内容
OS Windows 10 Pro 1909 64bit 日本語版
JDK Liberica JDK 14.0.2 full 64bit版

確認結果

サイズ削減に関するオプション指定のないデフォルトでの実行イメージ生成のコマンドラインが次です。 (実行イメージには、java.baseモジュールだけを含む指定)

D:\work> jlink --add-modules java.base --output runtime

ここに、いくつかサイズ削減に関するオプションを指定し、どれだけ実行イメージが削減されるかを見てみました。

No. 指定したオプション サイズ(MB)
1 デフォルト 46.1
2 --compress=1 39.0
3 --compress=2 33.7
4 --strip-debug 40.6
5 --no-header-files 45.9
6 --strip-native-commands 46.0
7 No.3、No.4、No.5 31.0
compressオプション

1を指定すると、文字列リテラルの重複をなくし、共有します。

2を指定すると、lib/modulesファイルをzip圧縮します。

strip-debugオプション

JDK 13より前は、Javaデバッグ情報を削除します。 JDK 13からは、Javaデバッグ情報に加えてネイティブコマンド・ネイティブライブラリからもデバッグ情報を削除します。

[JDK-8219207] Add --strip-java-debug-attributes jlink option - Java Bug System

[JDK-8219257] Add --strip-native-debug-symbols jlink plugin - Java Bug System

no-header-filesオプション

JNIライブラリ作成時に使用するC/C++のヘッダーファイルを削除します。

strip-native-commands

javaコマンド等を生成しないようにします。このオプションを指定して生成した実行イメージにはjavaコマンドがないのでアプリケーションが実行できなくなります。

何故このオプションがあるのかなと考えると、jpackageツール(JDK 14から搭載)でインストーラをつくるとアプリケーション起動専用実行コマンドが作られるので、javaコマンドがなくてもアプリケーションを実行することができるからではないかと思います。

jpackageコマンドが使用するjlinkのオプション

JDK 14から搭載されたjpackageコマンドは、--runtime-imageオプションで予め生成した実行イメージを指定しない場合、内部でjlinkコマンドを呼び出しアプリケーション実行イメージを生成します。このとき、--strip-debug、--no-header-files、--no-manpages、--strip-native-commands のオプションをjlinkに対して使用します。

まとめ

jlinkコマンドで実行イメージを小さくする幾つかのオプションが用意されています。 配布する実行イメージを生成するときは、必要がなければこれらのオプションを指定してイメージサイズを小さくするとよいです。