今日もプログラミング

IT技術とかプログラミングのこととか特にJavaを中心に書いていきます

EmbulkをWindowsで正しく起動する

embulk.batで起動する

前回は、Embulkを

java -jar embulk.jar <command> ...

で起動していたが、実はこれは正式な起動方法ではない。

embulk.jarをembulk.batにリネームし、

embulk <command> ...

で、すっきりと起動できるのだ!

 

但し、0.4.8まではembulk.bat <command> ...でないと起動できなかった(詳細はこちら)。

 

どうして起動できるのか?

embulk.bat(元はembulk.jar)の中身をテキストエディタで開くと、先頭に以下のようなコマンドが埋め込まれている。

java -jar %~f0 %*

これは、

java -jar <embulk.batのフルパス> <コマンドライン引数>

に展開されるので、embulk.batがJARファイルとして実行される。

 

ビルドスクリプトbuild.gradleを見ると、

task cli(dependsOn: ':embulk-cli:shadowJar') << {
    file('pkg').mkdirs()
    File f = file("pkg/embulk-${project.version}.jar")
    f.write("")
    f.append(file("embulk-cli/src/main/sh/selfrun.sh").readBytes())
    f.append(file("embulk-cli/build/libs/embulk-cli-${project.version}-all.jar").readBytes())
    f.setExecutable(true)
}

のようになっている。つまり、元のJARファイルの先頭にselfrun.shの中身をくっつけているようだ。

 

ZIPファイルの仕様では、ヘッダは必ずしもファイルの先頭になくてもよいらしい。

従って、このファイルはbatファイルとしても実行できるし、JARファイルとしても認識されるようだ。

こんなテクニックがあるとは知らなかった…。

 

ちなみに、拡張子をzipに変えてもWindowsの機能では展開できなかった。Lhacaでは展開できたけど。

 

なお、java.util.zip.ZipFileクラスのソースも覗いてみたが、ほとんどnativeだった…。

パフォーマンス上げるためなんだろうね。

 

OS Windows 7
Java 8u31
Embulk 0.4.9