MOD作成の際にasmに触れる機会に遭遇したので少し覚書きを。
あ、Javaです。
asmの公式ページはこちら→http://asm.ow2.org/
javadocはこちら→http://asm.ow2.org/asm33/javadoc/user/index.html
私が今この記事を書いているときはasmのjavadocは3.3ですが、実際に使用しているバージョンは4.0です。なんででしょ。
今のasmに対する私の印象は「実行時にクラスが読み込まれた時点にそのクラスに改変を施すためのライブラリ」です。長いと印象つきにくいですね。
私自身まだ全然わかっていないのでご了承ください。
今回は簡単な構造についてだけ書きます。
私がやっていた環境ではbyte配列が与えられていました。
そのbyte配列に改変を施すことで実行時のクラスに改変を加え、実際に実行している模様。
まず必要(なのかな?)なの
- ClassNode
- ClassReader
- ClassWriter
流れとしては
ClassReaderにbyte配列いれる
↓
ClassNodeにClassReaderで解析したのをいれてもらう(?)
↓
ClassNodeをいじって改変を加える
↓
ClassWriterにClassNodeいれてbyte配列にもどしてそれをかえす
あってるかわからないですが、現状の私の捉え方はこんな感じです。
それをソースであらわすと
public byte[] transform(byte[] arrayOfByte) { ClassNode classNode = new ClassNode(); // byte配列いれる ClassReader classReader = new ClassReader(arrayOfByte); // ClassReaderからClassNodeにいれてもらう、0は何かはおいといて classReader.accept(classNode, 0); // // ClassNodeにいろいろして改変を加える // // COMPUTE_FRAMESとCOMPUTE_MAXSはClassWriterのstatisなフィールド // 適宜、参照やstatic importを ClassWriter classWriter = new ClassWriter(COMPUTE_FRAMES | COMPUTE_MAXS); // ClassNodeからClassWriterにいれてもらう classNode.accept(classWriter); return classWriter.toByteArray(); }
こんな感じになります。
ClassReader(攻め)×ClassNode(受け)と、
ClassNode(攻め)×ClassWriter(受け)ですね。
わかりやすいですね!ね!
このとき、改変に失敗したりするとjava.lang.VerifyErrorでたりします。
今ちょうどそれに苦しめられてます。しにそうです。
今回はこんな感じで。
[覚えておくこと]
- ClassReaderは攻め
- ClassNodeは受けと攻めの両方
- ClassWriterは受け
・・・さて、英文のソースやjavadoc読んで理解深めましょうねー・・・