0

Some exception occurs when I try to inline two classes:

public class CI_Caller1 {
    private int _data;
    private CI_Callee_2 _callee;

    public CI_Caller1(int data, CI_Callee_2 callee){
        _data = data;
        _callee = callee;
    }
}

public class CI_Callee_2 {

    private Integer _a1;
    private String _t;

    public CI_Callee_2(Integer a1, String t){
        _a1 = a1;
        _t = t;
    }
}

The inling operation is to inline two fields, _a and _t in CI_Callee_2, as a member of CI_Caller1. The new member would be:

private int _data;
private Integer _callee__a1;
private String _callee__t;

Everything seems correct, but when i try to load the generated byte[], exception is thrown as:

java.lang.ClassFormatError: Field "_callee__a1" in class <Unknown> has illegal signature "_callee"
    at sun.misc.Unsafe.defineAnonymousClass(Native Method)
    at code.jit.asm.services.ACLoader.loadClass(ACLoader.java:27)

The way to vistiField is like:

    _fieldNode = reference2CI_Callee_2FieldNode();
    //cw is class visitor to the CI_Caller1
    cw.visitField(_fieldNode.access, calculateName(fieldHoster, _fieldNode.name), 
            _fieldNode.desc, _fieldNode.signature, _fieldNode.value);

The _fieldNode here references to a CI_Callee_2's field, and its original members (and its values):

desc: Ljava/lang/Integer;
name: _a1     //calculateName will map _a1 to _callee_a1
signature: null
value: null

I did not make any change on the _fieldNode once it is initilized with ClassNode of CI_Callee_2. (The signature value of _fieldNode keeps NULL all the time)

Is there anyone seen this exception? Thanks.

shijie xu
  • 1,975
  • 21
  • 52

1 Answers1

0

The field you created with the name "_callee__a1" has the signature _callee. The character _ is not a valid start of a field signature. You say you want the type to be Integer, so the field signature should be Ljava/lang/Integer;. (The L indicates that this is a reference type)

Erwin Bolwidt
  • 30,799
  • 15
  • 56
  • 79
  • Still confused. 1) I can not understand why there is signature ``_callee`` in the generated code, because ``_fieldNode.signature`` for visitField is NULL and it is initialized with classNode of CI_Callee2(never change). 2) What's the difference between ``signature`` and ``desc``? The "Ljava/lang/Integer;" is description and it has already been passed to cw.visitField as ``desc`` correctly. – shijie xu Jul 05 '15 at 13:11
  • I have fixed it. The problem is in another place where I passed wrong string '_callee' as desc for putField instruction. – shijie xu Jul 05 '15 at 23:31
  • @shijie xu: the ASM API uses names which are a bit misleading. `desc` is what is called *signature* elsewhere while `signature` is the *generic signature* which may be `null`. – Holger Jul 06 '15 at 18:40
  • ASM uses the terms "descriptor" (shortened "desc") and "signature" in the same way as the JVM specification: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3 – Brett Kail Jul 09 '15 at 16:01