Javapでエラーが起きる場所をよく見てみた
Eclipseからsun.tools.javap.Mainを叩いてみた。
まずは、問題が起きる箇所のスタックトレース。
java.io.EOFException at java.io.DataInputStream.readUnsignedByte(DataInputStream.java:273) at sun.tools.javap.StackMapData.readType(StackMapData.java:46) at sun.tools.javap.StackMapData.readTypeArray(StackMapData.java:40) at sun.tools.javap.StackMapData.<init>(StackMapData.java:32) at sun.tools.javap.MethodData.readStackMap(MethodData.java:213) at sun.tools.javap.MethodData.readCode(MethodData.java:131) at sun.tools.javap.MethodData.read(MethodData.java:59) at sun.tools.javap.ClassData.readMethods(ClassData.java:206) at sun.tools.javap.ClassData.read(ClassData.java:99) at sun.tools.javap.ClassData.<init>(ClassData.java:52) at sun.tools.javap.JavapPrinter.<init>(JavapPrinter.java:30) at sun.tools.javap.Main.displayResults(Main.java:201) at sun.tools.javap.Main.perform(Main.java:61) at sun.tools.javap.Main.entry(Main.java:49) at sun.tools.javap.Main.main(Main.java:34) ERROR:fatal exception
readUnsignedByteで、EOFを含むバイトを読もうとしてコケてるみたい。
その辺りのソースを見てみると、、、
StackMapData(DataInputStream in, MethodData method) throws IOException { offset = in.readUnsignedShort(); int local_size = in.readUnsignedShort(); locals = readTypeArray(in, local_size, method); int stack_size = in.readUnsignedShort(); stack = readTypeArray(in, stack_size, method); } static final int[] readTypeArray(DataInputStream in, int length, MethodData method) throws IOException { int[] types = new int[length]; for (int i=0; i<length; i++) { types[i] = readType(in, method); } return types; } static final int readType(DataInputStream in, MethodData method) throws IOException { int type = in.readUnsignedByte(); if (type == ITEM_Object || type == ITEM_NewObject) { type = type | (in.readUnsignedShort()<<8); } return type; }
なるほど、
要は「int local_size = in.readUnsignedShort();」をやってる箇所で
正しい値が取れなくて、過剰にfor文を回しているだけのようですね。
classのバイナリ構造に関してはよく知らないので推測だけど、
恐らく、ASMでclassをいじる際に、
local_sizeに相当する箇所のサイズを書き換えず、
クラスの内容だけ書き換えちゃってるから、
整合性が取れずにjavapでコケちゃってるんだと思う。
当面、javapができなくて困ってるわけじゃないので、
このぐらいで止めとこう。