-
Notifications
You must be signed in to change notification settings - Fork 2
Coding errors
It's possible to make classes which the virtual machine rejects, resulting in a LinkageError
of some kind:
-
BootstrapMethodError
— caused by an indy/condy bootstrap method which fails to produce a valid result -
ExceptionInInitializerError
— caused by an exception throwing out from a static initializer -
IncompatibleClassChangeError
— caused by failing to implement an abstract method, or by trying to access an inaccessible class member -
VerifyError
— the code in a method body is broken
With the MethodMaker
it's almost impossible to define code which can throw a VerifyError
. The notable exception is when attempting to access a variable which hasn't been assigned yet:
ClassMaker cm = ClassMaker.begin();
MethodMaker mm = cm.addMethod(int.class, "test").public_().static_();
var v1 = mm.var(int.class);
mm.return_(v1); // v1 hasn't been assigned yet!
var clazz = cm.finish();
clazz.getMethod("test").invoke(null);
When running the above example:
Exception in thread "main" java.lang.VerifyError: Bad local variable type
Exception Details:
Location:
org/cojen/maker/ClassMaker-8.test()I @0: iload_0
Reason:
Type top (current frame, locals[0]) is not assignable to integer
Current Frame:
bci: @0
flags: { }
locals: { }
stack: { }
Bytecode:
0000000: 1aac
The VerifyError
tends to produce a ton of extra information, and this makes it look much scarier than it actually is. Try to find an execution path in the code which accesses a local variable that hasn't been definitely assigned.
Java compilers perform definite assignment analysis, and so a VerifyError
isn't possible unless the compiler is defective. Although Cojen could perform definite assignment analysis too, it's redundant and adds overhead when making classes at runtime. A front end compiler which uses Cojen should perform it's own definite assignment analysis or prevent assignment problems in the first place.