log4j更改后,Hive-e返回对脚本有影响的附加警告-WARN JNDI查找类不可用,因为此JRE



在项目中,我们使用python中的一些技术脚本和Subprocess从hive中提取一些数据,运行msck修复表等(我知道我们应该切换到beeline:p(不幸的是,在每个输出中出现log4j问题后,我们开始得到这样的东西:

WARN JNDI查找类不可用,因为此JRE不支持JNDI。JNDI字符串查找将不可用,继续配置。忽略java.lang.ClassNotFoundException:org.apache.logging.log4j.core.lockup.JndiLookup

到目前为止,我们的Infra团队不允许我们对log4j属性进行任何更改。

由于我们在许多地方都有多个技术脚本,我们暂时希望找到简单的解决方案(直到我们能够在基础设施级别上解决它(。

已尝试:使用情况配置单元-s将hive.root.looger设置为控制台(我认为log4j不知何故不理解这是警告(

伙计们,有人知道我们如何修复它吗(最好是在运行时(

谢谢!

解决此问题的一种方法是用削弱版本的JndiLookup修补log4j-core,而不是用zip -d ...完全删除该类。该类的一个简单版本可能看起来像这样:

package org.apache.logging.log4j.core.lookup;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
@Plugin(name = "jndi", category = StrLookup.CATEGORY)
public class JndiLookup extends AbstractLookup {
@Override
public String lookup(final LogEvent event, final String key) {
return null;
}
}

以下是自动化编译和替换过程的bash脚本的要点:

https://gist.github.com/xyu/348e9cecf25e09bef997a58e1901481b

我查看了JndiLookup.java从2.0版到2.14.1版(就在2.15版本之前(引入了哪些更改。没有重大变化。无论您的应用程序使用的是哪种log4j2版本,它都会出现。您可以创建一个JndiLookup.java模拟类,该类只需调用LOGGER.warn,而在调用JndiLookup.lookup时不调用其他类。然后,您将替换JndiLookup.class,而不是将其从jar中删除。该类将加载,但除了向您提供一条可以在应用程序日志中监视的日志消息之外,没有任何意义,如果这样做会增加价值的话。

$git diff rel/2.0 rel/2.14.1 log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java
index 77749e015..30e65ad24 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java
@@ -16,53 +16,47 @@
*/
package org.apache.logging.log4j.core.lookup;

-import javax.naming.Context;
-import javax.naming.InitialContext;
+import java.util.Objects;
+
import javax.naming.NamingException;

+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
-import org.apache.logging.log4j.core.util.Closer;
+import org.apache.logging.log4j.core.net.JndiManager;
+import org.apache.logging.log4j.status.StatusLogger;

/**
* Looks up keys from JNDI resources.
*/
-@Plugin(name = "jndi", category = "Lookup")
-public class JndiLookup implements StrLookup {
+@Plugin(name = "jndi", category = StrLookup.CATEGORY)
+public class JndiLookup extends AbstractLookup {

-    /** JNDI resourcce path prefix used in a J2EE container */
-    static final String CONTAINER_JNDI_RESOURCE_PATH_PREFIX = "java:comp/env/";
+    private static final Logger LOGGER = StatusLogger.getLogger();
+    private static final Marker LOOKUP = MarkerManager.getMarker("LOOKUP");

-    /**
-     * Looks up the value of the JNDI resource.
-     * @param key  the JNDI resource name to be looked up, may be null
-     * @return The value of the JNDI resource.
-     */
-    @Override
-    public String lookup(final String key) {
-        return lookup(null, key);
-    }
+    /** JNDI resource path prefix used in a J2EE container */
+    static final String CONTAINER_JNDI_RESOURCE_PATH_PREFIX = "java:comp/env/";

/**
* Looks up the value of the JNDI resource.
* @param event The current LogEvent (is ignored by this StrLookup).
* @param key  the JNDI resource name to be looked up, may be null
-     * @return The value of the JNDI resource.
+     * @return The String value of the JNDI resource.
*/
@Override
public String lookup(final LogEvent event, final String key) {
if (key == null) {
return null;
}
-
-        Context ctx = null;
-        try {
-            ctx = new InitialContext();
-            return (String) ctx.lookup(convertJndiName(key));
+        final String jndiName = convertJndiName(key);
+        try (final JndiManager jndiManager = JndiManager.getDefaultManager()) {
+            return Objects.toString(jndiManager.lookup(jndiName), null);
} catch (final NamingException e) {
+            LOGGER.warn(LOOKUP, "Error looking up JNDI resource [{}].", jndiName, e);
return null;
-        } finally {
-            Closer.closeSilently(ctx);
}
}

@@ -73,11 +67,10 @@ public class JndiLookup implements StrLookup {
* @param jndiName The name of the resource.
* @return The fully qualified name to look up.
*/
-    private String convertJndiName(String jndiName) {
+    private String convertJndiName(final String jndiName) {
if (!jndiName.startsWith(CONTAINER_JNDI_RESOURCE_PATH_PREFIX) && jndiName.indexOf(':') == -1) {
-            jndiName = CONTAINER_JNDI_RESOURCE_PATH_PREFIX + jndiName;
+            return CONTAINER_JNDI_RESOURCE_PATH_PREFIX + jndiName;
}
-
return jndiName;
}
}

最新更新