问题
下面是运行报错
Job for tomcat.service failed because the control process exited with error code. See “systemctl status tomcat.service” and “journalctl -xe” for details.
tomcat.service - Tomcat
Loaded: loaded (/usr/lib/systemd/system/tomcat.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Fri 2024-01-12 17:26:13 CST; 44s ago
Process: 20250 ExecStart=/usr/local/bin/apache-tomcat-8.5.87/bin/startup.sh (code=exited, status=1/FAILURE)
Main PID: 20250 (code=exited, status=1/FAILURE)
Jan 12 17:26:13 localhost.localdomain systemd[1]: Starting Tomcat…
Jan 12 17:26:13 localhost.localdomain startup.sh[20250]: Neither the JAVA_HOM…
Jan 12 17:26:13 localhost.localdomain startup.sh[20250]: At least one of thes…
Jan 12 17:26:13 localhost.localdomain systemd[1]: tomcat.service: main proces…
Jan 12 17:26:13 localhost.localdomain systemd[1]: Failed to start Tomcat.
Jan 12 17:26:13 localhost.localdomain systemd[1]: Unit tomcat.service entered…
Jan 12 17:26:13 localhost.localdomain systemd[1]: tomcat.service failed.
Hint: Some lines were ellipsized, use -l to show in full
原因
在 systemd 服务中,它会使用一个独立的环境,不会直接继承系统全局的环境变量设置。这就是为什么在 Tomcat systemd 服务中设置 JAVA_HOME 时,它并不会直接使用系统全局的 JAVA_HOME 变量的原因,全局变量在设置在/etc/profile文件中
export JAVA_HOME=/usr/local/bin/jdk1.8.0_171
export JRE_HOME=/usr/local/bin/jdk1.8.0_171/jre
export PATH=$JAVA_HOME/bin:$PATH
解决方案 一
单独加入 jdk 的环境变量
1 [Unit]
2 Description=Tomcat
3 After=syslog.target network.target remote-fs.target nss-lookup.target
4
5 [Service]
6 Type=oneshot
7 Environment=JAVA_HOME=/usr/local/bin/jdk1.8.0_171 #这里是单独加入的 jdk 环境变量
8 ExecStart=/usr/local/bin/apache-tomcat-8.5.87/bin/startup.sh
9 ExecStop=/usr/local/bin/apache-tomcat-8.5.87/bin/shutdown.sh
10 ExecReload=/bin/kill -s HUP $MAINPID
11 RemainAfterExit=yes
12
13 [Install]
14 WantedBy=multi-user.target
解决方案 二
建立 Java软链接
alternatives 是一种在类 Unix 系统中用于管理软件包的多个版本的工具。它允许系统管理员配置一个软件包的多个版本,并通过简单的命令来切换默认版本。这种方式允许用户在系统上安装多个版本的同一个软件包,并根据需要轻松切换它们。
在使用 alternatives 之前,一些软件包管理系统(如 yum、apt 等)可能会在安装软件包时自动配置软链接,将软件包的可执行文件链接到 /usr/bin 或其他系统路径。这样做的问题在于,只有一个版本的软件包可以存在于特定路径,而 alternatives 提供了一种更灵活的方式来管理多个版本。
以下是 alternatives 的基本用法:
- 安装软件包:
bash
sudo alternatives --install /usr/bin/java java /path/to/java1 1
sudo alternatives --install /usr/bin/java java /path/to/java2 2
这里,/path/to/java1 和 /path/to/java2 是不同版本的 Java 可执行文件,分别被关联到 /usr/bin/java(用户系统的可执行文件都在/usr/bin中,我这么理解,或者说这里存放的都是系统使用 yum 安装软件创建的软链接,总之它们都连接到可执行的文件,而且不需要再去单独配置环境变量)。
设置默认版本:
sudo alternatives --config java
这将提示你选择默认的 Java 版本。你可以从列表中选择,并根据需要切换默认版本。如果啥都没有,说明系统还没有建立 JAVA 的软链接。
手动切换版本:
sudo alternatives --set java /path/to/java1
这会手动将默认版本更改为指定的版本。
使用 alternatives 的好处在于,它提供了一种标准化的方法来处理软件包的多个版本,而不是依赖于系统路径中的特定软链接。这对于系统管理员和开发人员来说是一种方便的工具,可以轻松管理不同版本的软件。
如果你手动安装了软件,并且没有使用包管理工具(如 yum、apt 等),而是直接将可执行文件和相关文件放在特定目录,那么 alternatives 可能并不会直接管理你手动安装的软件。通常,手动安装的软件包可以通过直接设置系统环境变量或使用软链接来管理。
测试上面的操作
先贴个结果,这里删掉了方案一种加入的
Environment=JAVA_HOME=/usr/local/bin/jdk1.8.0_171
正常启动
接下来看看怎么操作的
alternatives --install命令的具体语法如下
sudo alternatives --install <link> <name> <path> <priority>
- link 软链接的路径,即在系统路径中创建的链接。
- name 在 alternatives 中注册的名称,用于识别和管理软件的不同版本。
- path 软件包的实际路径,即可执行文件所在的目录。
- priority 版本的优先级,数字越高表示优先级越高。
对于安装 Java 的例子
sudo alternatives --install /usr/bin/java java /path/to/java1 1
sudo alternatives --install /usr/bin/java java /path/to/java2 2
- /usr/bin/java:是软链接的路径,这是 alternatives 将创建的链接。
- java:是在 alternatives 中注册的名称,用于标识 Java 的不同版本。
- /path/to/java1 和 /path/to/java2:是不同版本的 Java 实际路径。
- 1 和 2是版本的优先级,1 表示较高的优先级。
你可以根据你手动安装的 Java 版本和路径,使用适当的值来替换 /path/to/java1 和 /path/to/java2,并确保优先级是适当的。这样设置后,你可以使用 sudo alternatives --config java 来选择默认的 Java 版本。
在 /usr/bin/java 这个路径下通常是一个符号链接(symbolic link),它指向实际的 Java 可执行文件。所以,/usr/bin/java 不是 java 可执行文件的实际路径,而是一个链接。/usr/bin/java 这个路径是系统约定的用于放置软链接的目录。
当你使用 alternatives 命令时,它会在 /usr/bin/ 目录下创建一个名为 java 的软链接,指向你指定的 Java 可执行文件的实际路径。
我这里是这样写的
sudo alternatives --install /usr/bin/java java /usr/local/bin/jdk1.8.0_171/bin/java 1
这就创建了 /usr/bin/java 的软链接,指向 /usr/local/bin/jdk1.8.0_171/bin/java 这个实际的 Java 可执行文件。
这种做法的好处在于,它允许你轻松地通过 alternatives 切换系统中的默认 Java 版本,而不必手动修改软链接。
如果你想查看 /usr/bin/java 的实际路径,你可以使用 readlink 命令:
readlink -f /usr/bin/java
这将显示 /usr/local/bin/jdk1.8.0_171/bin/java 或者它实际指向的路径。
如果 /usr/bin 目录下没有 java 这个文件,这可能意味着 alternatives 还没有为 java 创建软链接,或者该软链接被手动删除了。
你可以通过执行以下命令检查 alternatives 是否已经为 java 创建了软链接
sudo alternatives --display java
这会显示 java 的信息,包括软链接的路径。如果 java 未被设置,或者路径不正确,你可以使用 alternatives --install 重新创建
sudo alternatives --install /usr/bin/java java /usr/local/bin/jdk1.8.0_171/bin/java 1
如果软链接已经存在,但指向错误的路径,你可以使用 alternatives --config java 来选择正确的路径。
如果还有问题,你可以手动创建 java 软链接,使用以下命令
sudo ln -s /usr/local/bin/jdk1.8.0_171/bin/java /usr/bin/java
这将创建一个名为 java 的软链接,指向你的 Java 可执行文件。然后,你可以使用 alternatives --config java 来选择默认的 Java 版本。
删除软链接
sudo alternatives --remove java /usr/bin/java
另外,你可以通过执行以下命令来查看当前的 java 链接到哪个版本
readlink -f $(command -v java)
如果这显示了你安装的 Java 版本的路径(例如 /usr/local/bin/jdk1.8.0_171/bin/java),那么 java 命令已经正确链接到你期望的版本。
在这种情况下,删除 JAVA_HOME 和其他 Java 相关环境变量可能是安全的,因为系统已经通过 alternatives 管理了默认的 Java 版本。不过,在删除这些环境变量之前,最好确保系统和应用程序都不再需要它们。
你可以在终端中执行 java -version 来验证当前默认的 Java 版本。如果显示的版本是你预期的版本,而没有显示未找到 java 命令的错误,那么系统中已经正确设置了默认的 Java 版本,你可以考虑删除 JAVA_HOME 等环境变量。