我们项目中使用到第三方的库文件, 这些 jar 库文件并没有放到 Maven 中央库上, 导致我们需要在项目中自己配置使用. 我们的两三个开发人员对 Java 都是很熟, 因此在使用中遇到了一些问题, 表现在: 在本地中引入第三方 jar 包后, 在 Idea 中进行相应设置后, 可以调试运行了, 但是用 Docker 打包上传到服务器后, 运行时会提示找不到某些类的定义.
经查看这些找不到的类就是来自第三方库, 那么问题有可能是第三方 jar 包的路径问题, 或者是根本就没有打包进 jar 文件里面. 我们可以去 Docker 容器内部查看 jar 文件, 执行命令: jar tf xxx.jar|grep lib, 其中 xxx.jar 是打包后生成的文件名称. 这个命令打印出 jar 文件中 lib 目录下的所有文件, 从这里我们可以看到, 确实没有包含第三方的 jar 文件.
在网上找了一阵子, 各种说法五花八门, 然而都不能解决问题, 比如这里有一篇: 3-ways-to-add-local-jar-to-maven-project, 看着貌似能解决问题, 但使用后还是无法解决. 比如将第三方 jar 包安装到本地 Maven, 这种方式是可以解决本地编译的问题, 但我们还得去编译服务器上再安装一遍, 而且要指定 groupId,artifactId 等东西, 感觉蛮麻烦. 我们只想在编译打包时, 把我们的 lib 文件夹的文件都拷贝到 jar 文件的 lib 目录下. 有什么办法呀?
Maven 中有各种 plugin, 也就是插件, 有人推荐用 assembly 插件, 比如这样写:
- <plugin>
- <artifactId>
- maven-assembly-plugin
- </artifactId>
- <configuration>
- <descriptorRefs>
- <descriptorRef>
- jar-with-dependencies
- </descriptorRef>
- </descriptorRefs>
- </configuration>
- </plugin>
我们以为这样就能把所有依赖包放进最终的 jar 文件中了, 可惜试了之后还是不行, 其它类似方法也试了都不行. 后面想想, 是不是要把 lib 文件夹放到 resource 目录下. 试了之后, 发现这回倒是拷贝进 jar 文件了, 但是放置的位置是 BOOT-INF/classes/lib 里面, 而其他的库文件则放到 BOOT-INF/lib 里面, 这样运行时会不会找不到那些第三方 jar 文件呢? 我们没有验证, 然后在这里找到一篇文章, 解决了拷贝 lib 目录文件到 BOOT-INF/lib 的问题, 配置如下:
- <resources>
- <resource>
- <directory>
- src/lib
- </directory>
- <targetPath>
- BOOT-INF/lib/
- </targetPath>
- <includes>
- <include>
- **/*.jar
- </include>
- </includes>
- </resource>
- <resource>
- <directory>
- src/main/resources
- </directory>
- <targetPath>
- BOOT-INF/classes/
- </targetPath>
- </resource>
- </resources>
这样之后, 所有的依赖包都放到 BOOT-INF/lib 目录下了, 程序也可以正常运行了.
以为到这里能加鸡腿了, 结果来个更大的坑. 第三方库里面有读取文件的接口, 我们在使用接口时, 传入了一个配置相关的文件的路径, 我们是在 resources 目录下新建了个目录来存放这个配置文件的. 运行时异常:
- java.io.FileNotFoundException:
- class path resource [aaa/xxx.conf] cannot be resolved to absolute file path because it does not reside in the file system.
这个问题是因为程序去读取文件时, 是去文件系统里面找文件, 而不是从 jar 里面找, 人家是建议使用 getInputStream 而不是 getFile. 可是读取文件的功能是第三方库实现的, 我们没法改动读取文件的方式. 那怎么办? 老老实实在 Dockerfile 文件加个拷贝操作呗, 把配置文件放到文件系统相应目录下即可.
总结一下, 这个问题的原因还在于, 我们对官方 Maven 文档不熟, 没有研究过各种配置, 对 Jar 文件的组织结构和运行原理不太清楚, 因为我们几个 Java 方面的经验都不够多, 踩过的坑还太少, 同时也不得不感叹, Java 开发里面的各种配置, 也真是眼花缭乱啊, 即便我们也使用了 Spring Boot 这种简化了配置的开发框架.
来源: https://www.cnblogs.com/woshiweige/p/11180274.html