
Exec format error 表示 systemd 尝试直接执行 JAR 文件(而非通过 Java 解释器),因 JAR 不是可执行二进制文件而失败;正确做法是显式调用 java -jar,并确保环境、路径和权限配置无误。
`exec format error` 表示 systemd 尝试直接执行 jar 文件(而非通过 java 解释器),因 jar 不是可执行二进制文件而失败;正确做法是显式调用 `java -jar`,并确保环境、路径和权限配置无误。
Systemd 无法直接运行 .jar 文件——它只支持执行具有合法 ELF 头的可执行程序(如 /usr/bin/java),而 JAR 是 ZIP 格式的归档包,需由 JVM 加载执行。你手动运行 java -jar app1.jar 成功,恰恰说明应用本身无问题;但当前 service 文件中 ExecStart=/opt/java_apps/app1/app1.jar 让 systemd 错误地尝试“直接执行”该 JAR,从而触发 Exec format error。
✅ 正确配置方式
必须将 ExecStart 显式指向 java 命令,并使用相对或绝对路径安全调用:
[Unit] Description=APP1 Java Service After=syslog.target Wants=network-online.target After=network-online.target [Service] Type=simple User=app1_user Group=app1_user WorkingDirectory=/opt/java_apps/app1 Environment="JAVA_HOME=/opt/java/jdk-17.0.7+7" Environment="PATH=/opt/java/jdk-17.0.7+7/bin:/usr/local/bin:/usr/bin:/bin" # ✅ 关键:显式调用 java -jar,避免硬编码路径失效 ExecStart=/usr/bin/env java -jar app1.jar # ✅ 推荐:启用日志捕获(替代危险的 StandardError=null) StandardOutput=journal StandardError=journal # ✅ 可选:加载自定义 JVM 参数(如你的 app1.conf) EnvironmentFile=/opt/java_apps/app1/app1.conf # ✅ 建议:添加 JVM 启动超时与重启策略 Restart=on-failure RestartSec=10 TimeoutStartSec=120 LimitNOFILE=65536 SuccessExitStatus=143 [Install] WantedBy=multi-user.target
? 为什么用
/usr/bin/env java?
它能根据PATH和JAVA_HOME自动定位java可执行文件,比硬写${JAVA_HOME}/bin/java更健壮(尤其当Environment=在ExecStart中不生效时)。若需严格绑定 JDK 版本,也可改用:ExecStart=/opt/java/jdk-17.0.7+7/bin/java -jar app1.jar
⚠️ 注意事项与最佳实践
-
禁止
StandardError=null/StandardOutput=null:这会完全丢弃所有输出,导致故障排查困难。应始终使用journal(默认)或重定向到文件(如StandardOutput=file:/var/log/app1/out.log)。 -
WorkingDirectory至关重要:确保app1.jar中引用的配置文件(如application.yml)、资源路径或-Dspring.config.location中的相对路径能被正确解析。 -
验证
EnvironmentFile加载:EnvironmentFile=仅支持KEY=VALUE格式;你原app1.conf中的JAVA_OPTS="-D..."是 Bash 变量赋值,systemd 不会自动展开JAVA_OPTS。如需传递 JVM 参数,请改用:Environment="JAVA_OPTS=-Dspring.config.location=/opt/java_apps/app1/conf/ -Dlogging.config=/opt/java_apps/app1/conf/logback.xml -server -Xms2g -Xmx2g ..." ExecStart=/usr/bin/env java ${JAVA_OPTS} -jar app1.jar或更推荐:将全部 JVM 参数直接写入
ExecStart(提升可读性与可控性)。
Java Maven Common下载Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
-
权限检查:
- 确保
app1_user对/opt/java_apps/app1/有读+执行权限(x对目录是进入必需); -
app1.jar需有读权限(无需x); -
JAVA_HOME目录及bin/java必须对app1_user可执行(ls -l $JAVA_HOME/bin/java)。
- 确保
✅ 验证与调试步骤
# 1. 重载配置 sudo systemctl daemon-reload # 2. 启动服务并观察实时日志 sudo systemctl start app1.service sudo journalctl -u app1.service -f # 3. 检查进程是否由正确用户运行 ps aux | grep app1.jar # 4. 手动模拟 systemd 环境测试(关键!) sudo -u app1_user -i bash -c 'cd /opt/java_apps/app1 && /usr/bin/env java -jar app1.jar'
遵循以上配置后,JAR 将作为标准 Java 进程被 systemd 托管,支持优雅启停、自动恢复、资源限制与集中日志管理,真正实现生产级可靠部署。
立即学习“Java免费学习笔记(深入)”;

















