Я использую ASM (также дерево и утилиту) и столкнулся со странным исключением.
Exception in thread "main" java.lang.ClassFormatError: Invalid length 65526 in LocalVariableTable in class file
Я пытаюсь отредактировать байт-код файла .class, чтобы создать новый. У меня есть цикл for с некоторыми ветвями if внутри, и я пытаюсь его изменить. Я публикую ниже код двух циклов for, начального и желаемого сгенерированного.
Исходный
int[] ar = new int[]{1,2,3,4,5};
int[] ar2 = new int[]{8,9,9,94,3,2};
MyClass myar = new MyClass(ar);
MyClass myar2 = new MyClass(ar2);
int sum=0;
for(int i=0; i<ar.length; i++)
if(ar[i]>3) {
if(ar2[i]>8) {
sum+=(ar[i]+ar2[i]);
}
}
}
Желаемый
int[] ar = new int[]{1,2,3,4,5};
int[] ar2 = new int[]{8,9,9,94,3,2};
MyClass myar = new MyClass(ar);
MyClass myar2 = new MyClass(ar2);
int sum=0;
for(int i=0; i<ar.length; i++)
int[] temp = callAFunctionToDoSthing(myar, myar2);
if(temp[0]>3) {
if(temp[1]>8) {
sum+=(temp[0]+temp[1]);
}else i+=1;
}else i+=2;
}
Чтобы сделать это, я использую ListIterator дерева ASM, чтобы обнаружить цикл for (я делаю это, проверяя, выполняются ли некоторые команды одна за другой). Я использую расширение байт-кода ASM для intellj, чтобы сравнить исходный и желаемый байт-код. Затем, используя ASM-дерево, я удаляю и добавляю в список байт-кодов нужные мне инструкции. (Я пробовал и ASM5, и ASM8). Проблема в том, что после этой операции, когда я запускаю сгенерированный файл .class, я получаю исключение выше. Дело в том, что я не редактирую LocalVariableTable вручную и не знаю, как ее редактировать. Если я запускаю команду javap -v в нужном коде, я даже не вижу LocalVariableTable, тогда как если я запускаю javap -v в сгенерированном файле .class, я его вижу.
Я попробовал другую модификацию, чтобы убедиться, что моя идея с ASM-деревом работает в более простом цикле for без if и уникального массива, и там все работает нормально.
Кроме того, я пытался использовать SKIP_DEBUG, но не вижу Label и LineNumber -Nodes, и в моем случае мне нужно удалить некоторые инструкции LabelNode и LineNumberNode.
ИЗМЕНИТЬ:
Я даю простой пример того, как я делаю преобразование. Я использую средство проверки различий исходного и желаемого байт-кода ASM, и оно выдает что-то вроде изображения ниже < img src="https://i.stack.imgur.com/LJeFW.png" alt="Проверка различий исходного и желаемого байт-кода"> Таким образом, код для управления этим
IntInsnNode bp7 = (IntInsnNode) aload17.getNext();
instructions.remove(bp7.getNext());
instructions.remove(bp7.getNext());
instructions.remove(bp7.getNext());
instructions.remove(bp7.getNext());
instructions.remove(bp7.getNext());
InsnList l4 = new InsnList();
LabelNode l45Ins = new LabelNode();
l4.add(new JumpInsnNode(Opcodes.IF_ICMPGT, l45Ins));
LabelNode l46Ins = new LabelNode();
l4.add(l46Ins);
l4.add(new LineNumberNode(178, l46Ins));
l4.add(new VarInsnNode(Opcodes.ALOAD, 20));
l4.add(new InsnNode(Opcodes.ICONST_0));
instructions.insert(bp7, l4);
javap
? Krakatau должен дать вам более точную картину того, что на самом деле находится в вашем файле класса. github.com/Storyyeller/Krakatau - person Antimony   schedule 10.06.2020callAFunctionToDoSthing
, нет перенаправления доступаar
/ar2
кtemp
, а расположение кода для меткиl45Ins
не определено. Кроме того, вы не показали, как вы анализируете исходный класс и генерируете новый класс. - person Holger   schedule 10.06.2020java.lang.IllegalArgumentException: Invalid end label (must be visited first)
. Кто-нибудь знает, что означает конечная метка, которую нужно посетить в первую очередь? - person Fotis koun   schedule 17.06.2020visitLabel(label)
наMethodVisitor
. Это будет коррелировать сLabelNode
. Конечная метка — это метка, указывающая конец области видимости переменной. - person JojOatXGME   schedule 22.06.2020Label
должен быть частью списка инструкций с использованиемLabelNode
. Если вы удалите некоторыеLabelNode
, вам придется поместить метки обратно в список инструкций или изменить все места, которые используют метку. Я не могу сказать намного больше. В вашем вопросе недостаточно информации для воспроизведения проблемы. В любом случае, возможно, у вас уже достаточно информации, чтобы решить проблему самостоятельно. - person JojOatXGME   schedule 24.06.2020