GithubHelp home page GithubHelp logo

jacoco / jacoco Goto Github PK

View Code? Open in Web Editor NEW
4.0K 133.0 1.1K 10.58 MB

:microscope: Java Code Coverage Library

Home Page: https://www.jacoco.org/jacoco/

License: Other

Java 84.12% HTML 10.37% CSS 0.34% XSLT 0.92% Groovy 0.38% JavaScript 2.65% Kotlin 1.10% Scala 0.11%
jacoco coverage java kotlin groovy bytecode instrumentation java-agent java-virtual-machine java5

jacoco's Introduction

jacoco's People

Contributors

aalmiray avatar allenhair avatar andre15silva avatar andrioli avatar atomicknight avatar bjkail avatar brockj avatar c-otto avatar cdietrich avatar chonton avatar davidkarlsen avatar dependabot[bot] avatar ethauvin avatar fabianishere avatar franciscodua avatar gergelyfabian avatar godin avatar hrmohr avatar imbilltucker avatar jochenberger avatar klieber avatar manandbytes avatar marchof avatar mattnelson avatar merks avatar mfriedenhagen avatar ollin avatar renuka-fernando avatar sclassen avatar slachiewicz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jacoco's Issues

Stack trace printed when no test classes are run (Surefire 2.12.2+)

Version 2.12.2 of the maven-surefire-plugin includes an optimization that avoids forking the JVM if a fork mode of "once" is specified and there are no tests to run. Consequently, there is no guarantee that the Jacoco data file will be generated, leading to the following stack trace when the above conditions are met:

[ERROR] Unable to read execution data file /home/atomicknight/test/target/jacoco.exec: /home/atomicknight/test/target/jacoco.exec (The system cannot find the path specified)
java.io.FileNotFoundException: /home/atomicknight/test/target/jacoco.exec (The system cannot find the path specified)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.(FileInputStream.java:120)
at org.jacoco.maven.ReportMojo.loadExecutionData(ReportMojo.java:251)
at org.jacoco.maven.ReportMojo.executeReport(ReportMojo.java:228)
at org.jacoco.maven.ReportMojo.execute(ReportMojo.java:217)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)

I'm not sure how this should be addressed. The simplest solution is to just ignore the missing data file, but that might not be desirable in all situations.

include commandline tool for merge/reporting of jacoco results in main source tree/final jars

Many projects are using eg Make or another commandline based toll as build framework and for launching of different testsuites.

It would be nice to have (except excellent API you have already now) direct commandline tool for merging of exec files and for report generating. I have write one by myself for this task - http://mail.openjdk.java.net/pipermail/distro-pkg-dev/attachments/20121127/ba8f6a1e/jacoco-tool-0001.diff - ( from http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2012-November/020984.html) and I will be happy to help with inclusion of such a tool into your repository.

Thanx for this amazing tool,
J.

Filtering: Finally block coverage

Consider the following simple block of Java code:

try
{
  System.out.println("A");
}
catch (RuntimeException ex)
{
  System.out.println("B");
}
finally
{
  if (f())
  {
    System.out.println("finally");
  }
}

In bytecode this is transformed into the following:

try
{
  System.out.println("A");
  if (f())
  {
    System.out.println("finally");
  }
}
catch (RuntimeException ex)
{
  System.out.println("B");
  if (f())
  {
    System.out.println("finally");
  }
}
catch (Throwable th)
{
  if (f())
  {
    System.out.println("finally");
  }
  throw th;
}

The duplicates of the finally block code are all tagged with the original line numbers. This means the reported coverage of the finally block is not as expected. For example consider the conditional line:

if (f())

In the original source code it looks like there are only two branches to cover. However the coverage report claims that there are six branches to cover. This is because there are three duplications of the conditional line.

I think JaCoCo should handle finally blocks specially to track coverage of these blocks in a way that is less confusing.

Error "Illegal class name "[L"" when instrumenting OSGi application with EMMA

I get the following exception when running an OSGi Application from within Eclipse 4.2, EMMA/JaCoCo is version 0.5.9.201207300726

Which details do you need for closer analysis?

Illegal class name "[L" in class file x.y.z.XYZAnalyzer
java.lang.ClassFormatError: Illegal class name "[L" in class file x/y/z/XYZAnalyzer
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.defineClass(DefaultClassLoader.java:188)
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.defineClass(ClasspathManager.java:580)
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findClassImpl(ClasspathManager.java:550)
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClassImpl(ClasspathManager.java:481)
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass_LockClassLoader(ClasspathManager.java:469)
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:449)
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216)
    at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:393)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:469)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:422)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:410)
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
...

Links to the tests contributing to coverage

Besides the hotspot page covered in #8, there is one other feature in Clover which seems to be useful: Clover is able to show the tests which contributed to coverage.
While for unit tests created in a TDD fashion this would seem like overkill as you probably have one test class for one application class, for integration tests e.g. via Webdriver having links to the tests which contributed to coverage could be a good feature, as these integration tests do not have this 1:1 relationship.

Upgrade to ASM 4.0

Godin

Seems that release of ASM 4.0 planned on October 29, so we can upgrade JaCoCo in order to support new Java 7 instruction invokeDynamic.

marchof

This has a implication on EclEmma: Currently EclEmma ships without ASM, as ASM 3.x is part of Eclipse. If we migrate to 4.0 we need to include it with EclEmma.

Another thing is an license issue: We should wait until ASM 4.0 is IP approved by Eclipse, otherwise we lock JaCoCo out from official usage within Eclipse (e.g. JaCoCo is currently used for platform build).
Changed 9 months ago by mtnminds

Actually as a first step I would like to upgrade to 3.3.1. As all tests passes and this version has lots of bug fixes I will upgrade the dependency to 3.3.1 for now.

