読者です 読者をやめる 読者になる 読者になる

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

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

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

読んだ : 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 サーバーのタイムゾーン設定がずれたときにいきなり想定しない動作になったりするので気を付けましょう。

grunt-ts が .baseDir.ts ファイルを作るのを抑制する

Grunt を使っていて TypeScript のビルドを行うタスクを定義する際には grunt-ts を使うことが多いでしょう。 (grunt-typescript もあるけど。) grunt-ts で困ったことがあったので書いておきます。

outDir オプションを使うと .baseDir.ts ファイルが作られる問題

grunt-ts を使って tsc コマンドの --outDir オプション指定を行うには outDir プロパティが使えるのですが、この値を指定すると、何故か 「.baseDir.ts」 という名前のファイルがソースディレクトリの方に生成されてしまいます。

このファイルは何かというと、TypeScript 1.5 で --rootDir オプションが導入される前に grunt-ts 独自に --rootDir 相当のことをするために導入されたものです。 grunt-ts のドキュメントを読む限り、baseDir オプションを使っておらず、fast コンパイルが無効になっている場合には 「.baseDir.ts」 ファイルは作られないはずです。 しかしながら、grunt-ts 5.5.1 で試したところ、baseDir オプションを使わず fast オプションに "never" を指定しても outDir オプションを指定すると 「.baseDir.ts」 ファイルが作成されてしまいました。 個人的にはバグっぽいなーと思っています *1。 一応 pull request を投げておきました。

ちなみに以下のような Gruntfile.js (一部) で動作確認しました。

grunt.initConfig({
  ts: {
    default: {
      src: ["src/ts/**/*.ts"],
      outDir: "build/ts"
      options: {
        fast: "never"
      }
    }
  }
});

回避方法

現在 (バージョン 5.5.1) の grunt-ts に .baseDir.ts ファイルを作らせないようにする方法はいくつかあります。

outDir オプションではなく additionalFlags--outDir オプションを指定する

grunt-ts は outDir オプションを見て 「.baseDir.ts」 ファイルを生成するかどうか決めているので、additionalFlags の方で --outDir を指定すると 「.baseDir.ts」 ファイルは生成されません。

grunt.initConfig({
  ts: {
    default: {
      src: ["src/ts/**/*.ts"],
      options: {
        additionalFlags: "--outDir build/ts"
      }
    }
  }
});
tsconfig.json ファイルを指定する

tsconfig.json の中で outDir オプションを指定し、grunt-ts には tsconfig プロパティで tsconfig.json のパスを指定教えるだけにするという方法もあります。 ただし、普通に指定するだけでは tsconfig.json を解析して grunt-ts が余計なことをするっぽい (tsconfig.json 側で outDir オプションを指定していると、grunt-ts が .baseDir.ts ファイルを作ってしまう) ので、passThrough オプションを有効にして、grunt-ts が余計なことをしないようにする必要があります。

grunt.initConfig({
  ts: {
    default: {
      tsconfig: {
        tsconfig: "src/ts/tsconfig.json", // このファイルの中でコンパイル対象のファイル群や `outDir` 指定を行う
        passThrough: true
      }
    }
  }
});

おわり

こんなしょうもないことをやってるのは無駄だと思うし grunt-ts はオススメしません。

関連ページ

*1:ドキュメントの記述から察するに仕様ではなさそうだし、コードの実装も微妙に変なので

UWP アプリ 「みお×ぽん」 のバージョン 1.1.0 をリリースしました

2016 年 10 月 1 日、IIJmio の 「IIJmio 高速モバイル / D サービス」 が au の回線にも対応して 「IIJmioバイルサービス」 に改称されました。

それに合わせて、「IIJmioバイルサービス」 のクーポン切り替えを行うことができる UWP アプリ 「みお×ぽん」 をバージョンアップしました。

www.microsoft.com

文言変更や一部デザイン変更、バグ修正のみであんまり大きな変更はしていないのですが、ご利用くださっている方はバージョンアップしてくださいませ。

変更内容

  • IIJmio 高速モバイル / D サービス」 という文言を 「IIJmioバイルサービス」 に変更。
  • 画面幅が小さい場合には、閉じた状態のナビゲーションウィンドウを完全に非表示にするように変更。
  • UWP アプリのライフサイクルを適切に扱えていなかった問題を修正。 *1

ちなみに公式アプリもあるよ

「みお×ぽん」 の最初のリリース時には IIJ による公式の UWP アプリはなかったのですが、2016 年 6 月ごろに公式アプリがリリースされました。

やったぜ!

*1:昔の MS のサンプルプロジェクト通りの実装だとだめっぽい。 これに関してはまた書こうと思う。