ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

Hyper-V 上の Debian VM の vNIC の IP アドレスを管理 OS 側から取得できるように LIS を有効にする

表題通り。 Hyper-V 上の Debian 8.7.1 で Linux 統合サービス (Linux Integration Services; LIS) を有効にした方法のメモ。

私が試したのは、Windows 10 Pro (Insider Preview Build 14986) の Hyper-V 上の VMDebian 8.7.1 Jessie をインストールする Packer のビルドを実行しようとした、というもの。

前提

直面した状況

Packer でビルドして Hyper-V VMDebian 8.7.1 Jessie をインストールしようとしたところ、Packer がゲストマシンに SSH 接続しようとしてずっと待ち続けるという状況になった。 (下記表示のまま進まない。)

==> hyperv-iso: Waiting for SSH to become available...

Packer のログ ($env:PACKER_LOG=1 でログ出力されるようにした) を確認したところ、以下のようなメッセージが表示されていた。

2017/02/18 19:48:48 packer.exe: 2017/02/18 19:48:48 [DEBUG] Error getting SSH address: No ip address.

すなわち、管理 OS 側から仮想ネットワークアダプタの IP アドレスを取得できなかったぽい。

管理 OS 側から仮想ネットワークアダプタの IP アドレスを取得できなかった原因

「Error getting SSH address: No ip address.」 の原因を探したところ、以下の issue が引っかかった。 ここでゲスト OS 側が管理 OS に IP アドレスを伝える必要があるということを知った。

で、Linux ゲストの場合は、Linux 統合サービスが必要とのこと。

Debian 8.7.1 Jessie で LIS を有効にする

Debian 8 系では、LIS がディストリビューションに含まれている。

有効にするための手順がどこに書かれているのかわからなかったので困ったのだけれど、やってみたところ Debian 8.7.1 では、APT の hyperv-daemons パッケージをインストールして再起動するだけで LIS が有効になるっぽかった。 (実際に試して、管理 OS 側から IP アドレスを取得できることを確認した。)

apt-get install hyperv-daemons

今回の場合、Packer でビルドするために Preseed を使っていたので、preseed.cfg のパッケージ選択に hyperv-daemons を含めるようにした。

d-i pkgsel/include string openssh-server build-essential hyperv-daemons
    # これは一例です。 hyperv-daemons パッケージ以外のパッケージは必ずしも必要ではありません。

参考

  • Debian Jessie Hyper-V : Debian 8 で LIS を有効にする方法。 KVP、VSS、FCOPY 統合のために hyperv-daemons と 4.2 カーネルが必要とのこと。 KVP やら VSS やら FCOPY まで追いかけられていないが、参考にした。
  • Install Hyper-V (LIS) On Debian 8 : Debian 8 で LIS を有効にする方法。 こちらも参考にはしたが、ここに書かれている方法を全て実行する必要はなさそうだった。

読んだ : RESTful Web Services with Dropwizard / Alexandros Dallas 著

Dropwizard に関わる仕事をしているので読んでみました。

RESTful Web Services with Dropwizard

RESTful Web Services with Dropwizard

Dropwizard について

Dropwizard は Java の web アプリケーションフレームワークです。 基本的には既存ライブラリの組み合わせで web アプリケーションを構築するというもので、Dropwizard 固有の仕組みはさほど多くありません。 (例えば Web リクエストを受け取るのは Jersey で、DB アクセスには Hibernate か jDBI が使われる。)

特に Java EE 系の知識を持っている人であれば、とっつきやすい感じです。

本書について

本書は、Dropwizard を使って web アプリケーションを構築するための方法を説明するものです。 プロジェクトの準備や、HTTP リクエストを受けるエンドポイントの記述、DB アクセス、ユーザー認証、HTML を返す View テンプレートについてなど、基本的な要素について、サンプルコードを交えながら仕組みが解説されます。

Java EE などについてある程度わかっている人が読むと Dropwizard の公式ドキュメントを読むのと大差ないと思いますが、初心者の人が読むと結構わかりやすいんじゃないかなと思います。 (ある程度わかってる人にとっても、Dropwizard についてざっと知ることができて良いかもしれませんが、そういう使い方だとちょっと値段は高めに感じる気がします。)

本書での学び

