ProGuardで処理したJarとSpringFrameworkの相性が悪い

生きてます。

最近、某社の基幹システム再構築案件で超忙しく、なかなかブログを書く暇もない。 単なる技術メモ程度の内容でしかないにもかかわらず、何たることだ。

しっかしこの某社、当社がプロジェクトの立て直しを手伝う前は、インチキ方法論者の某氏*1と愉快な仲間たちにまんまと騙されてボロボロな状態だったんですが、やっとマトモなプロジェクト進行ができるようになった感じです。お客様サイドも含めた現メンバー全員が頑張ってくれているおかげですね。皆さんありがとう。


で、某氏と愉快な仲間たちへ言いたいことはもちろん色々あるのですが。

一言で片付けるならば

「あなた達にはプロを名乗る資格が無い」

そして、もはや僕には関係ありませんが、新たな犠牲者(企業)が出ないことを祈るばかりです。



さて、愚痴はこれくらいにして今日のお題を。

ProGuardで難読化したらアプリが動かなくなった

ProGuradとは

ProGuardは本来、Androidアプリ向けのJarサイズ圧縮ツールです。サイズ圧縮は以下のような手法によりなされます。

  • シンボル置換(クラス名とメソッド名を全部'a'にする、とか)
  • メソッドのインライン化
  • クラスのインライン化(親クラスと子クラスをくっつけて一つにする)
  • その他いろいろな最適化、つまりバイトコードを激しく改変

こういう処理を経た結果、副作用として難読化にもなるわけです。 ウチの例だとざっくり1割(3,000KB→2,700KB程度)減るので、そこそこ激しく内容改変しとるんだろうなあ、というのがわかります。

ウチは元々、難読化目的でyGuardを使っていたのですが、yGuardがJava10に対応してくれないのでProGuardに乗り換えた次第です。

SpringのComponentScanが動作しない→zipのディレクトリエントリが消されたのが原因

はい。

見出し通りなのですが、ProGuardで処理したJarはzipのディレクトリエントリが消えてファイルエントリだけになります。 なんでこんな事をしているかというと、これによりごく僅か(〜10Kバイト)のサイズ削減ができることが理由のようです。

しかしながらSpringは、Jarに対するComponentScanをzipのディレクトリエントリを足がかりに行うため、ProGuardで処理したJarは全くComponentScanが効きません。

対応策としては、-keepdirectories **を指定してディレクトリエントリを全てキープさせればOK。

おしまい。

*1: この人が最近上梓した本の評価が高いのがマジで謎。前半は凡庸、後半はカルト宗教の勧誘文書ないし野球経験のない人が書いた野球評論という感じ。