スタックトレースろふ #irof

これは いろふ Advent Calendar 2014 の1日目です。

いろふアドベントカレンダーとは、我らが いろふさん への愛をワールドワイドなインターネッツに大公開する感じのやつです。

いろふさんをご存じない方はTwitterでヒョローをキメて、著書である養成読本を熟読すると良いですよ!

本編という名の出オチ

こちらのリポジトリをcloneして、

irofディレクトリに移動し gradlew run してください。

するとこうなります。

../../../_images/stacktracerof.png

なんといろふさんが例外吐いて終了しました! (-∧-;) ナムー

投げっぱなしの解説

Java言語ではメソッド名に空白や記号を使えませんがクラスファイルとJVM的にはもうちょい制約緩いっぽいので その辺を利用してスタックトレースでいろふさんを描きました。

いろふさんのアイコンからAAを作ったのは次のサービスです。

で、クラスファイルを書き出したのはASMというライブラリです。

ASMの ClassWriterGeneratorAdapter を使えば割と簡単にクラスファイルを書き出す事ができます。 詳しくはGeneratorAdapterのJavadocと今回のいろふソースコードを参照ください。

それと今回は使っていませんが ClassReader を使うとクラスファイルを読む事ができます。

例えばインスタンスメソッドを実行してるコードを見つけて標準出力に書き出すようなアレは次のように書けます。

ClassReader reader = new ClassReader("irof.Irof");

MethodVisitor methodVisitor = new MethodVisitor(Opcodes.ASM5) {

    @Override
    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
        if (opcode == Opcodes.INVOKEVIRTUAL) {
            System.out.printf("owner=%1$s name=%2$s desc=%3$s%n", owner, name, desc);
        }
    }
};

ClassVisitor classVisitor = new ClassVisitor(Opcodes.ASM5) {

    @Override
    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
        return methodVisitor;
    }
};

reader.accept(classVisitor, 0);

ちなみにASMはJDKにも入っています。 rt.jarcom.sun.xml.internal.ws.org.objectweb.asm 以下がそうですね。 JAX-WSに使われているようです。

あと jersey-server にも使われています。 jersey.repackaged.org.objectweb.asm 以下がそうです。

まとめ

いざやってみるとすんなり出来ちゃって変態度が低すぎてアレですが、まあいいか。