理系学生日記

おまえはいつまで学生気分なのか

忍者TOOLS

任意のプログラムをWindowsサービスとして構成する

Windows で Java のデーモンをサービスとして起動させときたかったんですが、なんか良いものないかなと思ったら winsw というのを見つけました。

作者は Jenkins の川口耕介さんであり、もともと winsw も Jenkins を念頭に作成されたらしいです。 実際に GitBucket を動かしてみたところ、問題なくサービス化できています。

手順

Github 上にインストールガイドがあるので、それに従えば良いと思います。 というのも乱暴かもしれませんので、以下に概要を記載しておきます。ここでは、prg というプログラムをサービス化するという前提で記載します。

  1. winsw.exe をダウンロードして、prg.exe にリネームする
  2. 設定ファイルとして、prg.xml を作成する (後述)
  3. prg.exeprg.xml を同じフォルダに配置する
  4. コマンドラインで、prg.exe install を実行する。これで Windows に prg がサービス登録される。

あとは、Windows Service Manager を使って、Windows の起動に合わせて起動をかける等、通常のサービスと同様に設定が可能になります。

設定ファイル

以下が Jenkins 用のサンプル設定。

<service>
  <id>jenkins</id>
  <name>Jenkins</name>
  <description>This service runs Jenkins continuous integration system.</description>
  <env name="JENKINS_HOME" value="%BASE%"/>
  <executable>java</executable>
  <arguments>-Xrs -Xmx256m -jar "%BASE%\jenkins.war" --httpPort=8080</arguments>
  <logmode>rotate</logmode>
</service>

書いてあることはだいたい読めば分かりますが、上で記述されている中で分かりづらいものがあるとすると、BASE くらいかと思います。

  • BASE: winsw.exe (をリネームしたもの) が配置されているディレクトリ。環境変数として扱われるので、%BASE% で値が参照できる。

結構細かな設定が可能でして、

  • 作業ディレクトリ
  • サービスから出力されるログの扱い (ローテーション等)
  • サービス起動時のタイムアウト
  • 起動時に設定ファイル等をダウンロードできる (auto update)

とかが可能です。

Windows で何かデーモン的なものを立ち上げるときには、採用を検討しても良いのではないでしょうか。

PoEAA: Transform View

今日の Transform View は、View として、ドメイン層のデータをインプットにして、HTML を出力するトランスレータを採用するパターンです。

Patterns of Enterprise Application Architecture (Addison-Wesley Signature Series (Fowler))

Patterns of Enterprise Application Architecture (Addison-Wesley Signature Series (Fowler))

この種のパターンで実際に多く使用されているのは XSLT です。ぼく自身も、XSLT でフロントエンドの HTML を描画する B2C のシステムを担当したことがあります。XML を返す API と XSLT を組み合わせて HTML を作成するやり方です。 昨日の内容と合わせると、Template View と Transform View、2 つの View が登場したことになりますが、これまでの IT では

  1. Template View に対しては多数の対応エディタが存在している
  2. Transform View に対しては、それほど対応エディタは多くなく、また、保守が難しくなる

というのが一般的です。 しかし、それでも Transform View が使用されているのには訳があります。

  1. XSLT は「変換」に焦点が置かれるため、ロジックを不用意に導入することが少なくなる
  2. Web サーバがなくとも View のテストが可能

PoEAA: Template View

Template View パターンは、静的 HTML と同じ形で HTML を記述した上で、動的に変更するようなところにのみマーカーを埋め込むパターンです。 静的なところは WYSIWYG のエディタで記述でき、動的な部分は実際にレンダリングする際に、マーカーがプログラムの実装と連携する形でコンテンツを描画します。

Patterns of Enterprise Application Architecture (Addison-Wesley Signature Series (Fowler))

Patterns of Enterprise Application Architecture (Addison-Wesley Signature Series (Fowler))

