1

Мне удалось сгенерировать динамически генерируемые байт-коды в файл с использованием ASM, но не загружать его. Сообщение об ошибке:Не удалось загрузить динамически генерируемые байт-коды

java.lang.ClassFormatError: JVMCFRE102 field signature invalid; class=TGWD, offset=0 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:364) 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:284) 
    at java.lang.invoke.ByteCodeClassLoader.run(ByteCodeClassLoader.java:20) 

BytecodeClassLoader это класс я писал здесь. Результат javap -v также показан ниже.

Classfile /C:/temp/TGWD.class 
    Last modified Mar 10, 2015; size 750 bytes 
    MD5 checksum 462ec39a439ab0d30c676eb92a93fd5a 
public class TGWD extends java.lang.invoke.BaseTemplate 
    minor version: 0 
    major version: 51 
    flags: ACC_PUBLIC, ACC_SUPER 

Constant pool: 
    #1 = Utf8    TGWD 
    #2 = Class    #1    // TGWD 
    #3 = Utf8    java/lang/invoke/BaseTemplate 
    #4 = Class    #3    // java/lang/invoke/BaseTemplate 
    #5 = Utf8    guard 
    #6 = Utf8    Ljava/lang/invoke/MethodHandle; 
    #7 = Utf8    trueTarget 
    #8 = Utf8    falseTarget 
    #9 = Utf8    <init> 
    #10 = Utf8    (Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)V 
    #11 = Utf8    java.lang.invoke.MethodHandle 
    #12 = NameAndType  #5:#11   // guard:java.lang.invoke.MethodHandle 
    #13 = Fieldref   #2.#12   // TGWD.guard:java.lang.invoke.MethodHandle 
    #14 = NameAndType  #7:#11   // trueTarget:java.lang.invoke.MethodHandle 
    #15 = Fieldref   #2.#14   // TGWD.trueTarget:java.lang.invoke.MethodHandle 
    #16 = NameAndType  #8:#11   // falseTarget:java.lang.invoke.MethodHandle 
    #17 = Fieldref   #2.#16   // TGWD.falseTarget:java.lang.invoke.MethodHandle 
    #18 = Utf8    eval 
    #19 = Utf8    ()V 
    #20 = Utf8    Hello 
    #21 = Utf8    (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; 
    #22 = Utf8    java/lang/Throwable 
    #23 = Class    #22   // java/lang/Throwable 
    #24 = NameAndType  #5:#6   // guard:Ljava/lang/invoke/MethodHandle; 
    #25 = Fieldref   #2.#24   // TGWD.guard:Ljava/lang/invoke/MethodHandle; 
    #26 = Utf8    java/lang/invoke/MethodHandle 
    #27 = Class    #26   // java/lang/invoke/MethodHandle 
    #28 = Utf8    invokeExact 
    #29 = Utf8    (Ljava/lang/String;)Z 
    #30 = NameAndType  #28:#29  // invokeExact:(Ljava/lang/String;)Z 
    #31 = Methodref   #27.#30  // java/lang/invoke/MethodHandle.invokeExact:(Ljava/lang/String;)Z 
    #32 = NameAndType  #7:#6   // trueTarget:Ljava/lang/invoke/MethodHandle; 
    #33 = Fieldref   #2.#32   // TGWD.trueTarget:Ljava/lang/invoke/MethodHandle; 
    #34 = NameAndType  #28:#21  // invokeExact:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; 
    #35 = Methodref   #27.#34  // java/lang/invoke/MethodHandle.invokeExact:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; 
    #36 = NameAndType  #8:#6   // falseTarget:Ljava/lang/invoke/MethodHandle; 
    #37 = Fieldref   #2.#36   // TGWD.falseTarget:Ljava/lang/invoke/MethodHandle; 
    #38 = Utf8    Code 
    #39 = Utf8    StackMapTable 
    #40 = Utf8    Exceptions 
{ 
    final java.lang.invoke.MethodHandle guard; 
    flags: ACC_FINAL 


    final java.lang.invoke.MethodHandle trueTarget; 
    flags: ACC_FINAL 


    final java.lang.invoke.MethodHandle falseTarget; 
    flags: ACC_FINAL 


    public TGWD(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle); 
    flags: ACC_PUBLIC, ACC_VARARGS 

    Code: 
     stack=0, locals=4, args_size=4 
     0: aload_0  
     1: aload_1  
     2: bipush  0 
     4: aaload   
     5: putfield  #13     // Field guard:java.lang.invoke.MethodHandle 
     8: aload_0  
     9: aload_1  
     10: bipush  1 
     12: aaload   
     13: putfield  #15     // Field trueTarget:java.lang.invoke.MethodHandle 
     16: aload_0  
     17: aload_1  
     18: bipush  2 
     20: aaload   
     21: putfield  #17     // Field falseTarget:java.lang.invoke.MethodHandle 
     24: return   

    public void eval(); 
    flags: ACC_PUBLIC 

    Code: 
     stack=0, locals=1, args_size=1 
     0: return   

    public java.lang.String Hello(java.lang.String, java.lang.String) throws java.lang.Throwable; 
    flags: ACC_PUBLIC 

    Code: 
     stack=0, locals=3, args_size=3 
     0: aload_0  
     1: getfield  #25     // Field guard:Ljava/lang/invoke/MethodHandle; 
     4: aload_1  
     5: invokevirtual #31     // Method java/lang/invoke/MethodHandle.invokeExact:(Ljava/lang/String;)Z 
     8: ifeq   21 
     11: aload_0  
     12: getfield  #33     // Field trueTarget:Ljava/lang/invoke/MethodHandle; 
     15: aload_1  
     16: aload_2  
     17: invokevirtual #35     // Method java/lang/invoke/MethodHandle.invokeExact:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; 
     20: areturn  
     21: aload_0  
     22: getfield  #37     // Field falseTarget:Ljava/lang/invoke/MethodHandle; 
     25: aload_1  
     26: aload_2  
     27: invokevirtual #35     // Method java/lang/invoke/MethodHandle.invokeExact:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; 
     30: areturn  
     StackMapTable: number_of_entries = 1 
      frame_type = 21 /* same */ 

    Exceptions: 
     throws java.lang.Throwable 
} 

