springboot thin jar启动失败处理
起因
使用springboot开发java后端服务很方便,但是久而久之发现springboot的依赖也越来越多jar也越来越大,有时候构建项目部署也很慢,针对这个问题springboot也给出给jar“瘦身”的方法,就是使用spring-boot-thin-launcher使用方式也很简单。只要在spring-boot-maven-plugin
插件中引入 spring-boot-thin-layout
就可以。
<properties>
<wrapper.version>1.0.27.RELEASE</wrapper.version>
</properties>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>${wrapper.version}</version>
</dependency>
</dependencies>
</plugin>
分析问题
在项目中引入spring-boot-thin-layout之后,通过mvn package构建jar构建完成之后发现jar变小了只有几十kb,这是因为通过thin瘦身之后,构建的jar包只包含我们的类,没有其他东西。
troyMac~ ll ./target
total 48
drwxr-xr-x 4 qujianfei staff 128B 3 30 23:12 classes
-rw-r--r-- 1 qujianfei staff 14K 3 30 23:12 function-sample-pojo-2.0.0.RELEASE.jar
-rw-r--r-- 1 qujianfei staff 6.5K 3 30 23:12 function-sample-pojo-2.0.0.RELEASE.jar.original
但是如果这时候我们直接通过jar -jar来运行应用,会遇到class not found的异常服务无法启动,原因就是上面说到的因为这个thin jar只有我们自己的类,没有服务所需要的依赖等其他信息因此无法启动。
Exception in thread "main" java.lang.ClassNotFoundException: org.springframework.boot.loader.thin.ThinJarLauncher
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at org.springframework.boot.loader.wrapper.ThinJarWrapper.launch(ThinJarWrapper.java:138)
at org.springframework.boot.loader.wrapper.ThinJarWrapper.main(ThinJarWrapper.java:107)
针对这个问题也找了一些资料,说是通过指定-Dthin.root=.
,这个方式我尝试了还是不行。因为-Dthin.root参数是指定一个本地的依赖缓存的位置,可以理解为maven仓库,如果目录不存在就会创建一个。可以问题的关键是依赖没有被下载下来。
解决问题 - 使用spring-boot-thin-maven-plugin
后来发现解决这个问题可以选择添加spring-boot-thin-maven-plugin
,然后重新执行mvn package,这时候会在target目录下多一个thin的目录,./target/thin目录下会保存应用所需要的依赖,这时候在启动服务,通过java -Dthin.root=target/thin/root -jar ./target/function-sample-pojo-2.0.0.RELEASE.jar
参数指定依赖所需再的仓库位置repository服务就可以正常启动。
<plugin>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-maven-plugin</artifactId>
<version>${wrapper.version}</version>
<executions>
<execution>
<!-- Download the dependencies at build time -->
<id>resolve</id>
<goals>
<goal>resolve</goal>
</goals>
<inherited>false</inherited>
</execution>
</executions>
</plugin>
./target/thin目录 服务启动正常
总结
在使用spring-boot-thin-layout构建thin jar,在启动的时候如果遇到Exception in thread "main" java.lang.ClassNotFoundException: org.springframework.boot.loader.thin.ThinJarLauncher
异常,可以使用spring-boot-thin-maven-plugin
将依赖拉取到本地,再结合-Dthin.root参数来解决。
pom.xml中的plugins
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>${wrapper.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-maven-plugin</artifactId>
<version>${wrapper.version}</version>
<executions>
<execution>
<!-- Download the dependencies at build time -->
<id>resolve</id>
<goals>
<goal>resolve</goal>
</goals>
<inherited>false</inherited>
</execution>
</executions>
</plugin>
</plugins>