Kengo's blog

Technical articles about original projects, JVM, Static Analysis and TypeScript.

codexでJVMバイトコード静的解析ツールを書いた

今年の目標としてRustでCLIを作りたかったのと、coding agentの台頭で静的解析ツールに求められるものも変わるのではないかと想定したことを受けて、RustでJVMバイトコードを解析するコマンドを作りました。

図1 ChatGPTに描かせたロゴ

開発の背景

SpotBugsへの貢献を止めてから後、実は2度ほど静的解析ツールを開発していました。目的はKotlinコンパイラプラグインとして動くものを書くことです。KotlinのIRを静的に解析することに挑戦したかったですし、独立したツールとして提供するよりもIDEやビルドシステムに統合されていた方が体験が良いのではと思ったからでした。差分コンパイルなどのプラットフォームの最新技術の恩恵も得られそうだと思いましたし。

しかし1度目は自分で書き、2度目はエージェントに書かせる形で挑戦したものの、結局はKotlinコンパイラが充分な情報を提供してくれ無さそうという結論になり、いずれも挫折しています。

そこから月日が経ちcoding agentが一般的になったことで、こうした統合の価値がほぼ無くなってきたのでは?むしろ設定や統合をできるだけ減らしてCLIでサクサク実行できる方がいいよね?ということを思いつき、成人の日を使ってcodexといっしょに書いてみた、というところです。もはやJavaやKotlinを書くのにIDEA使わなくなりましたもんね。

なおRustにしたのは知人と話していたときに、高速起動はやっぱRustかGolangだよな、Rustのほうがシステムプログラミング寄りだし一番速そう、みたいな話で盛り上がっていたのがきっかけです。変な苦手意識を取り除くためにも、自分が詳しくて簡単に検証サイクルを回せる開発テーマで使ってみるべきだ、という直感もありました。

codexと開発するうえで工夫したこと

claude codeのplan modeがいいぞという話を多く耳にしたので、codexで開発するうえでもまず how do you plan ~ という質問をまずして計画から入るようにしました。これはControl Flow Graph (CFG)のような静的解析としては一般的な構造や、厚めに書きたいテストケース周りでは特に役立ったと思います。エージェントと2人で仮説を持って開発に臨めること、結果として出てきたものをどんな観点でレビューすべきかをあらかじめ考えて臨めること、特にこの2点がコード変更量に圧倒されないために有用でした。

また経験上必要になるとわかっている性能検証用の実装( --timing オプションやベンチマーク用スクリプト )や実際のJavaコードを使ったテストを書くための spotbugs test harnessのようなハーネスを早期に実装できたのもかなり有効な工夫だったと思います。ひとつひとつの変更を積み重ねると全体最適でなかったり clone が多発するようなコードになったりして、性能改善のための開発を要所要所で入れていく必要があるのですが、その際にベンチマークによって「どこで、どのくらい」遅いのか、変更でどのくらい改善されたのかということがcodexにとって一目瞭然な状態を組み上げられたので、高速化のための方針策定からcodexに任せられるようになりました。たとえば v0.4.0 リリースではcallgraph edge overheadの2倍近い高速化を実現しましたが、このときのリクエストは次のようにとてもシンプルなものでした:

any idea to shorten analysis_load_ms? it is slow even when we load a single jar, so the cause is not storage I/O I guess.

これだけ書くとコードから仮説を立てて、ベンチマークを都度回しながら有効な手段を特定して実装してくれます。もちろん機能に影響はないことは単体テストとスモークテストで確認できる状態です。最終的には関数実行ごとに clone が実行されている点の修正が提案されましたが、その際もパフォーマンスを評価することをこちらから次のように依頼し、実際に実行されました:

reduce per-call cloning in build_edges then rerun the bench-spotbugs.sh to confirm the perofrmance.

ベンチマークを見ながらパフォーマンス確認できるところまでひとりで持ってくるのは何かと時間がかかり、かつ個人OSSではその内容に確信を持つためのレビューをお願いすることも難しいので、coding agentによってスピードと品質とが両方向上したと感じます。

今後の開発について

本番投入を考えたときに今の実装に足りていないのはルールセットをカスタマイズするための設定ファイルと、ルールをプラグインのような形で増やせる仕組み、そして組み込みルールの数です。そして前者2つについては実装戦略はわかっており、後はやるかやらないかだけという状況です。

ルールを増やすことはcoding agentにとっておそらく容易なことでしょう。既存ツールのルールを並べて評価し、重要そうなものをより本質的なルールへと再定義し、これを実装するだけです。間違いなく人間よりも早く量を用意できると思われます。

のであとはやるだけで普通に既存ツールの土俵で戦えるようになるはず。GradleやIDEAへの組み込みは元々スコープ外ですが、必要なら誰かがやるでしょう。

あと大切そうなのは、いかにdog foodingする場を作ってfalse positiveやfalse negativeについてフィードバックを受けるかという点でしょうか。こればかりはやってみないとわからないですね。ルールセットを増やしてcoding agentを積極的に採用しているOSSを見つけて売り込みに行く必要があるでしょう。

このプロダクトを育てるべきかはちょっとまだ見えてないんですが、継続の意義はあると思うので、しばらく隙間時間に育てていきたいと思います。