centic@SF

FYI, EclEmma 2.0.1 will ships with the ASM-bundle included because some Eclipse installations do not have it (i.e. if PDE is not installed), thus the first item should be covered starting with this release.

marchof

In the meantime I checked with Eclipse: They don't see any issues with ASM 4.0 IP approval, so we can go for it!

marchof

Another open issue: How do we consume ASM 4.0 as a bundle? It's not yet available from eclipse.org. For the EclEmma distribution we need a signed version of this bundle.
Changed 3 months ago by mtnminds

Opened bug against orbit to provide ASM 4.0:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=380801

marchof

Today I used some travel time for a prototype of JaCoCo based on ASM 4.0. There were two main issues:

ASM ClassVisitor and MethodVisitor has been converted to abstract classes. This breaks some internal interfaces in JaCoCo's flow analysis package which used to extend the ASM interfaces. For now I simply converted them also to classes which results in ugly class hierarchies. But this can be certainly refactored to a better structure.

The other issue was more tricky as it is about ASM runtime behavior only. Thanks to our regression tests I was quickly aware that the control flow analysis was completely broken at the beginning. The tree API of ASM 4.0 now replaces Label instances after every MethodNode.accept() call. This seriously hurts JaCoCo as we attach control flow information to label instances. My current workaround is to manually loop over the instruction list. But this hack might be better encapsulated when the internal APIs are redesigned anyways due to the issue above.

Build with maven 3 fails

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-plugin-plugin:2.7:report (report) on project jacoco-maven-plugin: Reporting mojo's can only be called from ReportDocumentRender -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-plugin-plugin:2.7:report (report) on project jacoco-maven-plugin: Reporting mojo's can only be called from ReportDocumentRender

Coverage task does not work with nested element that is a preset def

Assuming you have a preset def like:

<presetdef name="my.java">
  <java classname="org.jacoco.ant.TestTarget" failonerror="true">
    <classpath path="${org.jacoco.ant.coverageTaskTest.classes.dir}"/>
  </java>
</presetdef>

the following invocation of the coverage task will complain about the my.java task not being supported.

<jacoco:coverage>
  <my.java fork="true"/>
</jacoco:coverage>

It might be possible to work around this by configuring the sub tasks before enhancing and using the 'real' object (which is the java task). Unfortunately, this will require updating the constructed task objects instead of the source XML document.

Another hack might be to configure the sub tasks then 'unconfigure' them by setting the real object back to null. This is pretty nasty though and probably won't work

Multiply repot file merging with multimodule project reports aggregation

Hi! Our team using 3 types of jacoco reports in our projects

  • integration tests coverage
  • unit tests coverage
  • it+unit coverage

We used jacoco ant tasks for merging/aggregating job for a while but ended up with this patch: https://gist.github.com/4491163

Configuration example

<configuration>

  <!-- data files to merge -->
  <dataFiles>
    <dataFile>${jacoco.exec.it}</dataFile>
    <dataFile>${jacoco.exec.unit}</dataFile>
  </dataFiles>

  <!-- fail on missing data file from list -->
  <strict>false</strict>

  <!-- skip report generating for each module in 
       multimodule environment -->
  <skipModule>true</skipModule>

  <!-- ...and aggregate all module reports in superpom porject -->
  <aggregate>true</aggregate>
</configuration>

This patch does fallback to old behavior till no data passed to <dataFiles/>.

Anyway patch is rough enough and there is no tests yet... So any modifications are welcome!

Also it would be nice if we could combine this patch with patch from #12.

Allow to attach JaCoCo agent to running JVM

Godin

For more details see https://sourceforge.net/mailarchive/message.php?msg_id=27111681

brock_j@SF

