Ant and Jacoco: Need to set junit's fork to “true” but not property that's true
Domanda
I'm using the Jacoco Junit task and tried the following:
<!-- run the junit tests -->
<echo>DEBUG: $${junit.fork} = "${junit.fork}"</echo>
<jacoco:coverage
destfile="${target.dir}/jacoco.exec"
append="false">
<junit fork="${junit.fork}" includeAntRuntime="true">
<classpath>
<pathelement path="${main.destdir}"/>
<pathelement path="${test.destdir}"/>
</classpath>
<classpath refid="test.classpath"/>
<formatter type="${junit.formatter.type}"/>
<batchtest todir="${junit.batchtest.todir}">
<fileset dir="${test.destdir}" />
</batchtest>
</junit>
</jacoco:coverage>
And got the following:
test:
[echo] DEBUG: ${junit.fork} = "true"
[jacoco:coverage] Enhancing junit with coverage
BUILD FAILED
D:\build.xml:233: Coverage can only be applied on a forked VM
Total time: 6 seconds
D:\>
As you can see, ${junit.fork}
property was set to true
, and I used that property in <junit fork="${junit.fork}"/>
.
However, instead of using that property, I simply set <junit fork="true">
, it works fine:
<jacoco:coverage
destfile="${target.dir}/jacoco.exec"
append="false">
<junit fork="true" includeAntRuntime="true">
<classpath>
<pathelement path="${main.destdir}"/>
<pathelement path="${test.destdir}"/>
</classpath>
<classpath refid="test.classpath"/>
<formatter type="${junit.formatter.type}"/>
<batchtest todir="${junit.batchtest.todir}">
<fileset dir="${test.destdir}" />
</batchtest>
</junit>
</jacoco:coverage>
I have run ant -d test
to verify that the Java JVM is forking when I use the ${junit.fork}
property.
Why is JaCoCo insisting that the JUnit test isn't being forked unless I set the fork
parameter to the string true
and not to a property that's equals true
?
Soluzione
According to the Jacoco coverage task source code :
...
public void enhanceTask(final Task task) {
final RuntimeConfigurable configurableWrapper = task.getRuntimeConfigurableWrapper();
final String forkValue = (String) configurableWrapper.getAttributeMap().get("fork");
if (!Project.toBoolean(forkValue)) {
throw new BuildException("Coverage can only be applied on a forked VM", getLocation());
}
addJvmArgs(task);
}
...
The forkValue is read from the configurableWrapper. The attribute map values (like ${junit.fork}
) are evalutated using the method RuntimeConfigurable.maybeConfigure
which is invoked by Task.mayBeConfigure
. And when you continue to look at the Jacoco source code :
...
public void addTask(final Task task) {
if (childTask != null) {
throw new BuildException("Only one child task can be supplied to the coverge task", getLocation());
}
this.childTask = task;
final String subTaskTypeName = task.getTaskType();
final TaskEnhancer enhancer = findEnhancerForTask(subTaskTypeName);
if (enhancer == null) {
throw new BuildException(format("%s is not a valid child of the coverage task", subTaskTypeName), getLocation());
}
if (isEnabled()) {
log(format("Enhancing %s with coverage", childTask.getTaskName()));
enhancer.enhanceTask(task);
}
task.maybeConfigure();
}
...
This method (mayBeConfigure
) is invoked after the task has been enhanced (enhancer.enhanceTask(task);
).
I guess that it is your problem and a bug... and we should report it to the jacoco bug tracker.