问题已经过编辑,请查看更新的部分以及我找到解决方案的所有不同方法。
最初的问题
我试图为我的项目创建一个可执行的jar文件,但是在尝试运行它时遇到错误no main manifest attribute, in kerkinibackend.jar
。
该项目是一个Spring Boot应用程序,我使用IntelliJ作为IDE。
我试图找到最常见的情况,当这可能发生在类似的问题上,但我不能让它以任何方式工作。
我采取的步骤是:
java -jar kerkinibackend.jar
然后出现错误消息。问题是MANIFEST.MF
文件实际上是在src/main/java/META-INF
中创建的Manifest-Version: 1.0
Main-Class: com.teicm.kerkinibackend.KerkinibackendApplication
我也确实在pom.xml中有所需的依赖项
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
UPDATE
我通过将清单的默认生成更改为资源来解决问题。
现在,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
(作为另一个答案Relevant question-answer中的读取)以修复上一个问题。现在它没有显示相同的错误,而是一个不同的错误
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)
但我不知道这是否会让我更近一步或更远一步。为什么不能识别MySQL数据源。当我在本地使用项目时,一切正常,它连接到MySQL,它与前端进行通信。
尝试使用maven-assembly-plugin
的不同构建方法
我还尝试使用不同的方法来构建可执行jar,通过@Zsolt Tolvary
s方法(你可以在link找到更多关于它的信息)。这种方法在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>
对于任何有空闲时间的人,可以随意向我推荐一个解决方案,甚至可以尝试一下 - 她自己。我真的需要生成它,这是完成我的论文的最后一部分......
Github存储库的链接是Github Repository
感谢您的时间和精力
@khmarbaise上面给出的答案是正确的,是成功创建Spring Boot可引导jar的关键。
我的回应只是提供额外的信息,希望能进一步澄清一些与您有关的重要事项。 (我会把它放在评论中,但由于这是我第一次发布SO,我发表评论需要50个声望点中的0个 - 另一方面我可以自由发布答案 - “启动”我自己的问题:-)
首先,您列出的初始IntelliJ步骤不是必需的。也没有使用程序集插件(稍后再说一点)。
只要您在spring-boot-maven-plugin
中定义了pom.xml
(假设您还将目标“packaging”定义为“jar” - 这两者都已经完成),那么Maven与Spring的交互将在运行时生成可引导的jar文件Maven包命令:mvn clean package
正如@khmarbaise还指出的那样,目前您需要指示Maven跳过测试执行,因为您的测试失败,这将阻止您的可启动jar的“打包”成功完成:mvn clean package -DskipTests
顺便说一下,IntelliJ包含一个方便的Maven“工具窗口”,它允许您从IDE运行这些Maven命令。如果没有显示,请转到视图 - >工具窗口并选择“Maven”。
Spring Boot应用程序本身被“组装”为“主要方法”jar文件。这就是为什么尝试使用maven-assembly-plugin
构建Spring Boot应用程序/ jar没有意义(或者工作,因为Spring Boot在Spring引导的jar内部创建了一个不同的内部结构)。
如果打包成功完成,您应该在“编译器输出”目录下看到以下一对jar文件(通常位于[PROJECT_ROOT_DIR]/target)
:
kerkinibackend-0.0.1-SNAPSHOT.jar
kerkinibackend-0.0.1-SNAPSHOT.jar.original
窥视MANIFEST.MF
的kerkinibackend-0.0.1-SNAPSHOT.jar
文件,你会看到几个关键条目:
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.teicm.kerkinibackend.KerkinibackendApplication
如何工作:当使用-jar
标志调用JVM时,它将在MANIFEST.MF
中搜索Main-Class
条目。在这种情况下,它会发现Spring的JarLauncher
类作为它应该调用以启动应用程序的main
方法的类。然后JarLauncher
将依次查找清单的Start-Class
条目,该条目已经填充了@SpringBootApplication
类的完全限定路径:(com.teicm.kerkinibackend.KerkinibackendApplication
)并且最终将在main
上调用KerkinibackendApplication
:
public static void main(String[] args) {
SpringApplication.run(KerkinibackendApplication.class, args);
}
希望这些信息有助于澄清一些事情。如果没有,请告诉我。祝你好运并祝贺你(几乎)完成你的论文!