Issues encountered while prototyping:

  • most classes will have been loaded by the time we attach, so we have to redefine existing classes
  • Each class to be instrumented must be explicity redefined. A list of loaded classes is available from the Instrumentation class
  • List of classes includes array classes - name starts with [L
  • Some classes aren't redefineable and need to be excluded. These are usually system classes that belong in the java and com.sun packages
  • It is quite possible for the define operation to fail is if the VM doesn't support the operation. The exception looks like: java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the schema (add/remove fields) - Jacoco adds a static field to every class

marchof

Until we have a compelling use case I wouldn't adopt a technology for JaCoCo that depends on Java 1.6 com.sun.* classes. Adjusting priority.

Godin

Hi guys,
Couple of notes :

  • we will not have a dependency on com.sun.* classes, because they needed only for performing attach, so core and agent will remain free from them
  • "java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the schema (add/remove fields)" occurs on attempt to add field, which is exactly the case for JaCoCo instrumentation, but not allowed - quote from Javadoc for Instrumentation : "The redefinition may change method bodies, the constant pool and attributes. The redefinition must not add, remove or rename fields or methods, change the signatures of methods, or change inheritance. These restrictions maybe be lifted in future versions." Which means that instrumentation algorithm should be modified to allow redefinition.

marchof

JaCoCo instrumentation currently adds

  • A static field to hold a reference to the probe array of this class
  • A method for lazy initialization of the field above

Both could be omitted if every instrumented method would include the code to retrieve the probe array instance from the runtime. But without caching this instance I expect a dramatic performance decrease, because every method call will result in a cascade of about ten additional method calls.

Godin

Also note: classfileBuffer, which is passed during retransformation doesn't match original bytes, which we read from disk for report, because CRC64 generates different values for them. In order to investigate difference - classfileBuffer should be dumped on disk and analysed. Most probably order of methods changed. In anyway this means that the way to determine classId should be changed.

Coverage of runtime modified classes

Mocking framework use case
It is common for a mocking framework (such as PowerMock/EasyMock) to modify a class under test to intercept code, such as a static class method being called to a stub/mock. This changes the CRC hash of the class bytes, hence the Analyzer (in reporting) can not match the code executed with the original class code. The report will then show no coverage for the class under test.

Is it possible to enhance the Analyzer to merge the coverage data from the modified class into a record for the original class? I'm thinking of an option in a report to use an alternate ExecutionDataStore that permits this type of merging.

I understand that instruction/statement level coverage data might be incorrect / unaligned, however we'd see great value in class and method level coverage reporting.

Problem setting up JaCoCo development environment:ASM

I have forked JaCoCo with the intention of prototyping a solution for Issue #14.

Unfortunately I am having trouble getting JaCoCo to build cleanly in Eclipse. I have attempted to follow http://www.eclemma.org/jacoco/trunk/doc/environment.html and have therefore downloaded Eclipse 3.7.2 and Java 1.5. However, when I open the org.jacoco.core project I hit the following errors:

Unsatisfied constraint: 'Import-Package: org.objectweb.asm; version="[4.1.0,4.2.0)"'    MANIFEST.MF /org.jacoco.core/META-INF   line 14 Plug-in Problem
Unsatisfied constraint: 'Import-Package: org.objectweb.asm.commons; version="[4.1.0,4.2.0)"'    MANIFEST.MF /org.jacoco.core/META-INF   line 16 Plug-in Problem
Unsatisfied constraint: 'Import-Package: org.objectweb.asm.tree; version="[4.1.0,4.2.0)"'   MANIFEST.MF /org.jacoco.core/META-INF   line 15 Plug-in Problem

This seems to contradict the statement in the development environment article: "JaCoCo has dependencies to ... Objectweb ASM 4.0 ... [which is] included with the Eclipse 3.7.x PDE feature".

Do I need to do something extra to sort out this ASM dependency?

try-with-resources Statement: wrong coverage

...
try(final ObjectOutputStream out = new ObjectOutputStream(baos))  {
    ....
}

Result: 4 of 8 branches missed.

I think that is not possible. When I wirite it without the java 7 feature than the coverage is ok, means 100%;

...
ObjectOutputStream out = null;
try {
       out=new ObjectOutputStream(baos);
        ...
} finally {
        out.close;
}

For try-with-resources Statement checking branches should be skipped.

Simple unit test fails with VerifyError (array problem?)

Not 100% sure this is a JaCoCo problem, but I think it is. I have small unit test that fails with the following VerifyError:

Expecting a stackmap frame at branch target 80 in method hs.mediasystem.Levenshtein.compare(Ljava/lang/String;Ljava/lang/String;)D at offset 52
java.lang.VerifyError: Expecting a stackmap frame at branch target 80 in method hs.mediasystem.Levenshtein.compare(Ljava/lang/String;Ljava/lang/String;)D at offset 52
at LevenshteinTest.test(LevenshteinTest.java:44)
(rest removed)

The unit test code is:

package hs.mediasystem.util;

import java.util.Arrays;
import java.util.Collection;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class LevenshteinTest {
  private final String text;
  private final String matchText;

  public LevenshteinTest(String text, String matchText) {
    this.text = text;
    this.matchText = matchText;
  }

  @Parameters
  public static Collection<Object[]> data() {
    return Arrays.asList(new Object[][]
      {
        {"Star Wars", "Star Warz"},
        {"Star Wars", "Staar Wars"},
        {"Star Wars", "Satr Wars"},
        {"Star Wars", "Star Wars - 04 - A new hope"},
        {"Star Wars Episode IV: A new hope", "Star Wars - 04 - A new hope"},
        {"Star Wars", "Stargate"},
        {"Star Wars", "Fantasic Four"},
        {"Star Wars: Clone Wars", "Star Wars"},
        {"Star Wars: Clone Wars", "Star Wars 4"},
        {"Star Wars: Clone Wars", "Star Wars 4 A New Hope"},
        {"Star Wars: Episode IV - A New Hope", "Star Wars"},
        {"Star Wars: Episode IV - A New Hope", "Star Wars 4"},
        {"Star Wars: Episode IV - A New Hope", "Star Wars 4 A New Hope"}
      }
    );
  }

  @Test
  public void test() {
    double compare = Levenshtein.compare(text.toLowerCase(), matchText.toLowerCase());
    System.out.println(text + " + " + matchText + " -> " + compare);
  }
}

And the class being tested (so you can try the test case):

package hs.mediasystem.util;

public class Levenshtein {

  public static double compare(final String s1, final String s2) {
    final int n = s1.length();
    final int m = s2.length();

    if(n == 0 || m == 0) {
      return 0;
    }

    return 1.0 - (compare(s1, n, s2, m) / (Math.max(n, m)));
  }

  private static double compare(final String s1, final int n, final String s2, final int m) {
    int[][] matrix = new int[n + 1][m + 1];

    for(int i = 0; i <= n; i++) {
      matrix[i][0] = i;
    }

    for(int i = 0; i <= m; i++) {
      matrix[0][i] = i;
    }

    for(int i = 1; i <= n; i++) {
      int s1i = s1.codePointAt(i - 1);

      for(int j = 1; j <= m; j++) {
        int s2j = s2.codePointAt(j - 1);
        final int cost = s1i == s2j ? 0 : 1;

        matrix[i][j] = min3(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + cost);
      }
    }

    return matrix[n][m];
  }

  private static int min3(final int a, final int b, final int c) {
    return Math.min(Math.min(a, b), c);
  }
}

Support for very long methods

When instrumenting a very long method, the instrumented method might exceed the maximum size for a Java method, resulting in

java.lang.ClassFormatError: Invalid method Code length 67507 in class file xxx

HTML report: hotspots page

Add a new global page 'Hotspots' that has several tables on it listing elements with the highest rank in respect to certain metrics, e.g.:

  • Methods with most instructions missed
  • Methods with most branches missed
  • Classes with most instructions missed
  • Classes with most branches missed
  • Methods with highest complexity
  • Classes with highest complexity

Includes/excludes options for Ant report task

Currently the scope of a coverage report can only be defined via the fileset in the classes tag. Especially in the situation where the report is created based in JAR files this does not allow fine grain control over the scope.

Therefore the group element should be extended with includes and excludes attributes that have the same semantics as in the coverage attribute.

JUnit Assert.fail() method call coverage unrecognized

It seems that for some strange reason if I have in my code under test a call to org.junit.Assert.fail() that line does not get recognized in the code coverage report and is reported as uncovered.

As an example consider this class

package foo.bar.test;

import static org.junit.Assert.fail;

public class SomeCode {
    public void method(boolean fail) {
        if (fail) {
            fail("FAIL!!!");
        }
    }
}

The following unit test will produce a code coverage report with a partial cover of the if statement (1 of 2 branches) and a missing line at the Assert.fail() statement:

package org.agileware.test;

import org.junit.Test;

public class SomeCodeTest {

    @Test
    public void testMethod() {
        new SomeCode().method(false);
    }

    @Test(expected=AssertionError.class)
    public void testMethodAgain() {
        new SomeCode().method(true);
    }

}

Am I doing something wrong?

Maven exception during generation of JaCoCo report

I have a Maven LifecycleExecutionException due to JaCoCo when generating the coverage report.
This bug only happens when the build is done on our Jenkins server (running Linux), not when I build on my local (Windows) computer.

[INFO] Generating "Distribution Management" report    --- maven-project-info-reports-plugin:2.6
[INFO] Generating "Project Summary" report    --- maven-project-info-reports-plugin:2.6
[INFO] Generating "Mailing Lists" report    --- maven-project-info-reports-plugin:2.6
[INFO] Generating "Dependencies" report    --- maven-project-info-reports-plugin:2.6
[INFO] Generating "JaCoCo" report    --- jacoco-maven-plugin:0.6.1.201212231917
[FINDBUGS] No report found for mojo site
[PMD] No report found for mojo site
[DRY] No report found for mojo site
[JENKINS] Archiving site from /home/tomcat/.jenkins/jobs/site-job/workspace/module1/target/site to /home/tomcat/.jenkins/jobs/site-job/site/module1
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] Build tools ....................................... SUCCESS [1:10.908s]
[INFO] Parent POM ........................................ SUCCESS [1:08.944s]
[INFO] Module1 ........................................... FAILURE [2:28.217s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 10:30.895s
[INFO] Finished at: Thu Jan 17 15:44:30 CET 2013
[INFO] Final Memory: 98M/229M
[INFO] ------------------------------------------------------------------------
Waiting for Jenkins to finish collecting data
mavenExecutionResult exceptions not empty
message : Failed to execute goal org.apache.maven.plugins:maven-site-plugin:3.2:site (default-site) on project module1: Error during page generation
cause : Error during page generation
Stack trace : 
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-site-plugin:3.2:site (default-site) on project module1: Error during page generation
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:217)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:319)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.jvnet.hudson.maven3.launcher.Maven3Launcher.main(Maven3Launcher.java:79)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchStandard(Launcher.java:329)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:239)
    at org.jvnet.hudson.maven3.agent.Maven3Main.launch(Maven3Main.java:158)
    at hudson.maven.Maven3Builder.call(Maven3Builder.java:112)
    at hudson.maven.Maven3Builder.call(Maven3Builder.java:70)
    at hudson.remoting.UserRequest.perform(UserRequest.java:118)
    at hudson.remoting.UserRequest.perform(UserRequest.java:48)
    at hudson.remoting.Request$2.run(Request.java:287)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: org.apache.maven.plugin.MojoExecutionException: Error during page generation
    at org.apache.maven.plugins.site.SiteMojo.execute(SiteMojo.java:143)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    ... 27 more
