2

https://docs.gradle.org/current/samples/sample_jvm_multi_project_with_code_coverage.html的示例开始(即这里的代码https://github.com/gradle/gradle/tree/master/subprojects/docs/src/ samples/java/jvm-multi-project-with-code-coverageapplication/build.gradle )并通过更改 为简单地添加 Spring Boot

plugins {
    id 'myproject.java-conventions'
    id 'application'
}

dependencies {
    implementation project(':list')
    implementation project(':utilities')
    implementation 'org.springframework.boot:spring-boot-starter-web:2.3.8.RELEASE' // <-- this line is new
}

application {
    mainClass = 'org.gradle.sample.Main'
}

并更改application/src/main/java/org/gradle/sample/app/Main.java

package org.gradle.sample.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.gradle.sample.list.LinkedList;

import static org.gradle.sample.utilities.StringUtils.join;
import static org.gradle.sample.utilities.StringUtils.split;
import static org.gradle.sample.app.MessageUtils.getMessage;

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        LinkedList tokens;
        tokens = split(getMessage());
        System.out.println(join(tokens));
        SpringApplication.run(Main.class, args);
    }
}

将打破这个例子(完整的工作,或者更确切地说是非工作的例子:https ://github.com/SamuelBucheliZ/gradle-jvm-multi-project-with-code-coverage/tree/57e57b8bf24ef4208d9a03a361714c916701e599 )。

打电话时

./gradlew clean build codeCoverage -stacktrace

它会失败

> Task :code-coverage-report:codeCoverageReport FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':code-coverage-report:codeCoverageReport'.
> Error while creating report

* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':code-coverage-report:codeCoverageReport'.
        [...]
Caused by: java.io.IOException: Error while analyzing log4j-api-2.13.3.jar@org/apache/logging/log4j/util/ProcessIdUtil.class.
        at org.jacoco.core.analysis.Analyzer.analyzerError(Analyzer.java:162)
        at org.jacoco.core.analysis.Analyzer.analyzeClass(Analyzer.java:134)
        at org.jacoco.core.analysis.Analyzer.analyzeClass(Analyzer.java:157)
        at org.jacoco.core.analysis.Analyzer.analyzeAll(Analyzer.java:193)
        at org.jacoco.core.analysis.Analyzer.analyzeZip(Analyzer.java:265)
        at org.jacoco.core.analysis.Analyzer.analyzeAll(Analyzer.java:196)
        at org.jacoco.ant.ReportTask.createBundle(ReportTask.java:573)
        at org.jacoco.ant.ReportTask.createReport(ReportTask.java:545)
        at org.jacoco.ant.ReportTask.execute(ReportTask.java:496)
        ... 251 more
Caused by: java.lang.IllegalStateException: Can't add different class with same name: org/apache/logging/log4j/util/ProcessIdUtil
        at org.jacoco.core.analysis.CoverageBuilder.visitCoverage(CoverageBuilder.java:106)
        at org.jacoco.core.analysis.Analyzer$1.visitEnd(Analyzer.java:99)
        at org.objectweb.asm.ClassVisitor.visitEnd(ClassVisitor.java:378)
        at org.jacoco.core.internal.flow.ClassProbesAdapter.visitEnd(ClassProbesAdapter.java:100)
        at org.objectweb.asm.ClassReader.accept(ClassReader.java:722)
        at org.objectweb.asm.ClassReader.accept(ClassReader.java:401)
        at org.jacoco.core.analysis.Analyzer.analyzeClass(Analyzer.java:116)
        at org.jacoco.core.analysis.Analyzer.analyzeClass(Analyzer.java:132)
        ... 258 more


* Get more help at https://help.gradle.org

BUILD FAILED in 8s
19 actionable tasks: 19 executed

我怀疑这可能与https://github.com/jacoco/jacoco/issues/407有关。但是,我的问题是是否有任何方法可以解决此问题。不幸的是, https://docs.gradle.org/current/userguide/jacoco_plugin.html上的官方文档没有提供有关此主题的任何指导。

据我所知,有问题的行是https://github.com/SamuelBucheliZ/gradle-jvm-multi-project-with-code-coverage/blob/57e57b8bf24ef4208d9a03a361714c916701e599/buildSrc/src/main/groovy/myproject.jacoco -aggregation.gradle#L38

// Task to gather code coverage from multiple subprojects
def codeCoverageReport = tasks.register('codeCoverageReport', JacocoReport) {
    additionalClassDirs(configurations.runtimeClasspath) // <-- this line here
    additionalSourceDirs(sourcesPath.incoming.artifactView { lenient(true) }.files)
    executionData(coverageDataPath.incoming.artifactView { lenient(true) }.files.filter { it.exists() })

    reports {
        // xml is usually used to integrate code coverage with
        // other tools like SonarQube, Coveralls or Codecov
        xml.enabled true

        // HTML reports can be used to see code coverage
        // without any external tools
        html.enabled true
    }
}

删除它将使构建再次工作。但是,代码覆盖率报告是空的。有什么办法可以调整它,所以它只会包含项目本身的代码,而不包含外部jar等?

4

2 回答 2

4

只要这样做,你会没事的(所有外部类都将被排除在外):

additionalClassDirs(configurations.runtimeClasspath.get().filter{it.path.contains(rootProject.name)  })

这适用于 Kotlin DSL,对于 Groovy,您可能需要以这种方式稍微更改代码:

additionalClassDirs(configurations.runtimeClasspath.filter{it.path.contains(rootProject.name)  })
于 2021-06-01T20:54:35.890 回答
1

一种可能的方法是定义

def sourcesOutputPath = configurations.create("sourcesOutputPath") {
    visible = false
    canBeResolved = true
    canBeConsumed = false
    extendsFrom(configurations.implementation)
    attributes {
        attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, Usage.JAVA_RUNTIME))
        attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category, Category.DOCUMENTATION))
        attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named(DocsType, 'source-output-folders'))
    }
}

然后在

additionalClassDirs(sourcesOutputPath.incoming.artifactView { lenient(true) }.files)

代替

additionalClassDirs(configurations.runtimeClasspath)

可以在https://github.com/SamuelBucheliZ/gradle-jvm-multi-project-with-code-coverage中找到完整的工作设置

于 2021-06-15T08:06:56.743 回答