Java -jar 运行Spring Boot多模块项目提示没有主清单文件

Java -jar 运行Spring Boot多模块项目提示没有主清单文件

1.前言

我使用Maven自定义parent的方式搭建SpringBoot多模块项目,然后在本地开发运行没有问题,但是当要用Maven打包成jar包丢到服务器运行时,执行通过java -jar web.jar运行时提示web.jar中没有主清单属性却报了下面的错误:

java -jar web.jar
web.jar中没有主清单属性

2.解决web.jar中没有主清单属性

2.1.寻找问题原因出现的原因

既然本地开发运行没有问题,那应该思考是Maven打包时出现问题,根据提示是主清单属性找不到,在网上搜了一下,注清单是指Jar包中的META-INF目录MANIFEST.MF

打开jar包,META-INF目录下的MANIFEST.MF,内容如下:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: dell
Created-By: Apache Maven 3.8.1
Build-Jdk: 1.8.0_202

然后再对比公司其他项目的可运行的Jar包

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: dell
Start-Class: com.jrsmart.transfer.Application
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 2.2.1.RELEASE
Created-By: Apache Maven 3.8.1
Build-Jdk: 1.8.0_202
Main-Class: org.springframework.boot.loader.JarLauncher

就大概猜出是缺少了下面一些配置信息

Start-Class: com.jrsmart.transfer.Application
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 2.2.1.RELEASE
Main-Class: org.springframework.boot.loader.JarLauncher

其中比较关键还是我们没有主启动类Start-Class,是什么原因导致的呢?

2.2.为什么会缺少主启动类Start-Class

我web模块的pom文件如下:

    <parent>
        <artifactId>printer</artifactId>
        <groupId>com.jrsmart.print</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>web</artifactId>

然后父工程的pom是以spring-boot-dependencies依赖的形式来引入SpringBoot的定义的依赖的,没有使用到官方脚手架的方式来构建即下面的形式构建

image-20211211142740718

官方脚手架的方式是这样的

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

这就为我打包jar包埋下了坑,我开始尝试在网上寻找办法解决,网上大多数资料指出需要在pom.xml中配置maven插件,如下:

<build>  
 <plugins>  
     <plugin>  
         <groupId>org.springframework.boot</groupId>  
         <artifactId>spring-boot-maven-plugin</artifactId>  
     </plugin>  
 </plugins>  
</build>

我试了一下,发现在我自定义的parent的pom.xml下加入这些配置是没办法生效的

折腾了挺久的,于是我好奇点进去能运行的其他SpringBoot的jar包的spring-boot-starter-parent寻找问题

spring-boot-starter-parent 中maven插件的配置如下:

<plugin>  
 <groupId>org.springframework.boot</groupId>  
 <artifactId>spring-boot-maven-plugin</artifactId>  
 <executions>  
     <execution>  
         <goals>  
             <goal>repackage</goal>  
         </goals>  
     </execution>  
 </executions>  
 <configuration>  
     <mainClass>${start-class}</mainClass>  
 </configuration>  
</plugin>

好家伙一看到mainClass以及start-class,基本就觉得是这里的问题了,能上面缺少的Main-Class以及Start-Class对应

我们可以看到这里配置了主类信息以及一个重要的标签,对repackage的描述如下:

Repackages existing JAR and WAR archives so that they can be executed from the command line using  java -jar. 

重新打包现有的JAR和WAR归档文件,以便可以使用java -jar从命令行执行它们。  

看到这里我们就清楚了,当使用自定义的 parent 时,我们需要自行配置maven插件的<goal>属性,如下:

<build>  
     <plugins>  
         <plugin>  
             <groupId>org.springframework.boot</groupId>  
             <artifactId>spring-boot-maven-plugin</artifactId>  
             <executions>  
                 <execution>  
                     <goals>  
                         <goal>repackage</goal>  
                     </goals>  
                 </execution>  
             </executions>  
         </plugin>  
     </plugins>  
 </build>

2.3.解决问题

如果你是使用SpringBoot默认的parent来构建的话,那么就可以加入下面的配置应该就可以解决大多数问题

<build>  
 <plugins>  
     <plugin>  
         <groupId>org.springframework.boot</groupId>  
         <artifactId>spring-boot-maven-plugin</artifactId>  
     </plugin>  
 </plugins>  
</build>

如果你是使用SpringBoot自定义parent来构建的话,那么就可以加入mainClass配置应该就可以解决问题,mainClass对应的是SpringBoot全限定类名。

配置如下:

<plugin>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-maven-plugin</artifactId>
	<version>2.2.1.RELEASE</version>
	<configuration>
		<outputDirectory>
			${project.basedir}/deploy
		</outputDirectory>
		<fork>
			true
		</fork>
		<mainClass>
			com.jrsmart.print.WebApplication
		</mainClass>
	</configuration>
	<executions>
		<execution>
			<goals>
				<goal>
					repackage
				</goal>
			</goals>
		</execution>
	</executions>
</plugin>

之后指定mvn clean package指令打包jar包后看一下清单文件,内容如下:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: dell
Start-Class: com.jrsmart.print.WebApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 2.2.1.RELEASE
Created-By: Apache Maven 3.8.1
Build-Jdk: 1.8.0_202
Main-Class: org.springframework.boot.loader.JarLauncher

这样项目就打包成功了,通过java -jar也可以正确运行了。

3.经验总结

这里自己总结一下吧,如果项目没有特殊需求,就使用SpringBoot的默认脚手架方式搭建,也就是SpringBoot的Spring initializr来构建。

我这里是因为公司要搭建的服务很小型,不需要用到SpringBoot全部的依赖,自己按需引入spring-boot-dependencies然后手动排除一些依赖来达到轻量化项目大小的目的,因此踩了一些坑。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值