この「マーカー」というのにもいくつか種類がありますが、通常はこのマーカーを 1 から作るということはありません。これを如何に効率的に使うか、また、新しいマーカーを(プラットフォームが提供する形式に沿って)作るか、ということが求められます。 一般的な例で言うと、ASP/JSP/PHP などがあります。 これらの技術にも、条件分岐やループを記述する専用のマーカーが存在していますが、これらを導入する際は、ページの側にロジックを持たせないように注意しなければなりません。ページの側にロジックを持たせると、同種のロジックが個々のページに散らばる等、望ましくない結果を招きます。

Template View の強みは、(プログラマではなく)デザイナーがページ構造を見ながら記述が可能なことです。Template View パターンが広まっている今、これが実現できているかについては多説ありますが…。 逆に、その弱みは、

  1. 容易にロジックが書けてしまうため、その後の保守が極めて難解になり得ること
  2. Web サーバと密結合することが多いため、テストがしにくい。(この点では、Transform View の方がテスト容易性がある)

となります。

PoEAA: Front Controller

今日は Front Controller。 Front Controller は セキュリティや国際化など、リクエストに対する共通処理を一元的に行い、その後、リクエストをコマンドオブジェクトに引き渡すというパターンです。

Patterns of Enterprise Application Architecture (Addison-Wesley Signature Series (Fowler))

Patterns of Enterprise Application Architecture (Addison-Wesley Signature Series (Fowler))

Front Controller は以下の 2 つで構成されます。

  1. Web Handler: URL と Request からどのコマンドオブジェクトに処理を移譲するかを決める
  2. Command: リクエストに対するアクションを行う

Web Handler については、Interceptor として使うのが有用だとされています。そういえば、某フレームワークもそんな形でした。

Command については、Web Handler からリクエスト毎に生成されます。このため、Command をスレッドセーフに作る必要はありません。

没入したのは恐怖でした、BIOHAZARD 7

遅ればせながら、BIO HAZARD 7 をクリアしました。グロテスク ver. の方です。

BIO HAZARD 7 については「原点回帰」と言われていたのですが、その評判は確かでした。 初代の BIOHAZARD を想起される恐怖がそこかしこに満ちていて、ゆっくり開くドアの向こうに潜むであろう得体の知れないものを恐れながら、ただただ進まざるを得ないという何とも言えない感覚に支配されていて、ぼくはこのゲーム、今でも一人でプレイしたくありません。

初代の BIOHAZARD に回帰しながらも大きく違うのは、1 つは没入感だと思います。 初代 BIOHAZARD は固定カメラ視点で展開されていきますが、BIOHAZARD 7 ではいわゆる First Person View で物語が進んでいきます。

主人公であるイーサンが体験する視界はゲームをプレイする自分が体験する視界であり、イーサンが体験する未知は自分が体験する未知になります。 そして眼前に広がる世界は、PS1 を遥かに凌駕する精細さで目の前に展開されて、この不気味な廃屋に自分だけが取り残されたかのような、そんな感覚から逃げ出すことができませんでした。

また、イーサンは戦闘に関しては素人です。少ない武器、乏しい体術、攻撃を除けることもままならない中、いつ何が出てくるか分からない状態での探索というのは過大なストレスを作ります。 きしむ足音、うなる風音の一つにも反応してしまうほどに空気を張り詰めさせ、人間が本能として持っているのであろう恐怖センサーを過敏にし、もう勘弁してくれという状況で襲いくる敵との対峙。退屈を全く感じさせないゲームでした。

誰だよ絶対 PS VR でプレイしようとか言ってたのはよー。これ VR でやったらトイレ行けなくなるだろうがよー。

やって損はしないゲームだと思います。しかし、グロテスク ver. と無印の価格差は一体なんだったのか。

tabindexで消耗していた話

tabindex には苦しまされることが多いです。

ぼくは以前に tabindex でタブオーダーが明示的に指定されているシステムのテストを行うことになったんですが、タブオーダーが設計上で明示的に指定されている以上タブオーダーがテスト観点に挙がり、打鍵でタブオーダーを一つ一つ確認するというテストを行いましたが、 タブオーダーのようなユーザインタラクションに関するテストについては「どのようにそのテスト実施者が行ったテスト実施結果の正しさを確認するのか」という問題があり、たいへんつらいものでした。

