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

问题描述

我知道这是一个常见问题,我很不好意思提出这个问题,但我不明白为什么我无法加载我的多模块 Springboot 应用程序的主类。

完整的堆栈跟踪:

const

A 有一个根级 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) 文件

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

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

apply plugin: 'org.springframework.boot'

dependencies {
   // Removed,not important
}

对于根 bootJar { mainClass = 'space.forloop.addon.app.Main' } 文件是正确的,但似乎不是。还有什么我可能错过的吗?

解决方法

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

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

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

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

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

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

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

,

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

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

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