问题
在开发springboot项目时,maven引入本地第三方jar包,在idea中运行正常。打成jar部署后报找不到类
错误如下:
ERROR SpringApplication.reportFailure(834) | Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'persistenceExceptionTranslationPostProcessor' defined in class path resource [org/springframework/boot/autoconfigure/dao/PersistenceExceptionTranslationAutoConfiguration.class]: Unsatisfied dependency expressed through method 'persistenceExceptionTranslationPostProcessor' parameter 0; nested exception is org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [org.jbpm.pvm.internal.processengine.SpringHelper] for bean with name 'springHelper' defined in class path resource [spring-jbpm.xml]; nested exception is java.lang.ClassNotFoundException: org.jbpm.pvm.internal.processengine.SpringHelper
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:799)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:540)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1341)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1181)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:556)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207)
at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:229)
at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:723)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:536)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:755)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:402)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1247)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1236)
at com.ceris.TestApplication.main(TestApplication.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
Caused by: org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [org.jbpm.pvm.internal.processengine.SpringHelper] for bean with name 'springHelper' defined in class path resource [spring-jbpm.xml]; nested exception is java.lang.ClassNotFoundException: org.jbpm.pvm.internal.processengine.SpringHelper
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1486)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:681)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:648)
at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1614)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:523)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:495)
at org.springframework.beans.factory.BeanFactoryUtils.beanNamesForTypeIncludingAncestors(BeanFactoryUtils.java:265)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1473)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1270)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1227)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:886)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:790)
... 28 more
Caused by: java.lang.ClassNotFoundException: org.jbpm.pvm.internal.processengine.SpringHelper
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:93)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.springframework.util.ClassUtils.forName(ClassUtils.java:284)
at org.springframework.beans.factory.support.AbstractBeanDefinition.resolveBeanClass(AbstractBeanDefinition.java:469)
at org.springframework.beans.factory.support.AbstractBeanFactory.doResolveBeanClass(AbstractBeanFactory.java:1551)
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1478)
... 39 more
项目
Maven依赖如下:
<dependency>
<groupId>org.jbpm</groupId>
<artifactId>jbpm-bpmn</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/jbpm-bpmn.jar</systemPath>
</dependency>
解决
在spring-boot-maven-plugin 插件设置加上includeSystemScope为true
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.6.2</version>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
原因
scope为system的maven默认是不打包进去的。
<parameter>
<name>includeSystemScope</name>
<type>boolean</type>
<since>1.4.0</since>
<required>false</required>
<editable>true</editable>
<description>Include system scoped dependencies.</description>
</parameter>
注:springboot的maven打包插件,只会扫描当前模块下的路径,并不会把其他模块项目路径下的外部jar进行打包,需将第三方包放进项目内。
扩展
Maven依赖的范围
有时依赖信息中除了目标 jar 包的坐标还有一个 scope 设置,这就是依赖的范围。依赖的范围有几个可选值,常用的有:compile、test、provided 三个,当然还有不常用的 runtime、system…
compile:默认范围,编译测试运行都有效
provided:在编译和测试时有效
runtime:在测试和运行时有效
test:只在测试时有效
system:在编译和测试时有效,与本机系统关联,可移植性差
依赖范围传递性
依赖的范围也有传递性(继承性),当前项目和引用的资源配置的作用范围不同时,存在以下关系:
生命周期
Maven有3个内置的构建生命周期:
clean – 清理构建输出,包括生成的编译类、JAR文件等
default – 编译源代码并处理打包项目相关的所有事情
site –为项目生成文档
Clean 生命周期
Clean 生命周期一共包含了三个阶段:
pre-clean 执行一些需要在 clean 之前完成的工作
clean 移除所有上一次构建生成的文件
post-clean 执行一些需要在 clean 之后立刻完成的工作
Default 生命周期
每执行一个命令,在该命令之前的命令都会执行,一直到该命令。比如执行test(测试)命令,在test之前的所有指令都会依次执行,一直到test为止,test之后的不会执行。其他声明周期也一样。
validate(校验):校验项目是否正确并且所有必要的信息可以完成项目的构建过程。
initialize(初始化):初始化构建状态,比如设置属性值。
generate-sources(生成源代码):生成包含在编译阶段中的任何源代码。
process-sources(处理源代码):处理源代码,比如说,过滤任意值。
generate-resources(生成资源文件):生成将会包含在项目包中的资源文件。
process-resources (处理资源文件):复制和处理资源到目标目录,为打包阶段最好准备。
compile(编译):编译项目的源代码。
process-classes(处理类文件):处理编译生成的文件,比如说对Java class文件做字节码改善优化。
generate-test-sources(生成测试源代码):生成包含在编译阶段中的任何测试源代码。
process-test-sources(处理测试源代码):处理测试源代码,比如说,过滤任意值。
generate-test-resources(生成测试资源文件):为测试创建资源文件。
process-test-resources(处理测试资源文件):复制和处理测试资源到目标目录。
test-compile(编译测试源码):编译测试源代码到测试目标目录。
process-test-classes(处理测试类文件):处理测试源码编译生成的文件。
test(测试):使用合适的单元测试框架运行测试(Juint是其中之一)。
prepare-package(准备打包):在实际打包之前,执行任何的必要的操作为打包做准备。
package(打包):将编译后的代码打包成可分发格式的文件,比如JAR、WAR或者EAR文件。
pre-integration-test(集成测试前):在执行集成测试前进行必要的动作。比如说,搭建需要的环境。
integration-test(集成测试):处理和部署项目到可以运行集成测试环境中。
post-integration-test(集成测试后):在执行集成测试完成后进行必要的动作。比如说,清理集成测试环境。
verify (验证):运行任意的检查来验证项目包有效且达到质量标准。
install(安装):安装项目包到本地仓库,这样项目包可以用作其他本地项目的依赖。
deploy(部署):将最终的项目包复制到远程仓库中与其他开发者和项目共享。
Site 生命周期
野马也 尘埃也 生物之以息相吹也pre-site 执行一些需要在生成站点文档之前完成的工作
site 生成项目的站点文档
post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
site-deploy 将生成的站点文档部署到特定的服务器上 这里经常用到的是 site 阶段和 site-deploy
阶段,用以生成和发布 Maven 站点,这可是 Maven 相当强大 的功能,Manager 比较喜欢,文档及统计数据自动生成,很好看。