springboot服务引入外部jar包在windows运行正常,在linux环境上无法加载到引入jar包的类
一、问题描述
最近开发了一个springboot程序,需要依赖第三方jar包,这个jar包无法直接通过pom远程仓库下载,需要从自己本地引入,于是配置pom文件如下:将本地jar包引入工程,systemPath为jar所在的本地路径
<!--第三方jar包引入--> <dependency> <groupId>com.hikvision.js</groupId> <artifactId>data-sdk-bms</artifactId> <version>2.0.3</version> <scope>system</scope> <systemPath>${project.basedir}/lib/data-sdk-bms-2.0.3.jar</systemPath> </dependency>
在打包时将本地引入的jar引入打进lib文件夹下,如果没有如下配置,jar无法打入lib目录
<dependencySets> <dependencySet> <useProjectArtifact>false</useProjectArtifact> <outputDirectory>lib</outputDirectory> <unpack>false</unpack> <scope>system</scope> </dependencySet> </dependencySets>
然后使用maven打包,首先部署到windows机器上,启动程序,运行正常,然后将程序部署到linux环境上,运行报如下错误:
[WARN ] [2020-09-09 09:28:15] [org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)] Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.hikvision.js.deployalarmtool.DeployalarmtoolApplication]; nested exception is java.io.FileNotFoundException: class path resource [com/hikvision/bms/caller/BmsMessage.class] cannot be opened because it does not exist [ERROR] [2020-09-09 09:28:15] [org.springframework.boot.SpringApplication.reportFailure(SpringApplication.java:771)] Application startup failed org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.hikvision.js.deployalarmtool.DeployalarmtoolApplication]; nested exception is java.io.FileNotFoundException: class path resource [com/hikvision/bms/caller/BmsMessage.class] cannot be opened because it does not exist at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:183) at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:308) at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:228) at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:272) at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:92) at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:687) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:524) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:124) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) at com.hikvision.js.deployalarmtool.DeployalarmtoolApplication.main(DeployalarmtoolApplication.java:14) Caused by: java.io.FileNotFoundException: class path resource [com/hikvision/bms/caller/BmsMessage.class] cannot be opened because it does not exist at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:172) at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:50) at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:102) at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.createMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:89) at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.getMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:76) at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:80) at org.springframework.context.annotation.ConfigurationClassParser.asSourceClass(ConfigurationClassParser.java:701) at org.springframework.context.annotation.ConfigurationClassParser$SourceClass.getInterfaces(ConfigurationClassParser.java:879) at org.springframework.context.annotation.ConfigurationClassParser.processInterfaces(ConfigurationClassParser.java:368) at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:325) at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:247) at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:192) at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:297) at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:247) at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:200) at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:169) ... 13 more
nested exception is java.io.FileNotFoundException: class path resource [com/hikvision/bms/caller/BmsMessage.class] cannot be opened because it does not exist,显然是com/hikvision/bms/caller/BmsMessage.class这个类不存在,而这个类正是引入的本地的那个jar包中的,检查lib目录发现jar是存在的,并且权限也正常,这就很奇怪,一时间束手无策。
排查无果,又重新打包,发现一个maven的warning日志:
[WARNING] 'dependencies.dependency.systemPath' for com.hikvision.js:data-sdk-bms:jar should not point at files within the project directory, ${project.basedir}/lib/data-sdk-bms-2.0.3.jar will be unresolvable by dependent projects @ line 113, column 25
于是我便从这个warning入手进行排查,果然warning解决,问题也得到了解决。
二、解决方法
本地第三方jar包引入方法:
<!--第三方jar包引入--> <dependency> <groupId>com.hikvision.js</groupId> <artifactId>data-sdk-bms</artifactId> <version>2.0.3</version> </dependency>
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> <executions> <execution> <id>install-data-sdk-bms</id> <phase>clean</phase> <configuration> <file>${project.basedir}/lib/data-sdk-bms-2.0.3.jar</file> <repositoryLayout>default</repositoryLayout> <groupId>com.hikvision.js</groupId> <artifactId>data-sdk-bms</artifactId> <version>2.0.3</version> <packaging>jar</packaging> <generatePom>true</generatePom> </configuration> <goals> <goal>install-file</goal> </goals> </execution> </executions> </plugin>
按上面的方式配置pom,打包正常,windows和linux环境下运行也正常。