参考のリンクとしては現時点での最新バージョンのドキュメントへのリンクです。 閲覧時の最新バージョンのドキュメントは各自探してください。

  • Dropwizard では、maven-shade プラグイン を使って、単体で web アプリケーションとして実行可能な JAR ファイル (uber-jar) を作る。
  • Hibernate Validator によるアプリケーション設定のバリデーションが可能。
  • jDBI で DB から取得した結果をオブジェクトにマップする方法として、@MapResultAsBean アノテーションを使うという方法もある。
    • 参考 : MapResultAsBean (jDBI 2.48.2 API)
    • とはいえ公式的なドキュメントは何もなく、ドキュメント化されていない挙動に依存することになるので不安。 (JDBI の機能の多くがドキュメント化されてないのでまあこれに限った話ではないのだけど。)
  • HTTP リクエストパラメータのバリデーション周り。
    • JAX-RS のリソースメソッドのパラメータのバリデーションを明示的に実行することも可能。 (@Valid アノテーションでのバリデーション実行しか知らなかった。)
    • 複数フィールドにまたがるバリデーション。
    • 参考 : Dropwizard Validation | Dropwizard
  • Dropwizard には HTTP クライアント用モジュールも含まれている。
  • 認証周り。
    • Basic 認証用のクラスが用意されている。
    • オプションの認証も可能。 (認証されたユーザーの場合はそのユーザー専用のコンテンツを表示し、さもなければ一般ユーザー向けのコンテンツを表示する、みたいな。)
    • CachingAuthenticator によるキャッシング。
    • 参考 : Dropwizard Authentication | Dropwizard
  • Fixtures for Easy Software Testing (FEST) というプロジェクトがある。 TestNGJUnit と一緒に使える。 ソフトウェアテストを書きやすくするライブラリ。

感想

Dropwizard をそこそこ使ってて公式ドキュメントも (全部ではないけど) 読んでいたので、本書での学びはあんまりなかったです。 とはいえ上に書いたように新たに知れたこともいくつかあったので読んでよかったです。 (そんなに時間もかけずにざっと読めましたし。)

とはいえ紙の本だと 30 ドル以上するので、ちょっと高い感じはしますね。

読んだ : Kotlin スタートブック ― 新しい Android プログラミング / 長澤 太郎 著

Kotlin エバンジェリスト (JetBrains 黙認) であり、日本 Kotlin ユーザグループ代表であるたろーさん (長澤 太郎) によって書かれた書籍 『Kotlin スタートブック ― 新しい Android プログラミング』 (赤べこ本) を読みました!!

Kotlinスタートブック -新しいAndroidプログラミング

Kotlinスタートブック -新しいAndroidプログラミング

本書を読む前から、公式のリファレンスチュートリアルなどの気になる箇所を見てはいて Kotlin についてはなんとなく理解はしていたのですが、ところどころ知識が欠けている部分もあったので、本書によってそういった知識の欠落を埋めることができました。

どんな本か?

内容については著者のたろーさんが紹介されています。

導入としてまず 1 部があり、2 部で Kotlin の文法や機能の詳細が解説されます。 3 部にて、Android アプリ開発で Kotlin をどのように活用できるかが説明されます。 対象読者は 「Java および Android 開発経験者」 と書かれていますが、2 部までなら Android アプリ開発については知らなくても問題なく読み進められます。 「Android アプリ開発で Kotlin を使うために読む本」 というわけではなく、「Kotlin を使い始めるときに読む本」 かつ 「Android 開発に Kotlin を活用するためにどうすればいいかが書かれている本」 という感じです。

全体としては易し目の説明でスクリーンショットも多用されているのでプログラム開発の初心者でも読みやすい本だと思います。 一方で、説明する内容についてきちんと節が分かれていて飛ばし気味に読むこともやりやすいので、ソフトウェア開発についてある程度経験がある人が Kotlin の導入のために読むというのにも適しています。

感想

Kotlin を Java の代わりとして使い始めるのは結構簡単で、いくつかある Java との違い (各種文法の違いや 「== 演算子は同一性検査ではない」 みたいな違い) をおさえさえすれば導入できます。 逆に導入するのが簡単なせいで、「ちゃんと Kotlin 特有の機能や文法を学ぶ」 機会を設けず、必要に応じて公式リファレンスを参照している、という人も多いのではないでしょうか。 私もまさにそんな感じだったので、今回本書を読んで Kotlin 特有の機能、文法を学べたのは非常に良かったです。

