背景
昨晚十点多,刚过完情人节的我回到家正在舒服的泡脚。突然,运维联系的一条消息让我心提到嗓子眼:你的 Java 应用无法启动,并附上一张截图,图中提示Error: unable to access jarfile xxx.jar
。
时间紧迫,心情焦急,我不得不熬夜排查问题,直到凌晨十二点才终于解决。以下是这段“惊心动魄”的排查过程,记录了我从迷茫到豁然开朗的心路历程。
1. 初遇问题:深夜的警报
1.1 问题的出现
晚上十点,运维像往常一样执行上线,使用 nohup java -jar xxx.jar &
启动应用,准备测试一下功能。然而,命令行无情地抛出了一行错误:Error: unable to access jarfile xxx.jar
我的心一下子提到了嗓子眼——本来准备美美的睡一觉了,时间紧迫,要赶紧解决,不然就扣绩效了,问题出在哪儿呢?
1.2 初步检查
我深吸一口气,告诉自己冷静下来,开始一步步排查:
-
文件是否存在 ls -l xxx.jar
,文件明明就在那里,权限也没问题。 -
Java 环境 java -version
,JDK 8,版本正常。 -
文件权限 chmod 755 xxx.jar
,权限也给了,为什么还是不行?
2. 深入排查:迷雾中的探索
2.1 检查 JAR 文件
既然文件存在,权限也没问题,难道是 JAR 文件损坏了?我试着用 jar -tf xxx.jar
查看文件内容,发现里面的文件列表正常,META-INF/MANIFEST.MF
也完好无损。
接着我用md5sum xxx.jar
查看文件md5值,发现服务器上的文件md5值和本地的不一致!
挖了个渠!问题就要解决了吗?于是重新传了一份jar文件确保md5值一样,以为万事大吉了,结果运维使用vim xxx.jar
的方式修改了jar包里配置文件的数据库连接,然后保存,这md5肯定不一样啊,不出意外,执行启动命令还是同样的错!以为发现了新大陆呢…
然后我想到了不修改jar文件内容,通过在启动命令修改参数。这样确保jar文件和预发环境一致,于是重新上传jar文件然后通过nohup java -Dxxx=yyy -Dmmm=nnn -jar xxx.jar &
的方式启动,还是同样的错!崩溃…
2.2 检查资源文件
突然想到,应用依赖了一些外部配置文件。会不会是路径问题?我打开代码,检查资源文件的加载逻辑,发现确实是通过相对路径加载的。于是,我试着将配置文件放到 JAR 文件同级目录下,但问题依旧。
2.3 尝试直接运行
为了进一步缩小问题范围,我直接运行:java -jar xxx.jar
结果依然是 unable to access jarfile xxx.jar
。这让我更加困惑——明明文件就在那里,为什么就是不行呢?
3. 转机:绝对路径的启示
3.1 灵光一现
就在我几乎要放弃的时候,突然想到:会不会是路径的问题?我之前一直在 JAR 文件所在目录下执行命令,使用的是相对路径 ./xxx.jar。于是,我试着改用绝对路径:java -jar /path/to/xxx.jar
奇迹出现了——应用成功启动了!
3.2 恍然大悟
原来,问题出在当前工作目录上。当我在 JAR 文件所在目录下执行命令时,应用程序内部可能基于当前工作目录加载资源文件,而相对路径的解析导致了路径错误。改用绝对路径后,路径问题迎刃而解。
4. 根本原因:相对路径的陷阱
-
当前工作目录的影响
应用程序在运行时依赖当前工作目录加载资源文件,而相对路径的解析受当前工作目录影响。 -
路径配置问题
应用程序未正确处理相对路径,导致资源文件无法加载。
5. 解决方案:绝对路径的力量
5.1 使用绝对路径
在启动命令中使用绝对路径:nohup java -jar /path/to/xxx.jar > output.log 2>&1 &
5.2 明确指定资源文件路径
如果应用程序依赖外部资源文件,使用绝对路径或明确指定路径:java -jar xxx.jar --spring.config.location=/path/to/application.properties
5.3 修改应用程序代码
在代码中确保资源文件的路径是绝对路径,或基于 JAR 文件的位置动态计算路径。
6. 预防措施:避免重蹈覆辙
-
避免直接修改 JAR 文件
如果需要修改 JAR 文件内容,建议解压、修改、重新打包。 -
使用外部配置文件
将配置文件放在 JAR 文件外部,通过命令行参数或环境变量指定路径。 -
统一路径管理
在应用程序中统一管理资源文件路径,避免硬编码。
7. 总结:深夜的收获
-
问题原因
相对路径导致资源文件加载失败。 -
解决方法
使用绝对路径启动 JAR 文件,或明确指定资源文件路径。 -
经验教训
在 Linux 系统中,尽量使用绝对路径启动应用程序,避免因当前工作目录变化导致的路径问题。
8. 示例命令
8.1 使用绝对路径启动
nohup java -jar /path/to/xxx.jar > output.log 2>&1 &
8.2 指定外部配置文件
java -jar xxx.jar --spring.config.location=/path/to/application.properties
8.3 设置环境变量
export SPRING_DATASOURCE_URL=jdbc:mysql://localhost:3306/mydb
export SPRING_DATASOURCE_USERNAME=root
export SPRING_DATASOURCE_PASSWORD=123456
java -jar xxx.jar
希望这篇笔记对你有帮助!如果有其他问题,欢迎随时交流!
原文始发于微信公众号(BiggerBoy):深夜奋战:解决 nohup java -jar xxx.jar 启动失败的曲折之路
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/315620.html