Updating to instanceof pattern results in coverage loss

I upgraded my code to replace this syntax:

if (exp instanceof A) {
    A a = (A) exp;
    ...
}

to the new one:

if (exp instanceof A a) {
    ...
}

This resulted in coverage loss and all if instanceof expressions went from green to yellow.

The issue does not appear with jacoco, which highlights all covered instanceof pattern expressions in green.

Example :

@nbauma109 how are you running coverage? This seems to be adding branch coverage which we were not getting beforehand?

I use jacoco and codecov upload GitHub action.
This instanceof pattern seems to be adding an imaginary branch.
The most obvious example is ElementValueWriter which had 100% coverage and with instanceof pattern, it started showing an additional uncovered branch for each instanceof.

@nbauma109 I haven’t been able to see why this is with Jacoco, but Codecov is getting the partial from your coverage files. Click Download on any coverage report, like here

<sourcefile name="ElementValueWriter.java"><line nr="42" mi="0" ci="12" mb="1" cb="3"/>

You’ll see that mb is 1 and cb is 3. That means there were 4 branches, and one of them is not covered. I don’t really know more than that. If I have to guess,

ev instanceof SimpleElementValue evpt

seems to have 2 branches. And then the if condition wrapping it multiples it by 2.

Here’s my locally generated jacoco report for ElementValueWriter:

				<class name="jd/core/process/writer/ElementValueWriter" sourcefilename="ElementValueWriter.java">
					<method name="writeElementValue" desc="(Lorg/jd/core/v1/api/loader/Loader;Ljd/core/printer/Printer;Ljd/core/model/reference/ReferenceMap;Ljd/core/model/classfile/ClassFile;Lorg/apache/bcel/classfile/ElementValue;)V" line="42">
						<counter type="INSTRUCTION" missed="0" covered="155"/>
						<counter type="BRANCH" missed="0" covered="14"/>
						<counter type="LINE" missed="0" covered="35"/>
						<counter type="COMPLEXITY" missed="0" covered="8"/>
						<counter type="METHOD" missed="0" covered="1"/>
					</method>
					<counter type="INSTRUCTION" missed="0" covered="155"/>
					<counter type="BRANCH" missed="0" covered="14"/>
					<counter type="LINE" missed="0" covered="35"/>
					<counter type="COMPLEXITY" missed="0" covered="8"/>
					<counter type="METHOD" missed="0" covered="1"/>
					<counter type="CLASS" missed="0" covered="1"/>
				</class>
				<sourcefile name="ElementValueWriter.java">
					<line nr="42" mi="0" ci="12" mb="0" cb="2"/>
					<line nr="43" mi="0" ci="1" mb="0" cb="0"/>
					<line nr="44" mi="0" ci="5" mb="0" cb="0"/>
					<line nr="47" mi="0" ci="12" mb="0" cb="2"/>
					<line nr="48" mi="0" ci="3" mb="0" cb="0"/>
					<line nr="49" mi="0" ci="2" mb="0" cb="0"/>
					<line nr="50" mi="0" ci="5" mb="0" cb="0"/>
					<line nr="51" mi="0" ci="3" mb="0" cb="0"/>
					<line nr="52" mi="0" ci="3" mb="0" cb="0"/>
					<line nr="55" mi="0" ci="12" mb="0" cb="2"/>
					<line nr="56" mi="0" ci="1" mb="0" cb="0"/>
					<line nr="57" mi="0" ci="3" mb="0" cb="0"/>
					<line nr="58" mi="0" ci="3" mb="0" cb="0"/>
					<line nr="61" mi="0" ci="12" mb="0" cb="2"/>
					<line nr="62" mi="0" ci="3" mb="0" cb="0"/>
					<line nr="63" mi="0" ci="3" mb="0" cb="0"/>
					<line nr="65" mi="0" ci="3" mb="0" cb="2"/>
					<line nr="67" mi="0" ci="1" mb="0" cb="0"/>
					<line nr="68" mi="0" ci="7" mb="0" cb="0"/>
					<line nr="69" mi="0" ci="8" mb="0" cb="2"/>
					<line nr="71" mi="0" ci="3" mb="0" cb="0"/>
					<line nr="72" mi="0" ci="1" mb="0" cb="0"/>
					<line nr="73" mi="0" ci="7" mb="0" cb="0"/>
					<line nr="76" mi="0" ci="3" mb="0" cb="0"/>
					<line nr="79" mi="0" ci="12" mb="0" cb="2"/>
					<line nr="80" mi="0" ci="3" mb="0" cb="0"/>
					<line nr="81" mi="0" ci="3" mb="0" cb="0"/>
					<line nr="82" mi="0" ci="3" mb="0" cb="0"/>
					<line nr="84" mi="0" ci="2" mb="0" cb="0"/>
					<line nr="85" mi="0" ci="5" mb="0" cb="0"/>
					<line nr="87" mi="0" ci="3" mb="0" cb="0"/>
					<line nr="88" mi="0" ci="2" mb="0" cb="0"/>
					<line nr="89" mi="0" ci="2" mb="0" cb="0"/>
					<line nr="90" mi="0" ci="3" mb="0" cb="0"/>
					<line nr="92" mi="0" ci="1" mb="0" cb="0"/>
					<counter type="INSTRUCTION" missed="0" covered="155"/>
					<counter type="BRANCH" missed="0" covered="14"/>
					<counter type="LINE" missed="0" covered="35"/>
					<counter type="COMPLEXITY" missed="0" covered="8"/>
					<counter type="METHOD" missed="0" covered="1"/>
					<counter type="CLASS" missed="0" covered="1"/>
				</sourcefile>

@nbauma109 how are you generating jacoco locally and on CI? Are you sure versions are the same too?

I use the same command locally and on CI:
mvn -V -B -Pecj test jacoco:report --no-transfer-progress

It takes version from pom.

@nbauma109 can you do a cat ./target/site/jacoco/jacoco.xml before you run the Codecov step, just to try to isolate the problem? I really suspect this is something going on in the setup before it gets to Codecov.

Indeed, I see the differences now between the 2 jacoco.xml files.

What could be the issue ?

@nbauma109 this is definitely out of my knowledge. I guess there has to be something different between how you’re running locally and on CI. I know you said versions are from pom, but what about the OS? Or java versions? I’m a bit out of my league.