This is a fork of sbt-jacoco, an sbt plugin for code coverage analysis via JaCoCo.
See the docs for details on configuration options.
Original repository was forked due to issues during testing of our enterprise application. We are using Play Framework, which generates Routes.class
from router configuration in routes
config file. However, we have crossed a point when this file is so large that JaCoCo fails to instrument it. Running sbt jacoco
would fail with following exception:
Stack trace
java.io.IOException: Error while instrumenting Routes$$anonfun$routes$1.class.
at org.jacoco.core.instr.Instrumenter.instrumentError(Instrumenter.java:175)
at org.jacoco.core.instr.Instrumenter.instrument(Instrumenter.java:125)
at org.jacoco.core.instr.Instrumenter.instrument(Instrumenter.java:150)
at com.github.sbt.jacoco.data.InstrumentationUtils$$anonfun$instrumentClasses$4$$anonfun$apply$3.apply(InstrumentationUtils.scala:64)
at com.github.sbt.jacoco.data.InstrumentationUtils$$anonfun$instrumentClasses$4$$anonfun$apply$3.apply(InstrumentationUtils.scala:61)
at resource.AbstractManagedResource$$anonfun$5.apply(AbstractManagedResource.scala:88)
at scala.util.control.Exception$Catch$$anonfun$either$1.apply(Exception.scala:124)
at scala.util.control.Exception$Catch$$anonfun$either$1.apply(Exception.scala:124)
at scala.util.control.Exception$Catch.apply(Exception.scala:102)
at scala.util.control.Exception$Catch.either(Exception.scala:124)
at resource.AbstractManagedResource.acquireFor(AbstractManagedResource.scala:88)
at resource.ManagedResourceOperations$class.apply(ManagedResourceOperations.scala:26)
at resource.AbstractManagedResource.apply(AbstractManagedResource.scala:50)
at resource.ManagedResourceOperations$class.acquireAndGet(ManagedResourceOperations.scala:25)
at resource.AbstractManagedResource.acquireAndGet(AbstractManagedResource.scala:50)
at resource.ManagedResourceOperations$class.foreach(ManagedResourceOperations.scala:53)
at resource.AbstractManagedResource.foreach(AbstractManagedResource.scala:50)
at com.github.sbt.jacoco.data.InstrumentationUtils$$anonfun$instrumentClasses$4.apply(InstrumentationUtils.scala:61)
at com.github.sbt.jacoco.data.InstrumentationUtils$$anonfun$instrumentClasses$4.apply(InstrumentationUtils.scala:60)
at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:47)
at com.github.sbt.jacoco.data.InstrumentationUtils$.instrumentClasses(InstrumentationUtils.scala:60)
at com.github.sbt.jacoco.BaseJacocoPlugin$$anonfun$taskValues$8.apply(BaseJacocoPlugin.scala:98)
at com.github.sbt.jacoco.BaseJacocoPlugin$$anonfun$taskValues$8.apply(BaseJacocoPlugin.scala:98)
at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:40)
at sbt.std.Transform$$anon$4.work(System.scala:63)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:228)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:228)
at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
at sbt.Execute.work(Execute.scala:237)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:228)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:228)
at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159)
at sbt.CompletionService$$anon$2.call(CompletionService.scala:28)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 65536
at org.objectweb.asm.ClassReader.readLabel(ClassReader.java:2443)
at org.objectweb.asm.ClassReader.createLabel(ClassReader.java:2459)
at org.objectweb.asm.ClassReader.readStackMapFrame(ClassReader.java:3118)
at org.objectweb.asm.ClassReader.readCode(ClassReader.java:1849)
at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1275)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:679)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:391)
at org.jacoco.core.instr.Instrumenter.instrument(Instrumenter.java:103)
at org.jacoco.core.instr.Instrumenter.instrument(Instrumenter.java:123)
at org.jacoco.core.instr.Instrumenter.instrument(Instrumenter.java:150)
at com.github.sbt.jacoco.data.InstrumentationUtils$$anonfun$instrumentClasses$4$$anonfun$apply$3.apply(InstrumentationUtils.scala:64)
at com.github.sbt.jacoco.data.InstrumentationUtils$$anonfun$instrumentClasses$4$$anonfun$apply$3.apply(InstrumentationUtils.scala:61)
at resource.AbstractManagedResource$$anonfun$5.apply(AbstractManagedResource.scala:88)
at scala.util.control.Exception$Catch$$anonfun$either$1.apply(Exception.scala:124)
at scala.util.control.Exception$Catch$$anonfun$either$1.apply(Exception.scala:124)
at scala.util.control.Exception$Catch.apply(Exception.scala:102)
at scala.util.control.Exception$Catch.either(Exception.scala:124)
at resource.AbstractManagedResource.acquireFor(AbstractManagedResource.scala:88)
at resource.ManagedResourceOperations$class.apply(ManagedResourceOperations.scala:26)
at resource.AbstractManagedResource.apply(AbstractManagedResource.scala:50)
at resource.ManagedResourceOperations$class.acquireAndGet(ManagedResourceOperations.scala:25)
at resource.AbstractManagedResource.acquireAndGet(AbstractManagedResource.scala:50)
at resource.ManagedResourceOperations$class.foreach(ManagedResourceOperations.scala:53)
at resource.AbstractManagedResource.foreach(AbstractManagedResource.scala:50)
at com.github.sbt.jacoco.data.InstrumentationUtils$$anonfun$instrumentClasses$4.apply(InstrumentationUtils.scala:61)
at com.github.sbt.jacoco.data.InstrumentationUtils$$anonfun$instrumentClasses$4.apply(InstrumentationUtils.scala:60)
at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:47)
at com.github.sbt.jacoco.data.InstrumentationUtils$.instrumentClasses(InstrumentationUtils.scala:60)
at com.github.sbt.jacoco.BaseJacocoPlugin$$anonfun$taskValues$8.apply(BaseJacocoPlugin.scala:98)
at com.github.sbt.jacoco.BaseJacocoPlugin$$anonfun$taskValues$8.apply(BaseJacocoPlugin.scala:98)
at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:40)
at sbt.std.Transform$$anon$4.work(System.scala:63)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:228)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:228)
at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
at sbt.Execute.work(Execute.scala:237)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:228)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:228)
at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159)
at sbt.CompletionService$$anon$2.call(CompletionService.scala:28)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
[error] (test:fullClasspath) java.io.IOException: Error while instrumenting Routes$$anonfun$routes$1.class.
We were not the first to discover this issue - solution was already proposed and recently merge to version 3.3.0
. Unfortunately for us, this release (understandably) dropped support for sbt 0.13
. As we are in the middle of migration to Spring Boot, migrating to higher sbt and Scala versions proved to be too costly. As a solution, we have forked original repository, reverted to version 3.2.0
and backported fix for this to create custom 3.2.1
version.
To apply mentioned fix in your project, you need to specify sequence of excluded classes from JaCoCo instrumentation in your sbt.build
file. For our issue with Play Framework, we have used the following setting:
jacocoInstrumentationExcludes := Seq(
"router.Routes*",
"*routes$javascript*",
"*.routes"
)
If you want to test this library locally before publishing to artifactory, you can build this project using the following command:
sbt "++2.10.6" "^^0.13.17" clean publishLocal
Subsequently in your main project, register this library in your plugins.sbt
file:
addSbtPlugin("com.github.matusmak" % "sbt-jacoco" % "3.2.1")
If you haven't done already, make sure that your local repository is included in your list of resolvers:
resolvers ++= Seq(
Resolver.mavenLocal
)
All that is left to do is to sync sbt changes in your project.