今日のエントリでは、そもそも論として、tabindex の機能、そして、その使い方のベストプラクティスは何なのかを考えてみます。

tabindex とは

tabindex というのは、HTML 仕様で定義されている属性で、

  1. tabindex 属性を付与された要素がフォーカスを持てることを示す
  2. (TAB キー等で)フォーカスを移していく操作によって、フォーカスを移動できるかを示す
  3. フォーカスの移動順(タブオーダー順)を示す

といったことを可能にします。最後に示した フォーカスの移動順 というのは、実は tabindex 属性のオプション機能でしかありません。

tabindex が付与されていないタグに対しては、ブラウザはデフォルトの動作を適用します。 具体的には、<a><audio><button><img><input> といったタグ (これらを Interactive Content と呼びます) に対しては、デフォルトでフォーカスが当たります。 逆に言えば、<span><div> といった Interactive Content ではないタグに対してフォーカスを当てるためには、明示的な tabindex 属性の付与が必要です。つまり、tabindex 属性はタグを Interactive Content に変える、といっても良いかもしれません。

tabindex の使い方

tabindex については、大きく分けて 3 つの使い方があります。

  1. tabindex="0" を指定する
    • 指定されたタグは、ブラウザ上でフォーカスを受けることが可能になります。"0" が指定された場合、そのフォーカス順 (タブオーダー) はブラウザが決めます。ブラウザは通常、DOM 上での出現順にタブオーダーを割り当てます。
  2. tabindex="-1" 等、負の数を指定する
    • 指定されたタグは、フォーカスを当てることは可能になりますが、タブオーダーの中には含まれません(タブを押すだけでは、フォーカスを与えられません)。フォーカスを当てるためには、JavaScript 等で明示する必要があります。
  3. tabindex="1" 等、正の数を指定する
    • 指定されたタグは、ブラウザ上でフォーカスを受けることが可能になります。また、タブオーダー順で考慮されます。

最後の「タブオーダー順で考慮される」っていうのはちょっと複雑なんですが、大まかに言うと、

  1. tabindex が指定されている要素の方が、指定されていない要素よりも前
  2. tabindex の値が正の数の場合、tabindex が 0、または負の数の要素よりも前
  3. あとは大体、tabindex の値順

っていう感じになります。

ベストプラクティス

長々と書いてしまいましたが、tabindex については、

  • 使うなら負の数指定、あるいは 0 指定
  • 正の数は指定するな

が推奨になります。 これは、W3C の HTML 仕様ARIA のベストプラクティス にも記載があります。

W3C HTML 仕様

Using a positive value for tabindex to specify the element’s position in the sequential focus navigation order interacts with the order of all focusable elements. It is error-prone, and therefore not recommended. Authors should generally leave elements to appear in their default order.

ARIA-Practices

When using roving tabindex to manage focus in a composite UI component, the element that is to be included in the tab sequence has tabindex of “0” and all other focusable elements contained in the composite have tabindex of “-1”.

正の値を指定しないのは、タブオーダーの指定がミスしやすいからです。

通常のタブの遷移は、いわゆる Z 型、左から右、上から下に遷移するというのが自然なタブオーダーとされていて、普通に HTML/CSS を書くと、このあたりはブラウザが標準で行ってくれます。 しかし、tabindex 属性で正の値を指定する場合、これらのタブオーダー遷移が崩れやすくなります。要素の追加、削除に伴なって、tabindex の値を正しく保つのは並大抵のことではありません。

この保守コストを支払ってでも、タブオーダーを操作したいケースというのはそうそうあるものではないと思うので、tabindex を使って明示的にタブオーダーを操作する必要があるのかは、慎重に考えた方が良いところだと思います。

Macを切り替えたら exec-path-from-shellで環境変数が引き継がれなくなる

