线程“main”中的异常 java.lang.ClassNotFoundException - Spring Boot,多模块 gradle 项目

Posted

技术标签:

【中文标题】线程“main”中的异常 java.lang.ClassNotFoundException - Spring Boot,多模块 gradle 项目【英文标题】:Exception in thread "main" java.lang.ClassNotFoundException - Springboot, multimodule gradle project 【发布时间】: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 文件在这里是正确的,但似乎不是。还有什么我可能错过的吗?

【问题讨论】:

【参考方案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'

【讨论】:

不,这是一项不同的任务,而不是我所追求的,它也不起作用。

以上是关于线程“main”中的异常 java.lang.ClassNotFoundException - Spring Boot,多模块 gradle 项目的主要内容,如果未能解决你的问题,请参考以下文章

我的代码上的线程“main”java.util.NoSuchElementException 中的异常?

如何修复运行时错误-线程“main”java.util.NoSuchElementException中的异常

HTTPClient 示例 - 线程“main”中的异常 java.lang.NoSuchFieldError: INSTANCE

为啥我在代码中的线程“main”java.lang.StringIndexOutOfBoundsException 错误中收到异常?

线程“main”中的 Java 异常 java.lang.StringIndexOutOfBoundsException 错误

线程“main”中的异常 java.lang.ExceptionInInitializerError (Clojure)