Caused by: org.apache.maven.doxia.siterenderer.RendererException: Error rendering Maven report: Unable to read execution data file /home/tomcat/.jenkins/jobs/site-job/workspace/module1/target/jacoco.exec: malformed input around byte 2
    at org.apache.maven.plugins.site.ReportDocumentRenderer.renderDocument(ReportDocumentRenderer.java:233)
    at org.apache.maven.doxia.siterenderer.DefaultSiteRenderer.renderModule(DefaultSiteRenderer.java:319)
    at org.apache.maven.doxia.siterenderer.DefaultSiteRenderer.render(DefaultSiteRenderer.java:135)
    at org.apache.maven.plugins.site.SiteMojo.renderLocale(SiteMojo.java:175)
    at org.apache.maven.plugins.site.SiteMojo.execute(SiteMojo.java:138)
    ... 29 more
Caused by: org.apache.maven.reporting.MavenReportException: Unable to read execution data file /home/tomcat/.jenkins/jobs/site-job/workspace/module1/target/jacoco.exec: malformed input around byte 2
    at org.jacoco.maven.ReportMojo.loadExecutionData(ReportMojo.java:247)
    at org.jacoco.maven.ReportMojo.executeReport(ReportMojo.java:229)
    at org.apache.maven.reporting.AbstractMavenReport.generate(AbstractMavenReport.java:190)
    at org.apache.maven.plugins.site.ReportDocumentRenderer.renderDocument(ReportDocumentRenderer.java:219)
    ... 33 more
