创建了 Spring Boot Jar。运行但失败`DataSourceProperties$DataSourceBeanCreationException:无法确定合适的驱动程序类`IntelliJ

Ale*_*its 1 java jar intellij-idea maven spring-boot


该问题已被编辑,请提前查看更新部分以及我处理它以找到解决方案的所有不同方式。


初始问题

我试图为我的项目创建一个可执行的 jar 文件,但在尝试运行它时遇到了错误no main manifest attribute, in kerkinibackend.jar

该项目是一个 Spring Boot 应用程序,我使用 IntelliJ 作为 IDE。

我试图从类似的问题中找到最常见的情况,但我无法让它发挥作用。

我采取的步骤是:

  1. 打开 IntelliJ。
  2. 在右上角的图标上打开项目的结构。
  3. 导航到 Artifact。
  4. 按加号添加新神器。
  5. JAR -> 来自具有依赖项的模块。(在有一个 MANIFEST.MF 文件时也尝试使用空白选项,该文件是我第一次尝试时自动生成的)。
  6. 在弹出对话框中打开 Main 类的文件夹并指定它。(当我在某处阅读时,也尝试将 Main 类留空,并通过 Manifest 将其与其连接)。
  7. 其余为默认。(这样 IntelliJ 还会创建所需的清单,以防您已经删除文件将允许再次生成它)
  8. 然后,我按 Build -> Build Artifacts -> Build。
  9. 创建的大小为 57Mbs。我尝试将它作为可执行文件运行,但我发现它不起作用。然后我打开cmd并运行java -jar kerkinibackend.jar,然后出现错误消息。问题是该MANIFEST.MF文件实际上是在src/main/java/META-INF
Manifest-Version: 1.0
Main-Class: com.teicm.kerkinibackend.KerkinibackendApplication

Run Code Online (Sandbox Code Playgroud)

我在 pom.xml 中也确实有所需的依赖项

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
Run Code Online (Sandbox Code Playgroud)





更新

我通过将清单的默认生成更改为资源中来解决该问题。

现在 Jar 运行了,但是我从 Spring 中得到并出错 No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.









进一步更新

我试图在资源文件夹的 META-INF 文件夹中添加一个额外的文件spring.factories(作为另一个答案相关问题答案的阅读)以解决上一个问题。现在它没有显示相同的错误而是不同的错误

00:24:26.230 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:767)
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:218)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1308)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1154)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:391)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1083)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:853)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
        at com.teicm.kerkinibackend.KerkinibackendApplication.main(KerkinibackendApplication.java:11)
Run Code Online (Sandbox Code Playgroud)

但我不知道这让我更近了一步还是更远了。为什么不能识别 MySQL 数据源。当我在本地使用该项目时,一切正常,它连接到 MySQL,与前端进行通信。





尝试使用不同的构建方法 maven-assembly-plugin

我还尝试使用不同的方式来构建可执行 jar,通过@Zsolt Tolvarys 方法(您可以在链接中找到更多相关信息)。这种方法在 pom.xml 中使用了另一个名为maven-assembly-plugin.

不幸的是,按照建议的步骤确实会生成一个 jar 文件,但是当我尝试运行现在存在于/target文件夹中的生成的 jar 时,我收到一条错误消息,提示Error: Could not find or load main class com.teicm.kerkinibackend.KerkinibackendApplication在插件中更改了 Main 类的名称:

<build>
        <plugins>
            <plugin>
                    <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <finalName>KerkiniBackEnd</finalName>
                    <appendAssemblyId>false</appendAssemblyId>
                    <archive>
                        <manifest>
                            <mainClass>com.teicm.kerkinibackend.KerkinibackendApplication</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
Run Code Online (Sandbox Code Playgroud)





对于有空闲时间的任何人,请随时向我建议解决方案,甚至可以自己尝试。我真的需要生成它,这是完成我论文的最后一部分......

Github 存储库的链接是Github 存储库

感谢您的时间和精力

mou*_*abs 8

@khmarbaise 上面给出的答案是正确的,是成功创建 Spring Boot 可启动 jar 的关键。

我的回应只是为了提供额外的信息,希望能够为你进一步澄清一些关键的相关事情。(我会把它放在评论中,但由于这是我第一次发布给 SO,我有 50 个声望点中的 0 个发表评论 - 另一方面,我可以自由发布答案 - “启动”我自己的问题:-)

首先,您列出的初始 IntelliJ 步骤不是必需的。程序集插件的使用也不是(下面会详细介绍)。

只要您spring-boot-maven-plugin在您的pom.xml(假设您还将目标“包装”定义为“jar” - 两者都已定义)中定义,那么在运行 Maven 包时,Maven 与 Spring 的交互将产生一个可引导的 jar 文件命令:mvn clean package

正如@khmarbaise 还指出的,目前您需要指示 Maven 跳过测试执行,因为您的测试失败,这将阻止您的可启动 jar 的“打包”成功完成: mvn clean package -DskipTests

顺便说一下,IntelliJ 包括一个方便的 Maven“工具窗口”,它允许您从 IDE 运行像这样的 Maven 命令。如果未显示,请转到“查看”->“工具窗口”并选择“Maven”。

Spring Boot 应用程序本身被“组装”为“主要方法”jar 文件。这就是为什么尝试使用 构建 Spring Boot 应用程序/jarmaven-assembly-plugin没有意义(或工作,因为 Spring Boot 在 Spring Boot 需要运行的 jar 内创建了不同的内部结构)。

如果打包成功完成,您应该在“编译器输出”目录下看到以下一对 jar 文件(通常位于[PROJECT_ROOT_DIR]/target)

kerkinibackend-0.0.1-SNAPSHOT.jar
kerkinibackend-0.0.1-SNAPSHOT.jar.original
Run Code Online (Sandbox Code Playgroud)

查看您的MANIFEST.MF文件,kerkinibackend-0.0.1-SNAPSHOT.jar您会看到几个关键条目:

Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.teicm.kerkinibackend.KerkinibackendApplication

Run Code Online (Sandbox Code Playgroud)

运作方式:当JVM与被调用的-jar标志,它会搜索MANIFEST.MFMain-Class条目。在这种情况下,它将找到 Spring 的JarLauncher类作为main它应该调用其方法来启动应用程序的类。JarLauncher会再依次查找清单的Start-Class条目已填入完全合格的路径到你的@SpringBootApplication类:( com.teicm.kerkinibackend.KerkinibackendApplication),并会在打开最终会调用mainKerkinibackendApplication

    public static void main(String[] args) {
        SpringApplication.run(KerkinibackendApplication.class, args);
    }
Run Code Online (Sandbox Code Playgroud)

希望这些信息有助于澄清一些事情。如果没有,请告诉我。祝你好运,祝贺你(几乎)完成你的论文!