【问题标题】:Exception in thread "main" java.lang.ClassNotFoundException - Springboot, multimodule gradle project线程“main”中的异常 java.lang.ClassNotFoundException - Spring Boot,多模块 gradle 项目
【发布时间】:2021-04-06 04:19:07
【问题描述】:

我知道这是一个常见问题,我很尴尬地问这个问题,但我不知道为什么我无法加载我的多模块 Springboot 应用程序的主类。

完整的堆栈跟踪:

Exception in thread "main" java.lang.ClassNotFoundException: space.forloop.addon.app.Main
    at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
    at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:398)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:46)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:107)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
    at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)

A 有一个根级 gradle.build 文件

plugins {
    id 'org.springframework.boot' version '2.4.1'
    id 'io.spring.dependency-management' version '1.0.10.RELEASE'
    id 'java'
}

repositories {
    mavenCentral()
}

bootJar {
    mainClass = 'space.forloop.addon.app.Main'
}

def javaProjects = [
        'addon-sync-app',
        // Removed, not important
]

javaProjects.each {
    name ->

        project(":$name") {
            apply plugin: 'org.springframework.boot'
            apply plugin: 'io.spring.dependency-management'
            apply plugin: 'java'

            repositories {
             // Removed, not important
            }

            dependencies {
             // Removed, not important
            }
        }
}

在包模块 addon-sync-app 我有另一个 build.gradle 文件,它只有:

apply plugin: 'org.springframework.boot'

dependencies {
   // Removed, not important
}

查看Configuring the Main Class 的文档,我确定添加:

bootJar {
    mainClass = 'space.forloop.addon.app.Main'
}

到根gradle.build 文件在这里是正确的,但似乎不是。还有什么我可能错过的吗?

【问题讨论】:

    标签: java spring-boot gradle multi-module


    【解决方案1】:

    您以错误的方式使用 Spring Boot 插件。这是一个常见的错误,我认为他们需要更好地记录它,或者让它开箱即用。哦,好吧。

    在 Gradle 多项目中,您通常定义支持库,然后定义一个或多个可运行或可部署的应用程序。

    从您的描述中我无法判断的一件事是您是否打算使用根项目来构建最终应用程序,或者它是否应该是 addon-sync-app 项目。给定名称,我假设是后者,但它可以是其中之一(但通常不能同时是两者)。

    当你将 Spring Boot 插件应用到一个项目(无论是根项目还是子项目),并且你依赖默认值时,它将把那个项目变成一个“ fat jar”,它需要一个特殊的类加载器才能运行。这使得它不适合作为普通库。因此,当您尝试以正常方式依赖它时,将找不到您的类。

    要修复它,您应该只将 Spring Boot 插件应用于构建最终应用程序 jar 的项目。如果是addon-sync-app,则将其从根和所有非应用程序子项目中删除。

    如果您希望根项目生成最终应用程序,则需要为所有必需的子项目创建依赖项,并像以前一样从它们中删除 Spring Boot 插件。

    不应用 Spring Boot 插件时你会失去的一件事是对 BOM 的自动依赖,它定义了依赖的默认版本。如果你想继续使用它而不创建你的库的胖罐子,有几种不同的方法来处理它。我在here 上写了一个(有点太长)答案。

    【讨论】:

      【解决方案2】:

      根据 gradle 文档,您可以尝试添加 'application' 插件。

      https://docs.gradle.org/current/userguide/application_plugin.html

      plugins {
          id 'application'
      }
      
      application {
          mainClass = 'space.forloop.addon.app.Main'
      }
      

      【讨论】:

      • 不,这是一项不同的任务,而不是我所追求的,它也不起作用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-22
      • 2020-08-01
      • 2016-02-15
      • 2016-06-11
      • 2016-02-26
      相关资源
      最近更新 更多