1.Main class name has not been configured and it could not be resolved from classpath

* What went wrong:
Execution failed for task ':processAot'.
> Error while evaluating property 'applicationMainClass' of task ':processAot'.
   > Failed to calculate the value of task ':processAot' property 'applicationMainClass'.
      > Main class name has not been configured and it could not be resolved from classpath

检查是否存在有jar包的模块用到了springBoot插件,如果有的话,去掉。

    id("org.springframework.boot") version "3.5.6"

2.(GraalVM)This can be caused by a plugin being applied to two sibling projects and then using a shared build service.

* What went wrong:
Could not determine the dependencies of task ':dynamic-naming-config-server:bootJar'.
> Could not create task ':dynamic-naming-config-server:collectReachabilityMetadata'.
   > Cannot set the value of task ':dynamic-naming-config-server:collectReachabilityMetadata' property 'metadataService' of type org.graalvm.buildtools.gradle.internal.GraalVMReachabilityMetadataService loaded with InstrumentingVisitableURLClassLoader(ClassLoaderScopeIdentifier.Id{coreAndPlugins:settings[:]:buildSrc[:]:root-project[:]:project-dynamic-naming-config-server(export)}) using a provider of type org.graalvm.buildtools.gradle.internal.GraalVMReachabilityMetadataService loaded with InstrumentingVisitableURLClassLoader(ClassLoaderScopeIdentifier.Id{coreAndPlugins:settings[:]:buildSrc[:]:root-project[:]:project-dynamic-naming-config-api(export)}).
     This can be caused by a plugin being applied to two sibling projects and then using a shared build service. To fix this, use `@ServiceReference` or add the problematic plugin with `apply false` to the root build script.

原因是多个模块声明了GraalVM插件,导致ClassLoader出现冲突。

3.前后端模块组合打包文件拷贝失败

我的配置:

tasks.named<ProcessResources>("processResources") {
    from(project(":dynamic-naming-config-ui").layout.buildDirectory)
    into(layout.buildDirectory.dir("resources/main/static/"))
    // 指定依赖顺序, 必须在dynamic-naming-config-ui的build任务之后执行
    mustRunAfter(project(":dynamic-naming-config-ui").tasks.named("build"))
}

参考的Halo的配置,但是into(layout.buildDirectory.dir("resources/main/static/"))这行怎么改都不生效。

tasks.named('processResources', ProcessResources) {
    from project(':ui').layout.buildDirectory.dir('dist')
    into layout.buildDirectory.dir('resources/main')
    configure {
        mustRunAfter project(':ui').tasks.named('build')
    }
}

询问ChatGPT,ChatGPT告诉我,应该写成如下的配置内容。Halo当中的配置的into layout.buildDirectory.dir('resources/main')其实没生效,只不过它是默认值,所以恰好没问题。

// 处理资源文件的编译打包, 把前端打包文件打包到jar包当中
tasks.named<ProcessResources>("processResources") {
    from(project(":dynamic-naming-config-ui").layout.buildDirectory) {
        into("static")
    }
    dependsOn(project(":dynamic-naming-config-ui").tasks.named("build"))
}

原因在于:在 Gradle 的 CopySpec DSL(from {} / into {})和 ProcessResources Task 本身的属性 中,into 的语义有点不一样:
• 在 task 配置外层调用 into(...):它是 CopySpec 的配置,决定复制文件时的目标路径(相对 destinationDir)。
• 在 ProcessResources 任务上调用 into(...):它是 AbstractCopyTask 的方法,实际上会改变整个任务的输出目录(即 destinationDir),而 processResources 默认的输出路径就是 build/resources/main/,所以into(layout.buildDirectory.dir("resources/main/static/")),会被 Gradle 当作是“覆盖整个任务输出路径”的配置,但因为 processResources 自己又有默认输出路径,所以你以为没生效。

其实就是processResources的输出路径不让修改。也可以有另外一种改法,新增一个task,copy的task默认是没有输出路径的,可以对它进行配置。

tasks.register<Copy>("copyUiToResources") {
    from(project(":dynamic-naming-config-ui").layout.buildDirectory)
    into(layout.buildDirectory.dir("resources/main/static"))
    dependsOn(project(":dynamic-naming-config-ui").tasks.named("build"))
}
tasks.named("processResources") {
    dependsOn("copyUiToResources")
}