使用 maven shade-plugin 测试 fat jar

tests fat jar with maven shade-plugin

我需要构建一个 jar 用于在服务器上 CI 进程期间执行测试。这个 jar 必须包含所有测试依赖项(如 junit、mockito)和 spring 引导依赖项,而我的测试将使用 spring。我写了这样的maven配置:

        <plugin>
            <artifactId>maven-shade-plugin</artifactId>
            <executions>
                <execution>
                    <id>shade</id>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <finalName>${project.artifactId}-fat</finalName>
                        <minimizeJar>false</minimizeJar>
                        <shadeTestJar>false</shadeTestJar>
                        <artifactSet>
                            <includes>
                                <include>*:*</include>
                            </includes>
                        </artifactSet>
                        <transformers>
                            <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <mainClass>pl.klolo.demo.demo.smoke.SmokeTestAppKt</mainClass>
                                <manifestEntries>
                                    <Multi-Release>true</Multi-Release>
                                </manifestEntries>
                            </transformer>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>

Maven 构建了一个包含所有依赖项的 jar,但是当我尝试执行测试时出现我无法理解的奇怪错误:

2022-04-08 20:45:44.611  INFO 591618 --- [           main] p.k.d.demo.tests.DemoApplicationTests    : No active profile set, falling back to 1 default profile: "default"
2022-04-08 20:45:45.018 ERROR 591618 --- [           main] o.s.boot.SpringApplication               : Application run failed
java.lang.IllegalStateException: Unable to read meta-data for class 
    at org.springframework.boot.autoconfigure.AutoConfigurationSorter$AutoConfigurationClass.getAnnotationMetadata(AutoConfigurationSorter.java:237) ~[demo-fat.jar:0.0.1]
    at org.springframework.boot.autoconfigure.AutoConfigurationSorter$AutoConfigurationClass.getOrder(AutoConfigurationSorter.java:208) ~[demo-fat.jar:0.0.1]
    at org.springframework.boot.autoconfigure.AutoConfigurationSorter$AutoConfigurationClass.access[=11=]0(AutoConfigurationSorter.java:154) ~[demo-fat.jar:0.0.1]
    at org.springframework.boot.autoconfigure.AutoConfigurationSorter.lambda$getInPriorityOrder[=11=](AutoConfigurationSorter.java:64) ~[demo-fat.jar:0.0.1]
    at java.base/java.util.TimSort.countRunAndMakeAscending(TimSort.java:355) ~[na:na]
    at java.base/java.util.TimSort.sort(TimSort.java:220) ~[na:na]
    at java.base/java.util.Arrays.sort(Arrays.java:1515) ~[na:na]
    at java.base/java.util.ArrayList.sort(ArrayList.java:1750) ~[na:na]
    at org.springframework.boot.autoconfigure.AutoConfigurationSorter.getInPriorityOrder(AutoConfigurationSorter.java:62) ~[demo-fat.jar:0.0.1]

你能告诉我哪里出了问题以及如何解决吗?

SmokeTestApp:

fun main(args: Array<String>) {
    val launcher = LauncherFactory.create()
    val listener = SummaryGeneratingListener()
    launcher.registerTestExecutionListeners(listener)
    launcher.execute(
       LauncherDiscoveryRequestBuilder.request()
          .selectors(selectPackage("pl.klolo"))
          .build()
    )

    printSummary(listener.summary)
    exitProcess(
        if (listener.summary.failures.isEmpty()) 0
        else -1
    )
}

fun printSummary(summary: TestExecutionSummary) {
    println("Passed tests:  ${summary.testsSucceededCount}")

    summary.failures.forEach {
        println("###FAILED TEST ${it.testIdentifier.uniqueId}###")
        it.exception.printStackTrace()
    }
}

演示应用程序测试:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
class DemoApplicationTests(
    @Value("${test.applicationURI}") val applicationURI: String,
    @Value("${test.applicationPort}") val applicationPort: Int
) {

init {
    RestAssured.baseURI = applicationURI
    RestAssured.port = applicationPort
}

@Tag("smoke_test")
@Test
fun contextLoads() {
    println("smoke test ===> 1")
}

我找到了问题的原因。这是文件 spring.factories,条目为:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=

当我删除文件 jar 时工作正常