内容的には深く突っ込んでいくという感じではないので、本書を読みつつ気になったところは公式リファレンスを参照する、みたいに読み進めていくといい気がします。 公式リファレンスとは違った視点での説明されている項目もあったりするので、両方参照することで理解が深まったりもすると思います。 公式リファレンスには書かれていない 『!! 演算子の代わりに requireNotNull メソッドを使うと良い』 というような記述があるのも本書の良いところですね。

まさに 「これから Kotlin を使っていこうと思っている人のための Kotlin 入門本」 として、以下のような人にオススメできる書籍でした。

  • Kotlin を使ってみてるけどまだ Kotlin 全体についてちゃんとは学んでいない。
  • まだ Kotlin を使ってみてないけどこれから使ってみようかと思っている。

第 3 部の内容 (Kotlin で Android アプリ開発) について、ほとんど知っているものだったので自分にとってはあまり意味はなかったのですが、Kotlin を使った Android アプリ開発がどんな感じか全然知らない人にとってはそれらも役立つと思います。

読書メモ

自分にとって気になった箇所と、それに関連する公式リファレンスへのリンク。

Dropwizard + JDBI で SQL オブジェクトの返り値に Optional を使うときには SingleValueResult アノテーションが必要

DropwizardSQL ライブラリ JDBI を使うときのおはなし。

OptionalContainerFactory

dropwizard-jdbi ライブラリは OptionalContainerFactory クラスを提供してくれていて、JDBI の SQL オブジェクトで返り値に Java 8 で導入された Optional 指定することができます。

ちなみに普通に dropwizard-jdbi の DBIFactory#build メソッドを使うと自動的に OptionalContainerFactoryDBI に登録してくれるので、自分で登録する必要はありません。 (Dropwizard 1.0.5 で確認。)

SingleValueResult アノテーションが必要 (単に Optional を指定するだけでは動かない)

SQL オブジェクトのクラス定義で返り値に Optional を指定すればそれだけで動くのかと思いきや、実はそんなことはありません。 Optional を返すメソッドに SingleValueResult アノテーションを付ける必要があります。

import info.vividcode.app.web.example.dropwizard.domain.Person;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.customizers.SingleValueResult;

import java.util.Optional;

public interface PersonDao {

    @SqlQuery("SELECT * FROM person LIMIT 1")
    @SingleValueResult(Person.class)
    Optional<Person> findOne();

}

ここら辺のドキュメントがないので、ソースコードを読んで確認しました。

Optional を使う場合に限らず、Iterable じゃなくてコンテナを使いたい場合は SingleValueResult アノテーションを付ける必要がありそうですね。

関連ページ

MySQL Connector/J 5.1 系では useLegacyDatetimeCode=false にしよう

JDBCMySQL に接続するときに使用する MySQL Connector/J (mysql:mysql-connector-java) の話。 サーバー・クライアントのタイムゾーン設定が違っている場合にどう対応するのがいいか。

結論

  • MySQL Connector/J 6 (まだ開発版だけど) 以降は自動でやってくれるので気にする必要はない。
  • MySQL Connector/J 5.1 では URL に useLegacyDatetimeCode=false を入れて、時刻周りの新しい処理が動くようにしろ。
    • 新しい処理では、タイムゾーンの変換を一貫性をもってやってくれるようになる。
    • 『Use code for DATE/TIME/DATETIME/TIMESTAMP handling in result sets and statements that consistently handles time zone conversions from client to server and back again』
    • 参考 : 5.1 Driver/Datasource Class Names, URL Syntax and Configuration Properties for Connector/J
    • 5.1 系ではデフォルトでは互換のために新しい処理は動かないようになっているので、明示的に新しい処理を使うように URL で指定する必要がある。
    • バージョン 5.1.6 で導入された機能なので、それより古いものでは使えない。

問題

そもそもどういう問題に遭遇したのか。

MySQL Connector/J とタイムゾーン

おわり

タイムゾーンはライブラリ側がちゃんと面倒見てくれるだろう、と思って気にしなかったら、環境を変えて Java アプリケーションと MySQL サーバーのタイムゾーン設定がずれたときにいきなり想定しない動作になったりするので気を付けましょう。