如何调试无错误退出的OpenJDK 8 Java进程?
我使用最新版OpenJDK 8启动Jar包,执行命令如下:
/opt/jdk/jdk8u412-b08/bin/java -verbose -Djdk.tls.client.protocols="TLSv1.2" -cp "/applis/com/myapp/:/applis/com/myapp/myapp.jar" com.myapp.AppLauncher ... [Loaded java.lang.reflect.InvocationTargetException from /opt/jdk/jdk8u412-b08/jre/lib/rt.jar] [Loaded java.lang.Throwable$PrintStreamOrWriter from /opt/jdk/jdk8u412-b08/jre/lib/rt.jar] [Loaded java.lang.Throwable$WrappedPrintStream from /opt/jdk/jdk8u412-b08/jre/lib/rt.jar] [Loaded java.util.IdentityHashMap$IdentityHashMapIterator from /opt/jdk/jdk8u412-b08/jre/lib/rt.jar] [Loaded java.util.IdentityHashMap$KeyIterator from /opt/jdk/jdk8u412-b08/jre/lib/rt.jar] [Loaded java.lang.Shutdown from /opt/jdk/jdk8u412-b08/jre/lib/rt.jar] [Loaded java.lang.Shutdown$Lock from /opt/jdk/jdk8u412-b08/jre/lib/rt.jar] $ echo $? 0 $ /opt/jdk/jdk8u412-b08/bin/java -version openjdk version "1.8.0_412" OpenJDK Runtime Environment (Temurin)(build 1.8.0_412-b08) OpenJDK 64-Bit Server VM (Temurin)(build 25.412-b08, mixed mode)
进程无错误信息停止,退出码为0。
环境与运行情况说明
- 两台机器均为
Red Hat Enterprise Linux Server release 7.9 (Maipo),JDK版本、Jar包完全一致 - 两台机器SELinux状态均为Permissive:
$sudo getenforce Permissive
/applis/com/myapp目录仅包含Jar包和myapp.properties文件,两台机器该文件内容一致(仅存储服务器名称)
| 机器 | OpenJDK-1.8.0_412状态 | Oracle JSE 1.8.0_101-b13状态 |
|---|---|---|
| 机器1 | 启动失败(无错误退出,码0) | 启动成功 |
| 机器2 | 启动成功 | 启动成功 |
调试方法
增强日志输出维度
在启动命令中添加-Djava.util.logging.config.file=/path/to/custom-logging.properties指定详细日志配置,强制输出AppLauncher类的DEBUG级日志;同时添加-Xlog:all=debug:file=jvm_debug.log(OpenJDK 8u20+支持)生成JVM全流程调试日志,追踪类加载、初始化、线程启停的完整细节。排查系统依赖与环境差异
对比两台机器的环境变量:echo $PATH、echo $LD_LIBRARY_PATH,检查是否存在影响JDK加载的系统库差异;使用ldd /opt/jdk/jdk8u412-b08/jre/lib/amd64/server/libjvm.so查看故障机JVM依赖的系统库是否完整,有无版本不兼容情况。启用崩溃与核心转储分析
添加参数-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof排查内存问题;执行ulimit -c unlimited开启核心转储,进程退出后用jstack、jmap分析核心文件,查看退出时的线程状态与堆内存情况。简化启动流程排查
- 直接运行
/opt/jdk/jdk8u412-b08/bin/java -cp /applis/com/myapp/myapp.jar com.myapp.AppLauncher,去掉额外参数和目录类路径,排查参数或类路径导致的问题。 - 检查文件权限:
ls -l /applis/com/myapp/确保JDK进程对Jar包和配置文件有读权限;可直接复制机器2上的myapp.properties到故障机,排除文件隐藏字符或权限异常。
- 直接运行
对比JDK行为差异
执行java -XshowSettings:all输出两台机器JDK的配置差异,重点关注安全策略、TLS配置、系统属性默认值;添加-Djavax.net.debug=all开启TLS调试日志,排查是否是TLS协议配置导致的静默退出。
内容的提问来源于stack exchange,提问作者iclman

