Just tried JDK17 on Eclipse 2021-09 to have it fail with a java.lang.VerifyError
, which wasn't very helpful itself. I tracked it down to a switch statement, that gets fed a value pulled out of a Map
or another generic type. If I use a local variable in the switch statement instead, everything works as intended.
Test code:
import java.util.HashMap;
import java.util.Map;
public class SwitchFail {
public static void main(String[] args) {
//doesnt work
Map<Integer, String> stringMap = new HashMap<>();
stringMap.put(1, "Test");
switch(stringMap.get(1)) {
}
//works
String plainString = "Test";
switch(plainString) {
}
}
}
This throws the following error:
Error: Unable to initialize main class SwitchFail
Caused by: java.lang.VerifyError: Bad type on operand stack
Exception Details:
Location:
SwitchFail.main([Ljava/lang/String;)V @33: invokevirtual
Reason:
Type 'java/lang/Object' (current frame, stack[0]) is not assignable to 'java/lang/String'
Current Frame:
bci: @33
flags: { }
locals: { '[Ljava/lang/String;', 'java/util/HashMap', 'java/lang/Object' }
stack: { 'java/lang/Object' }
Bytecode:
0000000: bb00 1059 b700 124c 2b04 b800 1312 19b9
0000010: 001b 0300 572b 04b8 0013 b900 2102 0059
0000020: 4db6 0025 57b1
Didn't try another JDK between 11 and 17 yet. Switches gained some new functions between those versions, so that might be it. Maybe it's a problem in the Eclipse JDT or my local JDK, so any tries to reproduce this error on another configuration or IDE would be great. Tried on OpenJDK (build 17+35-2724) for macOS.
Edit: Also happens on
List<String> stringList = Arrays.asList("Test");
switch(stringList.get(0)) {}
Most likely an issue with the new JDT for Java 17 or my local installation.
get
with a map of a generic type because it doesn't look into the switch body to realize that the narrowed type is required. – AilsaList<String> stringList = Arrays.asList("Test"); switch(stringList.get(0)) {}
. It's probably rooted in the JDT or my local installation. – Lorenelorens