ずっと MacBook Air で日常を暮らしてきて、やっぱりデカいディスプレイで暮らしたいなぁということで、昔つかってた iMac に乗り変えました。 そこで困ったのが、Emacs で環境変数が引き継がれてこないということでした。

Emacs では、exec-path-from-shell を使うことで、zsh に定義した環境変数を Emacs でも使えるようにしているんですが、PATH とか GOPATH とかが使用できなくなっている。なぜだ。

これ、原因は、デフォルトシェルを切り替えていないからでした。これで解決。

$ sudo echo '/usr/local/bin/zsh' >> /etc/shells
$ chsh -s /usr/local/bin/zsh
$ sudo shutdown -r now

内容

exec-path-from-shell は、環境変数の引き継ぎを「シェルを実際に Emacs 内部で実行し、printf 等を使用して環境変数の値を出力させ、それを読み取る」という形で実現しています。 そして、ここで実行されるシェルというのは、以下のように決定されます。

  1. exec-path-from-shell の exec-path-from-shell-shell-name で定義されたもの
  2. Emacs の shell-file-name で定義されたもの
  3. (Emacs から見える) SHELL 環境変数の値

具体的な関数はこちら。

(defun exec-path-from-shell--shell ()
  "Return the shell to use.
See documentation for `exec-path-from-shell-shell-name'."
  (or
   exec-path-from-shell-shell-name
   shell-file-name
   (getenv "SHELL")
   (error "SHELL environment variable is unset")))

Emacs の設定を色んな環境で使用しようと思うと、elisp の変数に対してパスを設定することは望ましくありませんから、ぼくはこのうちの 3. を使っていました。 結果として、デフォルトシェル(bash)の環境変数が使用されていたというお話。

JavaでのQRコード生成

QR コード

あまり知られていませんが、QR コードは日本発の規格になります。 スマートフォンで打ち込むのが面倒なデータをカメラ読込のみで入力できることから世界的にも普及しておりまして、先日は iOS の Chrome に QR コードをスキャンする機能も追加されたのは記憶に新しいところです。

Java における QR コードライブラリ

Java で QR コードを作る場合、zxing (Zebra Crossing) を使用するのがスタンダードのようです。 これとは別に、QRGenというライブラリもあるのですが、こちらも内部で zxing を使用しています。QRGen については、すごく使いやすいインタフェースを提供してくれているので、そちらを使うという選択もアリだとは思います。

本日(2017/03/11) 時点でのデータは以下のとおり。

ライブラリ ライセンス Star 最終 commit
zxing Apache License 2.0 12,454 2017/03/08
QRGen Apache License 2.0 593 2016/10/31
Barcode4J Apache License 2.0 - 2012/????

zxing を用いた実装

最初に、作成した画像をそのままブラウザに返却する想定の実装例です。これにより、以下のような QR コードが生成されます。

    // QR コードで表現するコンテンツ
    final String contents = "kiririmodeのQRコード";

    // QR コード生成用のオプション
    final Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
    hints.put(EncodeHintType.MARGIN, 2);
    hints.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8);

    try {
      // QR コード用一時画像ファイルの作成
      final Path path = Files.createTempFile("qr", ".png",
          PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rw-------")));

      // QR コードデータの生成
      final BitMatrix matrix =
          new QRCodeWriter().encode(contents, BarcodeFormat.QR_CODE, 1024, 1024, hints);
      // QR コードを画像化
      MatrixToImageWriter.writeToPath(matrix, "PNG", path);

      final HttpResponse response = new FileResponse(path.toFile(), true);
      response.setContentType("image/png");
      return response;
    } catch (WriterException | IOException e) {
      throw new RuntimeException(String.format("converting [%s] to qrcode fails", contents));
    }

QR コード生成用のオプションは、個々に EncodeHintType として表現します。

エラー訂正のレベル

まず、ERROR_CORRECTION はエラー訂正のレベルになります。QR コードは wikipedia:リードソロモン符号 をベースとしており、誤り訂正を行うことができます。

エラー訂正レベルを上げるほど、一部が隠れていたり滲んでいたりしても QR コードとして読み取ることができますが、そのぶんデータ量が多くなります。データ量が多くなれば、クライアント側の読み取り速度にも影響を与えることがあります。 デンソーに依れば、エラー訂正レベル M (15 % まで訂正可能) で使われることが多いようです。

文字コード

また、文字コードのデフォルトは、ISO-8859-1 なので、日本語が表現できません。日本語を QR コードに埋め込みたい場合は、実装例のように CHARACTER_SET に対して UTF-8 等を明示的に指定する必要があります。

バージョン

QR コードにはバージョンがありますが、これは仕様としてのバージョンではなく、その QR コードのサイズによって分類されています。 そのサイズによって当然ながら QR コードに含められる情報量は変化します。ただ、zxing はそのあたりの面倒を自動的に見てくれる (コンテンツのデータサイズによって、自動的にバージョンを判別し、それに応じたサイズの QR コードを出力してくれる) ので、実装上あまり悩むことはないと思います。

全体として

全体として、zxing はすごく使いやすいライブラリだと思います。 最初だけ、どこから手をつけれんば良いんや…という状態でしたが、色々なサンプル実装を見た後で JavaDoc を読み解けば、なるほどこうすれば書けるのかというのが掴めてきます。

個人で実装するのは相当つらそうだったので、有り難く使わせてもらおうと思います。

PoEAA: Page Controller

Page Controller は、特定ページ/Action に対するリクエストを処理するオブジェクトです。

本書では、これを実現する方法として、

  1. Server Page (ASP/PHP/JSP 等) に混ぜる
  2. Script (CGI/Servlet) で記述する

という方法を謳っていますが、このうちで Server Page に混ぜる方法については、構造が汚くなるぞという念押しがされています。まぁ実践としても、コントローラは独立した Object として分離するというのがどこでも実施されている方法だと思います。 分離したコントローラの基本的な責務としては、

  1. URL のデコードと、Form データの抽出
  2. モデルの作成と、作成したモデルにデータ処理をさせる
  3. どの View を表示するかの決定と、当該の View に対するモデルの情報の引き渡し

となります。

PoEAA: Model View Controller

今日からは、Web Presentation Pattern の章にはいります。 最初が Model View Controller なんですが、おそらく開発者の誰もが聞いたことがあるパターンです。

Patterns of Enterprise Application Architecture (Addison-Wesley Signature Series (Fowler))

Patterns of Enterprise Application Architecture (Addison-Wesley Signature Series (Fowler))

Model View Controller は、以下の 3 つの役割を定義するところから始まります。

  1. Model: ドメインに関する情報を表現するオブジェクト
  2. View: UI 上のモデルの表現
  3. Controller: ユーザの入力を受けて、モデルを操作し、View を適切に更新する役割。

この 3 つの役割により、UI は 2 つの分離が起こります。1 つは「モデル」からの「表現」の分離、もう 1 つは「表現」からの「Controller」の分離です。特に前者の分離の重要性は著しく高く、これは以下のような理由に依ります。

  1. そもそもモデルと表現では、開発者に求められるスキルセットが全く異なる
  2. 同じモデルに対する、複数の表現が必要となるケースが多々ある。リッチクライアントやブラウザ、API や CLI インタフェースなど。
  3. 表現を排除すれば、モデルに対するテストが容易にある

逆に興味深かったのが、公社の「表現」と「Controller」の分離の重要性は低いとされていることです。 例として挙げられているのは、View の Editable/Non-Editable (Readonly) の振舞いをどう実装する場合が多いか、ということですが、これを分離しようと思うと、Editable な Controller と Non-Editable な Controller を配置することになると説明されています(たぶん)。 一方で、実際としてはそんなことはせず、1 つの Controller で Editable/Non-Editable の両方の View の振舞いを実現するはずだし、表現と Controller の分離は必要になったときにすれば良いよって温度感でした。

というわけで、これからようやくおもしろい章に入りそうです (DB あたりは長かったので飽きてきていた)。