バイトコードインジェクションツール Byteman

試験の過程で特定処理が呼び出された時に何かログを出す必要性が出てきたんですが、試験のためだけにソース変更するのも美しくないから何か手がないかな〜と探していたところ、AOPのような仕組みをJavaだけで実現できるプロダクトがあるという情報を会社の先輩から教えていただきました。

JBossコミュニティのBytemanというツールです。
https://www.jboss.org/byteman

これはオープンソースJavaバイトコード操作ツールで、GNU LGPL 2.1でライセンスされている。Bytemanはコードのテスト、トレース、モニタリングを支援するJavaエージェントであり、開発者はこれを使って、ロード時や実行中にJavaアプリケーションの動作を変更することができる。これはアプリケーションの書き直しや再コンパイルをすることなく動作し、StringやThreadといったJavaプラットフォームクラスを修正することまで可能だ。

Byteman 2.0.0: バイトコード操作、テスティング、フォールトインジェクション、ロギング

Bytemanを使うとこんな風にスクリプトでランタイム上のバイトコードを自由に操作することができます。AOPを知っている人は、それをかなり自由に適用できるもの、と思ってもらえばわかりやすいかな。今回はデバッガとしてのユースケースを説明しましたが、デバッガとして使うにしてもソースコードを用意する必要がないという点と、ログベースのデバッグができるのでマニュアルインタラクティブGUIデバッガではできないマルチスレッド系や「たまにしか起きない」系の問題のデバッグもできるという面で通常のデバッガより優れてます。また、他にも実行統計機能を追加したり(例はsamplesにいっぱい入ってる)、モニタリングツールですという名目でByteman有効化しておいて、小さい単純なバグが発見されたときにBytemanでこっそり直したり、などとより黒いことも可能になります。

nekopの日記 BytemanによるJava黒魔術

9月26日のJJUG主催ナイトセミナー JJUG ナイトセミナー - torutkの日記 で、「イマドキの現場で使えるJavaライブラリ事情」の紹介にあったBytemanをJUnitから使い、モック的に利用する流れを簡単に記述しました。

[http://d.hatena.ne.jp/torutk/20121001/p1:title=torutkの日記 [Java]JBoss Bytemanを使ってAOP]

SpringやSesar2などのフレームワーク使った事がある方は馴染みがあるかと思いますが、Javaのクラス名やメソッドを指定してログ出力を差し込んだりする機能で使ってみるとかなり便利。何よりソースの中に本来のビジネスロジックではない部分を減らせるのでS/N比の向上になります。
ただ、上記のフレームワークたちは基本的にはWebアプリケーションのフレームワークのため、画面を持たないようなプロダクト(常駐プロセス系とか)ではあまり利用されていないんじゃないかと思います。実際、今回もそうでしたしね。

常駐プロセスの中で子スレッドを作成してひたすら処理をループさせるメソッドがあるので、Thread.run()された後に開始されるそのループ処理メソッド名を指定すれば、ロジックの一回転毎にログを吐ける、はず。