Edited at

AndroidSDKのライセンス文書処理とjavaのデフォルトエンコーディングにまつわるトラブル

わりと特定条件下で発生する問題。(潜在的には多そうな話?)


特定条件下って

おおまかにこの2条件が成立すると起きる現象だと思ってます。該当しない人には無関係だと思うのでスルーしてください。


  • java実行時のファイルエンコーディング設定を明示していない。もしくは、明示しているがUTF-8ではない。

  • Android SDKのライセンス文書自体を取り扱う。文書の最終取り扱い先がUTF-8で動く。


AndroidSDK のライセンス

よく見ると、Androidリポジトリのxmlに記述されているライセンス文書のうち、

セクション12.1.だけに 全角アポストロフィ が入っている。

全角:12.1 -略- (including reasonable attorneys’ fees)

半角:12.1 -略- (including reasonable attorneys' fees)

(上がもともとあったもの、下が半角にしたもの)

## 起きた実例

kivy-buildozer では、androidアプリのビルド時にAndroidSDKの各パッケージをダウンロードするように動いている。

これは内部的に、


$ tools/android update sdkコマンドを実行して、出力をキャプチャして表示しつつ、[y/n]のダイアログを見つけたらyを投げる」


という処理をしているのだが、java実行時のfile.encodingがUTF-8になっていないと、コマンド側で出力されるテキストがUnicodeで出力されずに、python側がデコード失敗するというものだった。


対処

基本的には「呼び出す側のプログラムと呼び出される側(今回はandroid)での、処理エンコーディングのミスマッチ」が原因っぽいので次のような対処をしていけばいい?


1. java実行時のエンコーディングを明示して実行させる

buildozerでの対応はこれ。

JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 で指定できるので、あらかじめenvに入れておくか、実行時に指定できるようにしておけばOK

(多分こっちが正答)


2. デコード失敗を無視して処理を進める

対処の方式として一つの手ではあるけど、肝心なところがこの現象に引っかかったりすると良くない。

あと、ライセンス文書を加工するのってまずいような。


3. java のエンコーディングに呼び出し側を合わせる

思いつきで書いたけどたぶん無理。直前にわからないから


4. 呼び出す側をjavaで作る

もともと、javaのプログラム上でandroidコマンドを実行する分にはエンコーディングが揃ったままなので行ける気もする。試してないけど


5. androidコマンドは別に実行する

buildozerのケースでも、失敗後にandroid-GUIでパッケージをインストールさせてしまえば以降はそんなに問題にならないとは言える。

でもそれじゃせっかくのツールが意味が無いかな、と。


所感

書けば書くほど、レアケース感がすごい。(javaのファイルエンコーディングに関する記事はBlogでかなり見るので、あらかじめ指定してそうなのが強い)

が、後で思い出す時に便利そうなのと、Pull Requestを投げるいい機会になったので、とりあえず書いてみた。