Java.lang.VerifyError - If there is a class with a static variable containing a reference to the class instance

public class Config {
    public static Ref<Config> s = new Ref<Config>(new Config());
    static class Ref<T> {
        public T r;
        public Ref(T r) {
            this.r = r;
        }
    }
    public int INTERVAL = 4000;

    public Config()
    {
    }

    public static void main(String[] args) {
        System.err.println(Config.s.r.INTERVAL);
    }
}

Running this reason in java.lang.VerifyError

Exception in thread "main" java.lang.VerifyError: (class: Config, method: main signature: ([Ljava/lang/String;)V) Incompatible type for getting or setting field

If I run this:

System.err.println(Config.s.r);

Than no exception is thrown, and in debugging I can see the value "Config.srINTERVAL"

When I run with -verbose: class, I see that the Ref class is not loaded in the first example. In the second example, the class Ref is loaded.

This is the only project class compiled and launched using java6. The problem is not with jvm or a third party.

I assume the problem is combined in the same initialization of a static string variable and an instance variable.

works as follows - work:

Config c = Config.s.r;
System.err.println(c.INTERVAL);

Ps. The code is very complex and it is divided into 2 classes in dev env. I just limit it to a short example

Jdk - Java SE 6 [1.6.0_65-b14-462] OS - Mac

+4
2

, . , :

Config c = Config.s.r;
System.err.println(c.INTERVAL);

( ): , 2 :

public static void main(java.lang.String[]);
  Code:
   0:   getstatic   #22; //Field s:LRef;
   3:   getfield    #33; //Field Ref.r:Ljava/lang/Object;
   6:   checkcast   #1; //class Config
   9:   astore_1
   10:  getstatic   #37; //Field java/lang/System.err:Ljava/io/PrintStream;
   13:  aload_1
   14:  getfield    #27; //Field INTERVAL:I
   17:  invokevirtual   #43; //Method java/io/PrintStream.println:(I)V
   20:  return

}

- :

public static void main(java.lang.String[]);
  Code:
   0:   getstatic   #33; //Field java/lang/System.err:Ljava/io/PrintStream;
   3:   getstatic   #22; //Field s:LRef;
   6:   getfield    #39; //Field Ref.r:Ljava/lang/Object;
   9:   getfield    #27; //Field INTERVAL:I
   12:  checkcast   #1; //class Config
   15:  invokevirtual   #43; //Method java/io/PrintStream.println:(I)V
   18:  return

}

@Hot , , (int), . Oracle.

+1

:

public static void main(java.lang.String[]);
  Code:
   // Fetch static field s -- place is stack location 1
   0:   getstatic   #22; //Field s:LRef;
   // Fetch instance field r using stack 1 as base -- place in stack location 1
   3:   getfield    #33; //Field Ref.r:Ljava/lang/Object;
   // Peform checkcast on stack location 1 to assure it a "Config" -- leave stack unchanged
   6:   checkcast   #1; //class Config
   // Store stack location 1 into local variable 1.  Pop stack.
   9:   astore_1
   // Fetch static field System.err -- place in stack location 1
   10:  getstatic   #37; //Field java/lang/System.err:Ljava/io/PrintStream;
   // Fetch local variable 1 -- place in stack location 2
   13:  aload_1
   // Fetch instance field I using stack 2 as base -- place in stack location 2 
   14:  getfield    #27; //Field INTERVAL:I
   // Invoke println, using stack 1 as base, stack 2 as parm -- stack becomes empty
   17:  invokevirtual   #43; //Method java/io/PrintStream.println:(I)V
   20:  return

}

:

public static void main(java.lang.String[]);
  Code:
   // Fetch static field System.err -- place is stack location 1
   0:   getstatic   #33; //Field java/lang/System.err:Ljava/io/PrintStream;
   // Fetch static field s -- place in stack location 2
   3:   getstatic   #22; //Field s:LRef;
   // Fetch instance field r using location 2 as base -- place in stack location 2
   6:   getfield    #39; //Field Ref.r:Ljava/lang/Object;
   // --- Note that the checkcast should be here ---
   // Fetch instance field I using location 2 as base -- place in stack location 2
   9:   getfield    #27; //Field INTERVAL:I
   // Perform checkcast on location 2, to assure it a "Config" (it isn't)
   12:  checkcast   #1; //class Config
   // Invoke println using location 1 as base, location 2 as parm.
   15:  invokevirtual   #43; //Method java/io/PrintStream.println:(I)V
   18:  return

}
0

Source: https://habr.com/ru/post/1523915/


All Articles