英文:
systemd Unable to find Java
问题
我在Centos Dist上遇到了一个奇怪的行为,尝试运行一个使用Spring Boot创建的可引导的JAR文件。
如果我从Shell中运行JAR应用程序,它可以正常运行。
当使用以下配置创建的服务运行应用程序时:
[Unit]
Description=app
After=syslog.target
[Service]
ExecStart=/foo/bar/app.jar
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
~
我一直收到错误消息"无法找到Java"。
我检查了$PATH和$JAVA_HOME属性,它们都正确设置(我认为这不会增加更多信息,因为可引导的JAR在不作为服务的情况下可以正常运行)。
我做错了什么?我已经围绕这个问题忙碌了3天,它让我发疯。
英文:
I'm facing a strange behaviour on a Centos Dist trying to run a bootable jar created with spring boot.
If I run the jar app from the shell it runs perfectly
When running the app with a service created with the following config:
[Unit]
Description=app
After=syslog.target
[Service]
ExecStart=/foo/bar/app.jar
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
~
I keep getting the error "Unable to find Java"
I checked the $PATH and $JAVA_HOME properties and they are set up correctly (I don't think this adds more information because the bootable jar runs correctly without beeing a service)
What I'm doing wrong? Been messing around this problem for 3 days and it's driving me mad.
答案1
得分: 11
The long and short of the issue is that systemd does not run services in the same context as the user shell, and the mechanism used for running .jar files directly uses the PATH
variable to determine the location of the JRE for running the jar.
如果java位于默认的systemd路径上,服务将会默认启动。systemd的默认路径 绝对不包含您为java指定的路径。
To address the PATH variable not being set sufficiently, we're going to update the service configuration with a PATH
environment variable more suitable to it. To accomplish this, we need to add a Environment
variable to the [Service]
section of the service definition file.
要解决PATH变量不足的问题,我们将会更新服务配置,使用更适合它的PATH
环境变量。为了做到这一点,我们需要在服务定义文件的[Service]
部分添加一个Environment
变量。
[Unit]
Description=app
After=syslog.target
[Unit]
Description=app
After=syslog.target
[Service]
Environment=PATH=/usr/lib/jvm/jdk-14.0.2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/foo/bar/app.jar
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
然后我们重新加载systemd(systemctl daemon-reload
),然后应该能够启动服务(systemctl start blah.service
)。
然后我们重新加载systemd(systemctl daemon-reload
),然后应该能够启动服务(systemctl start blah.service
)。
It would probably be significantly easier if the jre you want to use is integrated into the OS; it saves having to futz around with the PATH, and would survive upgrades to java, which would alter the path, requiring an update to the service definition - there's a pretty good guide here as to how to install it, system integrated:
如果您想要使用的JRE集成到操作系统中,那可能会更加简单;这样可以避免与PATH进行操作,并且在Java升级时也能保持兼容,因为Java升级会改变路径,需要更新服务定义 - 这里有一份不错的指南,详细介绍了如何进行系统集成安装:
-
Download rpm
wget --no-check-certificate -c --header "Cookie: oraclelicense=accept-securebackup-cookie" https://download.oracle.com/otn-pub/java/jdk/14.0.2+12/205943a0976c4ed48cb16f1043c5c647/jdk-14.0.2_linux-x64_bin.rpm
-
Install locally
yum localinstall jdk-14.0.2_linux-x64_bin.rpm
-
Use
alternatives
to configure javaalternatives --config java
-
Check after setting
java -version
-
下载rpm
wget --no-check-certificate -c --header "Cookie: oraclelicense=accept-securebackup-cookie" https://download.oracle.com/otn-pub/java/jdk/14.0.2+12/205943a0976c4ed48cb16f1043c5c647/jdk-14.0.2_linux-x64_bin.rpm
-
本地安装
yum localinstall jdk-14.0.2_linux-x64_bin.rpm
-
使用
alternatives
配置Javaalternatives --config java
-
设置后检查
java -version
英文:
The long and short of the issue is that systemd does not run services in the same context as the user shell, and the mechanism used for running .jar files directly uses the PATH
variable to determine the location of the JRE for running the jar.
If java was on the default systemd path, then the service would start by default. The default path for systemd definitely does not contain the path that you're specifying for java.
To address the PATH variable not being set sufficiently, we're going to update the service configuration with a PATH
environment variable more suitable to it. To accomplish this, we need to add a Environment
variable to the [Service]
section of the service definition file.
[Unit]
Description=app
After=syslog.target
[Service]
Environment=PATH=/usr/lib/jvm/jdk-14.0.2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/foo/bar/app.jar
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
Then we reload systemd (systemctl daemon-reload
), and we should be able to start the service (systemctl start blah.service
).
It would probably be significantly easier if the jre you want to use is integrated into the OS; it saves having to futz around with the PATH, and would survive upgrades to java, which would alter the path, requiring an update to the service definition - there's a pretty good guide here as to how to install it, system integrated:
- Download rpm
wget --no-check-certificate -c --header "Cookie: oraclelicense=accept-securebackup-cookie" https://download.oracle.com/otn-pub/java/jdk/14.0.2+12/205943a0976c4ed48cb16f1043c5c647/jdk-14.0.2_linux-x64_bin.rpm
- Install locally
yum localinstall jdk-14.0.2_linux-x64_bin.rpm
- Use
alternatives
to configure javaalternatives --config java
- Check after setting
java -version
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论