Hello. I'm trying to configure some excludes for c...
# community-support
a
Hello. I'm trying to configure some excludes for code coverage. I tried this:
Copy code
plugins {
    id("jacoco")
    // ... everything else
}

tasks.withType<Test> {
    configure<JacocoTaskExtension> {
        excludes = listOf(
            "com.example.*",
        )
    }
}
but it doesn't seem to do anything. I tried different formats, like
com.example.**
,
com/example/*
and
com/example/**
, but none of them worked. How do I correctly do this? Btw I'm running coverage from IDE by just executing a Gradle task with the coverage option. I know I can edit the "run configuration" and add the excludes in the IDE's UI, but I'd rather have a global configuration in Gradle.
v
I might remember wrongly, but I don't think JaCoCo is used if you run it like that, but IJ's own coverage recording, then what you write to the build script would be irrelevant. Maybe you should just use IJ to display the coverage report generated by the Gradle run instead.
Actually, in the project settings you can switch between using IJ coverage recording and JaCoCo coverage recording, but even then I'm not sure whether it would reuse the build script settings.
a
Actually, in the project settings you can switch between using IJ coverage recording and JaCoCo coverage recording
Ah, so that was the source of my problems. Just found this:
Now it seems to work. Thank you very much 🙇
👌 1
No, sorry, I was wrong and celebrated too early. Now the coverage doesn't work at all. It shows 0% everywhere, which coincidentally was exactly what I expected as I tried to exclude all my code to test the config 🤦
🙈 1
So I guess this is the reason it shows 0% 😅
Copy code
> Task :users:testDebugUnitTest
Exception in thread "main" java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:118)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:560)
	at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:572)
Caused by: java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:118)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.jacoco.agent.rt.internal_0e20598.core.runtime.InjectedClassRuntime$Lookup.defineClass(InjectedClassRuntime.java:134)
	at org.jacoco.agent.rt.internal_0e20598.core.runtime.InjectedClassRuntime.startup(InjectedClassRuntime.java:54)
	at org.jacoco.agent.rt.internal_0e20598.PreMain.premain(PreMain.java:50)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	... 3 more
Caused by: java.lang.LinkageError: loader 'bootstrap' attempted duplicate class definition for java.lang.$JaCoCo. (java.lang.$JaCoCo is in module java.base of loader 'bootstrap')
	at java.base/java.lang.ClassLoader.defineClass0(Native Method)
	at java.base/java.lang.System$2.defineClass(System.java:2406)
	at java.base/java.lang.invoke.MethodHandles$Lookup$ClassDefiner.defineClass(MethodHandles.java:2505)
	at java.base/java.lang.invoke.MethodHandles$Lookup$ClassDefiner.defineClass(MethodHandles.java:2480)
	at java.base/java.lang.invoke.MethodHandles$Lookup.defineClass(MethodHandles.java:1865)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	... 8 more
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message Outstanding error when calling method in invokeJavaAgentMainMethod at src/java.instrument/share/native/libinstrument/JPLISAgent.c line: 627
*** java.lang.instrument ASSERTION FAILED ***: "success" with message invokeJavaAgentMainMethod failed at src/java.instrument/share/native/libinstrument/JPLISAgent.c line: 466
*** java.lang.instrument ASSERTION FAILED ***: "result" with message agent load/premain call failed at src/java.instrument/share/native/libinstrument/JPLISAgent.c line: 429
FATAL ERROR in native method: processing of -javaagent failed, processJavaStart failed
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.dylib+0x525930]  jni_FatalError+0x7c
V  [libjvm.dylib+0x68d68c]  JvmtiExport::post_vm_initialized()+0x2b8
V  [libjvm.dylib+0xa245ac]  Threads::create_vm(JavaVMInitArgs*, bool*)+0x6c8
V  [libjvm.dylib+0x544298]  JNI_CreateJavaVM+0x74
C  [libjli.dylib+0xa228]  JavaMain+0x100
C  [libjli.dylib+0xd5b0]  ThreadJavaMain+0xc
C  [libsystem_pthread.dylib+0x6c0c]  _pthread_start+0x88
> Task :users:testDebugUnitTest FAILED
v
Probably, if you run with
--info
(or
--debug
if it is not there) you can have a look at the JVM args used. I'd guess you now have the JaCoCo agent defined twice, once by the Gradle build and once injected by IJ and that does most probably not work.
It might still be best to just not use "... with Coverage" but just let IJ display the JaCoCo report that Gradle created.
Or it might be a candidate for a feature request to IJ to support this OOTB
Or to have a third "Coverage Tool" option that then just displays the Gradle-generated one when using "... with Coverage". That might maybe be the best solution. 🤷‍♂️
a
So far, my impression is that this must be some sort of a bug in the IDE. As soon as I switch to JaCoCo mode in the IDE, running tests with coverage always fails, so the feature must be broken or something.
v
As I said, I guess it tries to inject the JaCoCo agent to the execution while you configured Gradle to also inject the JaCoCo agent and twice the JaCoCo agent in the JVM then fails.
So I'd rather say it is a shortcoming or missing feature as I just explained in my last messages above. But it basically fails because you request JaCoCo usage twice.
I guess at least
Yes, guess confirmed 🙂
So there should probably be a bug report that IJ handles it more gracefully if JaCoCo is added by the Gradle build, and additionally a feature request to have a third coverage tool that just displays what Gradle already creates.
a
It might still be best to just not use "... with Coverage" but just let IJ display the JaCoCo report that Gradle created.
Yeah, this works fine, but it's cumbersome to select the appropriate report file every time with the IDE's file picker, especially when there are many modules etc.
v
That's why I recommended the feature request. You could probably configure your build to not use JaCoCo if the execution is done through IntelliJ (check for existence of system property
idea.active
), but then you will again not have the includes / excludes you define in the build script.