Caused by: java.io.UTFDataFormatException: malformed input around byte 2
    at java.io.DataInputStream.readUTF(DataInputStream.java:634)
    at java.io.DataInputStream.readUTF(DataInputStream.java:564)
    at org.jacoco.core.data.ExecutionDataReader.readExecutionData(ExecutionDataReader.java:145)
    at org.jacoco.core.data.ExecutionDataReader.readBlock(ExecutionDataReader.java:111)
    at org.jacoco.core.data.ExecutionDataReader.read(ExecutionDataReader.java:85)
    at org.jacoco.core.data.ExecFileLoader.load(ExecFileLoader.java:51)
    at org.jacoco.core.data.ExecFileLoader.load(ExecFileLoader.java:65)
    at org.jacoco.maven.ReportMojo.loadExecutionData(ReportMojo.java:245)
    ... 36 more
channel stopped
[WARNINGS] Skipping publisher since build result is FAILURE
[JaCoCo plugin] Collecting JaCoCo coverage data...
[JaCoCo plugin] **/target/jacoco.exec;**/target/classes;**/src/main/java; locations are configured
[JaCoCo plugin] Number of found exec files: 5
[JaCoCo plugin] Saving matched execfiles:  /home/tomcat/.jenkins/jobs/site-job/workspace/module1/target/jacoco.exec /home/tomcat/.jenkins/jobs/site-job/workspace/cc/target/jacoco.exec /home/tomcat/.jenkins/jobs/site-job/workspace/fli/target/jacoco.exec /home/tomcat/.jenkins/jobs/site-job/workspace/jms/target/jacoco.exec /home/tomcat/.jenkins/jobs/site-job/workspace/webapp/target/jacoco.exec
[JaCoCo plugin] Saving matched class directories:  /home/tomcat/.jenkins/jobs/site-job/workspace/module1/target/classes /home/tomcat/.jenkins/jobs/site-job/workspace/buildtools/target/classes /home/tomcat/.jenkins/jobs/site-job/workspace/cc/target/classes /home/tomcat/.jenkins/jobs/site-job/workspace/fli/target/classes /home/tomcat/.jenkins/jobs/site-job/workspace/jms/target/classes /home/tomcat/.jenkins/jobs/site-job/workspace/scheduler/target/classes /home/tomcat/.jenkins/jobs/site-job/workspace/webapp/target/classes
[JaCoCo plugin] Saving matched source directories:  /home/tomcat/.jenkins/jobs/site-job/workspace/module1/src/main/java /home/tomcat/.jenkins/jobs/site-job/workspace/cc/src/main/java /home/tomcat/.jenkins/jobs/site-job/workspace/fli/src/main/java /home/tomcat/.jenkins/jobs/site-job/workspace/jms/src/main/java /home/tomcat/.jenkins/jobs/site-job/workspace/webapp/src/main/java
[JaCoCo plugin] Loading EXEC files..
[JaCoCo plugin] Publishing the results..
[JaCoCo plugin] Loading packages..
[JaCoCo plugin] Done.
Finished: FAILURE```

Investigate filtering with annotations

brock_j@SF

It may be useful to tag a method/class as unable to be covered. Elements that are tagged with this annotation will not be instrumented and will be skipped during structure analysis.

The annotation would have to have a retention of 'class' so it doesn't have to be present at runtime. The annotation could eventually be replaced by one provided by the JDK (if one is ever added)

It might be a good idea to actually mark the element as explicitly 'skipped' in reports so the total element counts are accurate.

marchof

We should put this on the list of filtering szenarios. Some concerns:

  • If the annotation is JaCoCo API, we get a dependency from production code to a particular code tool :-(
  • When we have a reasonable set of filtering patterns (e.g. for private, empty default constructors) the annotation requirement might become obsolete.

brock_j@SF

You are correct about the dependency issue. It is a compile time only link, which is slightly better, but probably still not acceptable.

How about something a little bit different?

We don't need to filter out members during instrumentation, instead, it could be done at the reporting/view stage. We could simple provide a file with instructions on what is to be skipped in the report. This would probably fit better with your idea of filtering options. This would just be a 'static' filtering rule (ignore the method called x in class org.example.Foo)

Eclipse integration could mark the ignored elements in some way (perhaps a special annotation of background colour)

brock_j@SF

How common would it be to not want to record coverage information for test classes? Could we look for classes that have test methods defined in them?

Or might we in future want to instrument test classes differently to put extra information into the execution data stream?

marchof

Test cases itself should not be in the scope of the coverage analysis. But as the test implementation typically has a different class path entry it can be easily ignored by the coverage analysis (see JaCoCo coverage report).

What could be useful indeed is a annotation, that defines the scope of a test case (something like @TestScope(MyClass.class). When the coverage runtime encounters this annotation e.g. on a method it would track execution information only for the given class(es). This would result in precise 1:1 test coverage data, filtering out all execution data that results from side effects from other tests. Actually for the JaCoCo build I already implemented this on bundle level by specifying an instrumentation filter that for the classes in the bundle under test only (so e.g. report tests do not produce any execution data for the core bundle, even though core classes are heavily used by the tests).

Add fault tolerance to the Maven Check mojo Edit

Different runs of jacoco may result in slightly different coverage results (for example, see https://groups.google.com/d/topic/jacoco/8EpEUQRjr4s/discussion ).

It would be great that this doesn't fail the build. This could be easily achieved by adding a "tolerance" configuration parameter for the check mojo.

It would be used like this for example:

          <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
...
            <configuration>
              <check>
                <instructionRatio>70.68</instructionRatio>
                <tolerance>10%</tolerance>
              </check>}
            </configuration>
          </plugin>

In this case the build would fail only if the result is < 70.68% - 10%.

"Level of Detail" attribute for report formatters

Currently the XML and HTML formatters creates a report down to individual methods and source files. The CSV formatter always lists classes. There are use cases where a more coarse grain structure would be sufficient (e.g. just groups, bundles or packages).

Jacoco does not generate link to report on Maven Site

When you create a coverage report using the Jacoco Maven Plugin, the report is accessible from target/site/jacoco/index.html

There is nothing wrong with that, but it is not possible to access the report by navigating to it from the main target/site/index.html page. Maybe it's a good idea to create a link in the left menu column that links to the Jacoco Report? This is common for all other reports, like Checkstyle, Findbugs and PMD. They even generate their content in Maven Format, so that the Maven menu always stays visible on the left. If this is undesired, because you don't want to tie Jacoco to Maven too much, then a simple link to the generated page will do. This is also how Cobertura does it.

Report format selection

The maven report goal should allow to select the formats to be created. Maybe we can use a similar syntax as in Ant to make the report formats configurable.

Mixing extra jvm arguments for the surefire-maven-plugin with jacoco

Noticed that the maven jacoco plugin appends the agent to the argLine property of the surefire plugin. Since I need to add some additional parameters to the jvm cmdline I ended up using something similar to this <argLine>-foobar ${argLine}</argLine> in order to preserve the jacoco agent. All works OK if I don't disable the jacoco plugin using the skip property. If I do that I end up with an argLine property which is not initialized and because of that the actual string "${argLine}" is appended to the jvm command line.

Is there a better way to handle extra surefire jvm arguments with the jacoco plugin?

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.12.1</version>
    <configuration>
        <forkMode>once</forkMode>
        <argLine>-foobar ${argLine}</argLine>
    </configuration>
</plugin>
<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>${jacoco.version}</version>
  <executions>
    <execution>
      <goals>
        <goal>prepare-agent</goal>
      </goals>
      <configuration>
        <skip>${jacoco.skip}</skip>
      </configuration>
    </execution>
    <execution>
      <id>report</id>
      <phase>prepare-package</phase>
      <goals>
        <goal>report</goal>
      </goals>
      <configuration>
        <skip>${jacoco.skip}</skip>
      </configuration>
    </execution>
  </executions>
</plugin>

Log destfile in jacoco:merge ant task

Each loaded .exec filename is logged, but target filename is not - it can help debug if user specified a location and expects the result in some other place.

JaCoCo appears to overcount switch statements

I am viewing unit test coverage in Sonar using JaCoCo. For a switch statement with three cases and a default block, with explicit breaks after each case, JaCoCo tells me I need to cover 10 paths. Now, this number would seem to make sense if each case fell through (4 + 3 + 2 + 1) but not when I explicitly break after each. Am I misunderstanding this number, or is this actually incorrect?

Support offline instrumentation

In certain scenarios the JaCoCo agent is not suitable, for example when the container is not under control of the test set or the VM simply doesn't support Java agents (Dalvik VM).

For this JaCoCo should offer an offline mode where class files can be instrumented during the build and jacocoagent.jar is simply put on the class path.

JMX MBean not registered

I'm usign the lastest version (0.6.2) but I cannot see the jacoco MBean from jconsole.
Running the MBeanClient provided in the examples I get a
javax.management.InstanceNotFoundException: org.jacoco:type=Runtime

Multi-report merging (within single project)

gelephantastic@SF

There are a few threads about Maven plugin datafile merging. I'd like to write in about the 2 major Maven merge use cases so you're aware. One is trivial, one is not. The trivial case is for multiple test types: unit tests, functional tests, and perhaps even integration tests or acceptance tests (like Concordion). For this case, I would expect that you could list additional, optional extra report files to conditionally be merged in at the report generation phase. This is trivial because it's all within a single Maven module. The harder case is merging the data file in a multi-project module, where I may want the parent pom to identify every report file that was used in any reactor module, and merge that into a master report for the whole build. This would ideally include all the "extra" reports from the trivial case above. I might try to code up the first use case. I expect I will tackle the problem exactly as I've described; the main dataFile parameter (defaulted to target/jacoco.exec) will still be expected. I might add either a list of files to (optionally) merge, or a directory that contains all the additional data files to be merged. It might be good to switch from target/jacoco.exec to using a directory, like target/jacoco/execution.exec, and then have the default behavior to merge everything in there, perhaps even then outputting the merged report to target/jacoco.exec. It's getting fuzzy here, since I'm out on a limb, but just a thought.

marchof

I like the idea to create a report on multiple exec-Files (like the Ant task also supports).

But to be honest I don't like the idea to recursively search directories. This might cause searching thousands of directories. Also there might be other *.exec files in the directories that should not be considered.

What is best practice here? Can't we supply a file set?

gelephantastic@SF

I picked the recursion simply because it was the smallest change (and also backwards compatible), but I certainly agree with your concerns. I don't know what the best practice is.. probably some sort of includes/excludes and a directory, or just statically listing all the reports that are expected?

In the case of the latter, do you use an API-breaking dataFiles/dataFile arrangement in the XML config, or do you keep dataFile and add an extraDataFiles/dataFile configuration block?

In the case of the former, you would keep a single dataFile but also add, I suppose, a dataFileFilter/include=*.exec or something of that nature. That option still requires recursion, but at least it is selective about what it picks up instead of trying to merge everything.

marchof

We can add a new property ("dataFiles") and deprecate the old one.

gelephantastic@SF

I think that's a good approach. I'm trying to figure out the "best practice" way of writing a Maven report plugin, to see how hard it would be to enable merging for a multi-module project. If I can just aggregrate the dataFiles list from all executed sub-modules, it will be a snap.

I'll fix my patch and re-attach (sans the multi-module investigation).

gelephantastic@SF

One thing I didn't address in this patch is handling the absence of report files. An exception will likely be raised for any desired report file that is not, in fact, present at the time of report generation. This is probably the desired behavior, though.

I dredged this up (http://docs.codehaus.org/display/MAVEN/Atypical+Plugin+Use+Cases) while thinking about multi-module merging/aggregation. I reviewed the Javadoc plugin, JXR, etc. - they have all ceased to use @Aggregator and resort to rather interesting tactics to handle multi-module reports. One of the main problems is that there are essentially 3 environments:

  1. Run as a report plugin within the Maven 3 site plugin.
  2. Inherited as a build plugin from the parent pom.
  3. Run once from an aggregator POM (no inheritance).

From what I can tell, this mess hasn't really been cleaned up in Maven 3 at all. @Aggregator is still around, the summarize phase doesn't exist, and parent/child ordering (in terms of when you want your plugin to run) is still tightly coupled to parent/child linkage declarations in the POM. Yuck.

kbrockhoff@SF

I took a different approach to aggregation. I have attached a diff with the changes I made to get my approach to work.

I define two profiles in my pom defining the build. One runs jacoco:agent with aggregate=true and then executes the unit tests. The other profile runs jacoco:agent and then executes both unit and integration tests. Both profiles result in a single jacoco.exec which is in the ${project.build.directory} of the execution root. Due to the issues discussed above about @Aggregator, I then have to run jacoco:report standalone to actually generate the report.

So the commands from the top level project are:

mvn clean install -Ptest.coverage (or -Pit.coverage)
mvn jacoco:report -Daggregate=true

gelephantastic@SF

This is a tough issue not made easier by Maven - I really wish they had added that summarize phase. I like your solution, but in my case, I can only make a single invocation of Maven (CI, business processes, separate scratch areas for build plans, all that jazz). Locally I can do whatever, I'm referring to our build infrastructure. Although perhaps with machinations I can trigger a dependent plan with the same scratch area.

Unrelated, I recommend you use variables and profile activation rather than setting profiles directly. So, mvn clean install -Dit.coverage; then you can activate any number of granular build options - you can, for example, choose to include test coverage with IT coverage if you like. I think I would want something like your solution AND something like mine, so I can run multiple invocations (test + IT) in a single build and aggregate both intra-module and inter-module reports such as you do here.

veithen@SF

There is another issue with kbrockhoff's changes. It will only work with multi-module projects where the root POM is also the parent POM. This is not necessarily the case. For projects that don't have this property, the execution fails with a NullPointerException. This is caused by the following piece of code in the patch:

while (!prj.isExecutionRoot()) {
  prj = prj.getParent();
}

Not sure how this should be fixed.

gelephantastic@SF

Nice catch. I did a little digging. I wish Maven actually had JavaDocs?, but anyway... MavenSession? has a "getProjects" method that might be usable to find all the projects that are targeted for building in the current execution context. There's also a getTopLevelProject() utility method.

It's probably a gross violation of Maven, and it might not even be possible if the ProjectDependencyGraph? implementation returns unmodifiable collections, but I wonder if it would be possible to insert a fake MavenProject? at the end of the sorted project list as a faux "summary" phase - you just clone the top level project and move the reporting execution. Somehow.

Quieter logging when -DskipTests

As mentioned at the end of #19 it would be useful to suppress the message Skipping JaCoCo execution due to missing execution data file from report—and also suppress any activity from prepare-agent—when skipTests (or maven.test.skip) is set.

Ant task or attributes for failing a build based on coverage

I want to be able to fail my Ant build if coverage drops below a certain level.

Is anyone assigned to this already? If not I might take a crack at it (caveat: I haven't even read the Jacoco developer docs, much less the Jacoco code)

This is the only thing preventing me from using Jacoco instead of Cobertura, which I would very much like to do because of the better Scala support in Jacoco. My employer has some mixed Java/Scala Ant builds that would be very difficult to migrate to Maven/SBT, mainly for operation reasons.

HTML report colours are not visible to all users

richard1000@SF

The span.fc and span.bc colours chosen cannot be differentiated by users who are red/green blind (approx 6% of the population). The colours chosen are too similar in shade to be distingushable.

Changing span.nc to #ffaaaa makes enough of a shade difference for me to be able to distinguish between them.

Ideally I would like (via attributes in the Ant report task) to be able to select my own colours to override the defaults when generating an HTML report.

marchof

Thanks for this valuable hint!

What about adding an option to provide your custom stylesheet? Then you can control all visual aspects. Alternatively you could easily replace the stylesheet after report generation.
Changed 4 weeks ago by richard1000

An option to provide a custom stylesheet would be fine, but I suspect that most people would only want to tweak the colours and so a convenience attribute to override the default colours would be good.

Replacing the stylesheet after report generation is a workaround (that I am doing), but it is better to use a correct one in the first place.

marchof

Ok, so I will adjust span.nc to #ffaaaa as a first step.

Some more questions: What about the colors of the

  1. red/green bars in the tables
  2. the branch diamonds at the left side in source annotations
  3. the yellow lines and diamonds for partial coverage?

do they also need adjustment?

Support for JDK 1.8.0

Status Overview

Latest snapshot build: Snapshot Repository

[x] ASM5: Release Required

We need a new ASM version which supports class file version 52.0. ASM 5.0_BETA is released to Maven central repo.

[x] Adjust JaCoCo to new ASM APIs: Done

JaCoCo needs to be adjusted to ASM5 APIs. This has been done on a experimental branch.

[x] Select proper runtime implementation: Done

The ModifiedSystemClassRuntime does not work any more with JRE 8. So an alternative Runtime has to be selected. The UrlStreamHandlerRuntime seems to do the job.

[x] Maven JavaDoc: Workaround

With JDK 8 JavaDoc generated by Maven fails to compile due to Lint checks. As a workaround we can disable this check for the Maven plugin.

[x] Invalid Line Numbers: Fixed with JDK Build 103

The JDK 8 compiler missed line number information in certain cases which makes our integration tests fail (and also leads to wrong line coverage results).

Add a coverage check mojo

timothyastle@SF

It would be nice if the JaCoCo Maven Plugin supported a mojo that would check the coverage and fail the build if the coverage was not met.

This was a nice feature in the Maven Cobetura plugin (http://mojo.codehaus.org/cobertura-maven-plugin/usage.html) and it helped developers know if their commit would drop the code coverage before actually committing.

Currently developers have to lean on sonar (external system) to see if their commit will break the build if build breaks are enabled.

Jacoco maven plugin clogs up logs with Exceptions

When I run Jacoco using the Jacoco maven plugin on a project, I get an enourmous amount of these exceptions in the log:

java.lang.instrument.IllegalClassFormatException: Error while instrumenting class org/apache/maven/surefire/report/ConsoleOutputCapture$ForwardingPrintStream.
    at org.jacoco.agent.rt_kqcpih.CoverageTransformer.transform(CoverageTransformer.java:91)
    at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
    at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:424)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    at org.apache.maven.surefire.junit.JUnit3Provider.invoke(JUnit3Provider.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:103)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:74)
Caused by: java.lang.IllegalStateException: Class org/apache/maven/surefire/report/ConsoleOutputCapture$ForwardingPrintStream is already instrumented.
    at org.jacoco.agent.rt_kqcpih.core.internal.instr.ClassInstrumenter.assertNotInstrumented(ClassInstrumenter.java:133)
    at org.jacoco.agent.rt_kqcpih.core.internal.instr.ClassInstrumenter.visitField(ClassInstrumenter.java:81)
    at org.jacoco.agent.rt_kqcpih.asm.ClassVisitor.visitField(Unknown Source)
    at org.jacoco.agent.rt_kqcpih.asm.ClassReader.accept(Unknown Source)
    at org.jacoco.agent.rt_kqcpih.asm.ClassReader.accept(Unknown Source)
    at org.jacoco.agent.rt_kqcpih.core.instr.Instrumenter.instrument(Instrumenter.java:69)
    at org.jacoco.agent.rt_kqcpih.core.instr.Instrumenter.instrument(Instrumenter.java:82)
    at org.jacoco.agent.rt_kqcpih.CoverageTransformer.transform(CoverageTransformer.java:89)
    ... 24 more

I get these exceptions for a lot of classes that come from external libraries, like Spring, Hibernate, JPA, Maven, etc., yet Jacoco seems to work fine and generates the reports correctly. I think that the issue is caused by the following line of code:

JacocoAgent.java, line 158:

final JacocoAgent agent = new JacocoAgent(options,
new IExceptionLogger() {
public void logExeption(final Exception ex) {
ex.printStackTrace();
}
});

Maybe it's a good idea not to have these exceptions in the log when they don't affect the correct behaviour of Jacoco? Or at least make it configurable, so that people with lots of exceptions in the log can turn it off? Also, printing them to the STDOUT is perhaps not be best way of logging things. Maven provides a org.apache.maven.plugin.logging.Log object, that should be used to log things that occur during a Maven Build.

Fail to build maven war project without src/main/resources folder

Some of my projects don't have resources and since I use git as SCM "resources" folder doesn't exists. In previous version of jacoco ("0.5.8.201207111220") stacktraces appear on console but build continues, on the latest version of jacoco "0.6.1.201212231917" build fail.

[ERROR] Failed to execute goal org.jacoco:jacoco-maven-plugin:0.6.1.201212231917:report (report) on project webapp: Execution report of goal org.jacoco:jacoco-maven-plugin:0.6.1.201212231917:report failed: basedir /home/sj/dev/tmp/121231/webapp/target/classes does not exist -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.jacoco:jacoco-maven-plugin:0.6.1.201212231917:report (report) on project webapp: Execution report of goal org.jacoco:jacoco-maven-plugin:0.6.1.201212231917:report failed: basedir /home/sj/dev/tmp/121231/webapp/target/classes does not exist
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:225)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.apache.maven.plugin.PluginExecutionException: Execution report of goal org.jacoco:jacoco-maven-plugin:0.6.1.201212231917:report failed: basedir /home/sj/dev/tmp/121231/webapp/target/classes does not exist
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:110)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    ... 19 more
Caused by: java.lang.IllegalStateException: basedir /home/sj/dev/tmp/121231/webapp/target/classes does not exist
    at org.codehaus.plexus.util.DirectoryScanner.scan(DirectoryScanner.java:550)
    at org.codehaus.plexus.util.FileUtils.getFileAndDirectoryNames(FileUtils.java:1717)
    at org.codehaus.plexus.util.FileUtils.getFileNames(FileUtils.java:1645)
    at org.codehaus.plexus.util.FileUtils.getFileNames(FileUtils.java:1627)
    at org.codehaus.plexus.util.FileUtils.getFiles(FileUtils.java:1601)
    at org.codehaus.plexus.util.FileUtils.getFiles(FileUtils.java:1584)
    at org.jacoco.maven.BundleCreator.createBundle(BundleCreator.java:63)
    at org.jacoco.maven.ReportMojo.createReport(ReportMojo.java:261)
    at org.jacoco.maven.ReportMojo.executeReport(ReportMojo.java:234)
    at org.jacoco.maven.ReportMojo.execute(ReportMojo.java:219)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    ... 20 more

Remove dependency on Sun classloader

By default the JaCoCo agent excludes the classloader sun.reflect.DelegatingClassLoader. As this classloader does not have access to the Java runtime library itself, therefore instrumented classes failed to load. This is documented in several places and can still be reproduced. It seems to be related to the following Java bug:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6265952

It would be nice to find another mechanism to determine this situation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.