java.lang.ClassCastException: Z cannot be cast to java.lang.String
Asked Answered
C

3

5

I'm getting an error: java.lang.ClassCastException: Z cannot be cast to java.lang.String while trying to run coverage (EclEmma) on a Junit test. If I run the test regularly (without coverage) then it passes.

This is the code (all the fields in the class are Strings):

@Override
public Map<String, String> getErrors() throws IllegalAccessException, IllegalArgumentException {

    Map<String, String> errors = new HashMap<String, String>();

    for (Field field : this.getClass().getDeclaredFields()) {
        field.setAccessible(true);
        String value = (String) field.get(this);

        if (value.equals("N")) {
            if (!errors.containsKey(field.getName())) {
                errors.put(field.getName(), value);
            }
        }
    }
    return errors;
}
Candlenut answered 18/8, 2016 at 7:31 Comment(1)
Is the code obfuscated?Bastion
B
8

The problem is that to produce the code coverage EclEmma adds a field private static final transient boolean[] $jacocoData to your class.

Since this field is only present during code coverage runs, the normal unit test passes, but the code coverage run fails: your original code is not expecting this non-String field.

The best solution is to check if the field you are seeing is really a String field and otherwise skipping the test of the field value:

for (Field field : this.getClass().getDeclaredFields()) {
    field.setAccessible(true);
    if (field.getType() != String.class) {
        continue;
    }
    String value = (String) field.get(this);

    if (value.equals("N")) {
        if (!errors.containsKey(field.getName())) {
            errors.put(field.getName(), value);
        }
    }
}
Braces answered 19/8, 2016 at 11:7 Comment(0)
P
0

Try to do this:

String value = "null";
if(field.get(this) != null)
    value = field.get(this).toString();

Instead of this:

String value = (String) field.get(this);
Paredes answered 18/8, 2016 at 7:41 Comment(8)
Note that this might fail if field.get(this) is null. Better to use Objects.toString(field.get(this)).Keewatin
@AndyTurner how can it be, that you're always there and correct and still less than 30k repu? :)Disagree
@Disagree 30k rep requires 150 days at daily maximum to reach. If I actually tried to reach that, I doubt I'd still have a job :)Keewatin
@Disagree yes, I do. No, they don't.Keewatin
Thanks @NathaëlNoguès. It worked. Do you have an idea why it worked when I ran a unit test but didn't work when I ran the coverage?Candlenut
@Co.zohar I have realy no idea of why it worked in unit tests haha ! I very don't understand what realy was your problem, I just tried to correct a Java common mistake (to cast to String instead of using toString method)Paredes
This isn't a real fix. The real problem is that the OP is expecting all of his/her fields to be strings.Debrahdebrecen
@OliverCharlesworth Thanks. I added a check if field value is instance of String.Candlenut
C
0

Finally, I checked that the field value is instance of String and replaced casting to String with the function toString().

String value = null;
Object fieldValue = field.get(this);
if (fieldValue instanceof String) {
    value = fieldValue.toString();
}

if ("N".equals(value)) {
    if (!errors.containsKey(field.getName())) {
        errors.put(field.getName(), value);
    }
}
Candlenut answered 18/8, 2016 at 8:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.