仕事でDBのマイグレーションに関わっていて、データの移行に適した良いツールないかなと探していたところ embulk というツールを見つけた。結構、流行っているということで調べ始めたところ、実行ファイルが面白い仕組みになっている事に気づいた。
embulk の Windows インストールは次のように記載されている。
PowerShell -Command "& {Invoke-WebRequest http://dl.embulk.org/embulk-latest.jar -OutFile embulk.bat}"
てっきり最近良く見るインストールスクリプトのダウンロード実行かと思ったら、そうではなく jar ファイルをダウンロードして bat ファイルとして保存しているだけだ。
昔から実行して展開できる形式の ZIP 圧縮ファイルはよく見たけれども、bat ファイルとはなるほどと思ってしまった。jar ファイルの内部形式である ZIP 圧縮フォルダはファイル末尾のエントリからの相対位置でエントリを記録することで、追記が可能なフォーマットになっている。このため、ファイルの先頭にZIP形式とはまったく関係のない任意のファイルを配置できる。
この方法を使えば、先頭から読むと bat ファイルのように実行でき、なおかつ jar ファイルとしても扱えるような特殊なファイルを作ることができる。*1
しかも、組み込むファイルは、ただのテキストファイルであるため、トリックを利用することでWindows バッチとしてもシェルスクリプトとしても実行できる jar ファイルにすることができる。
実際にバイナリエディタで開いてみると、embulk.jar の先頭は次のようになっている。
: <<BAT @echo off ... java %java_args% -jar %this% %jruby_args% %args% ... exit /b BAT ... exec java $java_args -jar "$0" $jruby_args "$@" exit 127
この方法を使えば、実行するだけで自動デプロイ可能な war ファイルなども作れる気がする。