问题说明:
上图的·错误信息 SLF4J: Class path contains multiple SLF4J bindings 表明我的类路径中存在多个 SLF4J(Simple Logging Facade for Java,即 Java 简单日志门面)实现。SLF4J 是一个为各种日志框架提供的门面或抽象层,它被设计为同一时间只能有一个绑定。当发现多个绑定时,可能会导致日志记录出现意外行为。
解决方案:
A、手动删除冲突的 JAR 文件来解决 SLF4J 多绑定问题
方案A:
如果你没有使用构建工具,或者更倾向于手动操作,你可以从类路径中物理移除其中一个冲突的 JAR 文件。
类似我的情况的,可以选择移除 Hive 库目录(
/opt/hive/lib/
)中的log4j - slf4j - impl - 2.10.0.jar
,或者移除 Hadoop 公共库目录(/usr/local/hadoop/share/hadoop/common/lib/
)中的slf4j - log4j12 - 1.7.10.jar
。在移除之前,要确保了解其影响。
先运行下面的代码
##先删除这个依赖项,看能否看到hive的版本号
rm /opt/hive/lib/log4j-slf4j-impl-2.10.0.jar
##我是把hive安装在/opt/下,这里替换成自己的安装目录
1. 删除 Hadoop 中的冲突文件
如果你已经决定删除 Hadoop 中的 slf4j - log4j12 - 1.7.10.jar 文件,可按如下步骤操作:
步骤一:确认文件路径和存在性
首先,要确保该文件确实存在于指定路径。你可以使用以下命令进行确认:
ls /usr/local/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.10.jar
如果文件存在,会显示该文件的名称;若不存在,会提示 “没有该文件或目录” 的错误信息。
步骤二:备份文件(可选但推荐)
在删除文件之前,最好先进行备份,这样如果后续发现删除文件导致了其他问题,还可以恢复。使用以下命令备份文件:
sudo cp /usr/local/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.10.jar /usr/local/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.10.jar.bak
此命令会在同一目录下创建一个以 .bak 结尾的备份文件。
步骤三:删除文件
使用 rm 命令删除文件,由于该文件位于系统目录,可能需要管理员权限,所以可能要使用 sudo:
sudo rm /usr/local/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.10.jar
执行此命令后,输入你的用户密码,确认权限,文件就会被删除。
2. 删除 Hive 中的冲突文件
如果你选择删除 Hive 中的 log4j - slf4j - impl - 2.10.0.jar 文件,操作步骤类似:
步骤一:确认文件路径和存在性
ls /opt/hive/lib/log4j-slf4j-impl-2.10.0.jar
步骤二:备份文件(可选但推荐)
sudo cp /opt/hive/lib/log4j-slf4j-impl-2.10.0.jar /opt/hive/lib/log4j-slf4j-impl-2.10.0.jar.bak
步骤三:删除文件
sudo rm /opt/hive/lib/log4j-slf4j-impl-2.10.0.jar
3. 验证删除结果
删除文件后,你可以再次使用 ls 命令验证文件是否已被成功删除:
步骤一:验证 Hadoop 中的文件
ls /usr/local/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.10.jar
步骤二:验证 Hive 中的文件
ls /opt/hive/lib/log4j-slf4j-impl-2.10.0.jar
如果文件已被成功删除,这两个命令都会提示 “没有该文件或目录”。之后,重新启动你的应用程序,查看 SLF4J 多绑定的错误是否已经解决。
B、排除不必要的依赖
如果你想通过排除不必要的依赖来解决 SLF4J 多绑定问题,需要根据你启动 Hive 的方式来选择合适的方法。通常情况下,我们可以使用 Maven 或 Gradle 这类构建工具进行依赖排除,如果不是通过构建工具启动 Hive,也可以从配置文件角度来解决。以下是不同场景下的具体操作方法:如果你使用的是像 Maven 或 Gradle 这样的构建工具,你可以排除冲突的依赖项。
1.Maven 示例:
如果你是在 Maven 项目中集成 Hive 并遇到这个问题,可以在 pom.xml
文件中排除冲突的依赖。一般 Hive 和 Hadoop 的依赖会被引入到项目中,我们可以对 Hadoop 依赖进行处理,排除其中的 slf4j-log4j12
依赖。示例代码如下:
<dependencies>
<!-- Hive 依赖 -->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>3.1.0</version>
</dependency>
<!-- Hadoop 依赖,排除冲突的 SLF4J 绑定 -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>你的 Hadoop 版本</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
在上述代码中,我们在 hadoop-common
依赖里添加了 <exclusions>
标签,将 slf4j-log4j12
依赖排除。这样在项目运行时,就不会同时存在两个冲突的 SLF4J 绑定。
2.Gradle 示例:
如果你使用的是 Gradle 项目,可以在 build.gradle
文件中对依赖进行排除。同样是对 Hadoop 依赖进行处理,示例代码如下:
dependencies {
// Hive 依赖
implementation 'org.apache.hive:hive-exec:3.1.0'
// Hadoop 依赖,排除冲突的 SLF4J 绑定
implementation('org.apache.hadoop:hadoop-common:你的 Hadoop 版本') {
exclude group: 'org.slf4j', module: 'slf4j-log4j12'
}
}
在这个示例中,我们在 hadoop-common
的依赖配置里使用 exclude
语句排除了 slf4j-log4j12
依赖,避免了多绑定问题。
3. 非构建工具启动 Hive
如果你不是通过 Maven 或 Gradle 这类构建工具启动 Hive,而是直接在服务器上运行 Hive 脚本,那么可以通过修改启动脚本或者配置文件来排除不必要的依赖。
a.修改 Hive 启动脚本
你可以编辑 Hive 的启动脚本(通常是 $HIVE_HOME/bin/hive
),在脚本中移除对冲突 JAR 文件的引用。不过这种方法比较复杂,需要对脚本有一定的了解。
b.修改 Hadoop 配置文件
在 Hadoop 的配置文件(如 $HADOOP_HOME/etc/hadoop/hadoop-env.sh
)中,尝试移除或者注释掉与 slf4j-log4j12
相关的类路径配置。但这种方法可能会影响 Hadoop 的正常运行,需要谨慎操作。
验证修改结果
完成上述修改后,重新启动 Hive 并查询版本号,检查是否还存在 SLF4J 多绑定的错误信息:
hive --version
如果错误信息消失,说明你已经成功解决了 SLF4J 多绑定问题。