読者です 読者をやめる 読者になる 読者になる

この日記は私的なものであり所属会社の見解とは無関係です。 GitHub: takahashikzn

全ての例外発生をフックする最短手段

Java

ちょっと自分用メモ。


デバッガ上でアプリを動作させられないような状況下において、
例外の発生をフックしたいことがある。(エラー原因の解析処理をフックしたいなど→例えばログを出すとか)


で、技術的にどうすればコレが可能か?を考えたのだが
まず思いついたのが、自プロジェクトのすべてのクラスを対象に
AspectJあたりを使って、全てのメソッドにアスペクトを適用する』というやり方。
要するに、『全てのメソッドのメソッドボディをtry-catchで囲ってしまい、catch節で実行したい処理を行う』わけ。


…なんだけど、コレはあまりに過激すぎるので実際にはムリだろう。

そこで考えたのが

JDKにパッチをあてる方法。パッチと言ってもrt.jarをいじるわけではなく、
自分のクラスパス上にjava.lang.Throwableを配置して、そっちを優先させてしまうというシンプルな方法。


例えば、このようなソースを、${PRJ_ROOT}/src/java/lang/Throwable.javaとして配置すればいい。
JDKjava.lang.Throwableのソースをまんまコピーして書き換えただけ。

package java.lang;
import  java.io.*;

public class Throwable implements Serializable {

    private static final Log LOG = ...;

    // ...略

    public Throwable() {
        LOG.debug(...); //デバッグ用のログ
        fillInStackTrace();
    }

    // ...略
}


あとは、この書き換えたクラスを"-Xbootclasspath/p:path"を使ってrt.jarより先に読ませればいい。
Eclipseで設定するならこんな感じ。



ただし、この小細工を適用したまま商用環境に乗せてしまうとライセンス違反な気がするので、
あくまでも開発中だけの暫定対応ということに注意。

2013/12/8追記

ライセンス違反かどうかかなり微妙です。(bootclasspath/pだから大丈夫という意味にも読めるが)
この手順を実行する際は自己責任で。

http://otndnld.oracle.co.jp/document/products/jrockit/jrdocs/refman/optionX.html#wp999509