Может у кого-нибудь есть идея, где ошибка в генерируемых байт-кодах? Благодарю. Я также прилагается файл класса здесь Class File ..

Ниже представлена ​​информация может быть полезной: 1, Согласно стеком, я думаю, проблема в трех членов на местах. Я использую ниже код для создания этих полей:

FieldVisitor fv; 
fv = cw.visitField(ACC_FINAL, 'guard', "Ljava/lang/..", null, null); 
fv.visitEnd(); 

меняет ACC_FINAL к ACC_PRIVATE. Результат тот же, если ни один из трех элементов поля не показан в javap -v.

2, Базовый класс BaseTemplate является пустой абстрактный класс определяется как:

public abstract class BaseTemplate { } 

========================= ===== Update:

После изменения инструкции putfield в моем исходном коде от

mv.visitFieldInsn(PUTFIELD, className, list.get(i).name(), list.get(i).type());

в

mv.visitFieldInsn(PUTFIELD, className, list.get(i).name(),Utils.getFieldDesc(list.get(i).type()));, теперь загрузка класса становится успешной. Причина в том, что набор сигнатур поля wronlg (как в ответах @Holger).

+0

Обратите внимание на теги, которые вы используете. '** ** ПРИМЕЧАНИЕ **: Для Java ASM вместо этого используйте тег [java-asm].' ' –

+0

Связанный файл класса не совпадает с указанным выше, сумма MD5 не соответствует. '-private' опции' javap' ... – Holger

ответ

1

Вы создали свой конструктор, используя "java.lang.invoke.MethodHandle" как полевую, а не правильную "Ljava/lang/invoke/MethodHandle;". Это можно увидеть в javap выходе линиями:

 5: putfield  #13    // Field guard:java.lang.invoke.MethodHandle 
… 
    13: putfield  #15    // Field trueTarget:java.lang.invoke.MethodHandle 
… 
    21: putfield  #17    // Field falseTarget:java.lang.invoke.MethodHandle 

тогда как метод Hello правильно использует:

 1: getfield  #25    // Field guard:Ljava/lang/invoke/MethodHandle; 
… 
    12: getfield  #33    // Field trueTarget:Ljava/lang/invoke/MethodHandle; 
… 
    22: getfield  #37    // Field falseTarget:Ljava/lang/invoke/MethodHandle; 

Это также объясняет довольно большой постоянный бассейн. Элемент № 11 содержит неправильную подпись java.lang.invoke.MethodHandle, которая затем используется элементами последующих действий № 12 - # 17, которые используются конструктором. Они отличаются от пунктов № 25, № 33 и № 37, используемых в методе Hello. В правильно сгенерированном классе эти инструкции разделяют одни и те же элементы в пуле констант (все они косвенно ссылаются на правильную подпись Ljava/lang/invoke/MethodHandle;, которая хранится в элементе # 6 в этом файле класса.

+0

Спасибо. Это исправляет мою проблему как то, что я обновил в первом сообщении. Следующая проблема заключается в том, что размер стека ошибочно вычисляется в сгенерированном байт-коде (он должен быть 2 для конструктора вместо 0). Упрощенную дополнительную информацию можно найти по адресу http://stackoverflow.com/questions/28988694/wrong-stack-size-calculated-by-asm-library –

 Смежные вопросы

  • Нет связанных вопросов^_^