naoki86star

インターネットの片隅でなにかしら書いてみる

proguard / sbt-proguard

proguardというのは、javaのコードを難読化してくれるソフトウェア。
お仕事でantタスクで動いていた成果物をありがたく使わせてもらっていたがコンパイル環境とか変化に対応する必要があって、基本的なところから調べる・覚える。元の環境はant with jdk8。

これはproguard(on sbt)をjdk11, jdk17で使おうというゴールのためにヒューリスティックに調べたときのメモ

  • 初めてproguardの動作を俯瞰して理解して見てみるためにはguiのツール(proguardgui.sh)が役に立つ。
    • guiは実行時にconfigurationファイルを保存できる。このファイルと、guiでの設定を比較すると、動かし方・設定ポイントが理解しやすい、と自分は思った。
      • injarというのが入力で、とか、dontoptimizeというのが動作のオプションで、とか、を比較して分かるようになり、これをもとにコマンドラインからの実行の理解の助けになり、proguardのドキュメントも何を言ってる部分が分かる感じで読みやすくなる。
  • オプションの選択と、難読化をかけたくない・あるいはかけると実行に不具合が起きるクラスをうまいこと設定するのがポイント
    • 実行が成功する(出力jarが得られる)ようになったらjar tvfコマンドでどんなクラス名に置き換わったか見ながら調整、というのは必須に思える。
  • librariesJarという設定がよくないと実行が失敗するのだが、jdkのバージョン特に17以降で設定の雰囲気が違う
    • 8, 11のときはJAVA_HOMEを渡しておくといいのが、17のときは必要なjmodをすべて明示的に設定する、とうまくいく
    • とりあえずJAVA_HOMEだけ渡す、もしくは11以降だとjdkのjmodをすべて明示的に設定するとかがよく、それ以上の外部ライブラリを渡してもうまくいかない、ことがある
  • sbt-proguardを使うことでsbtから必要モジュールのダウンロードとか難読化実行とかbuild手順に組み込むことができる
    • コンパイルしてassemblyしてそれを難読化の流れであれば、sbt-proguard / sbtはラクチン。
    • sbt-proguard / sbt でlibrariesJarの設定はどうするのがいいのか 少なくともjdk11 17で分岐設定するように書かないといけないオーバーライドしてJAVA_HOMEだけにするとうまくいってることもあるが、openjdkの形態によってはjmodsを明示する必要がある。
 Proguard/proguardLibraries := Seq(file(System.getProperty("java.home"))),
    • sbt-proguardの細かい設定(どんな項目があるのか、型はなんなのか)は、ソースを見て試していく
    • 難読化実行時にconfiguration.proというファイルを出力するので、この内容を見ながらデバッグとか調整とか
    • 除外クラスの設定とかの量が多ければ、テンプレート的にファイルを用意しておいてコマンドライン実行のほうが、見通しがいいかもしれない。
      • build.sbtでsettingで冗長に書き連ねる(あるいは別*.scalaに追い出せたとしても)のを後になって見るとなんだかよくわからないし、設定は一貫性を持って決めると思うので、少なくとも配列の形で記述できていないと、...、後で読めない。