log4j更改配置单元后,-e返回对脚本有影响的其他警告- WARN JNDI查找类不可用,因为此JRE

vwkv1x7d  于 2022-11-06  发布在  其他
关注(0)|答案(2)|浏览(75)

在项目中,我们使用Python中的一些技术脚本,使用Subprocess从hive中提取一些数据,运行msck修复表等(我知道我们应该切换到beeline:p),不幸的是,在每个输出中出现log4j问题后,我们开始得到这样的结果:
警告JNDI查找类不可用,因为此JRE不支持JNDI。JNDI字符串查找将不可用,继续配置。忽略java.lang.ClassNotFoundException:org.apache.logging.log4j.core.lookup.JndiLookup
到目前为止,我们的Infra团队还不允许我们对log4j属性进行任何更改。
由于我们有多个技术脚本在许多地方,我们希望找到一个简单的解决方案的时间(直到我们可以修复它的基础设施水平)。
已尝试:使用hive -s设置hive.root.looger到控制台(我认为不知何故log4j不理解这是警告)
伙计们,有人知道我们如何修复它吗(最好是在运行时)
谢谢你!

eimct9ow

eimct9ow1#

解决这个问题的一个方法是用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

huus2vyu

huus2vyu2#

我查看了JndiLookup.java从2.0版到2.14.1版的变化(就在2.15发行版之前)。没有重大的变化。无论您的应用程序使用的是什么log4j2版本,您都可以创建一个JndiLookup.java模拟类,在调用JndiLookup.lookup时只调用LOGGER.warn,而不调用其他任何内容。然后,您可以替换JndiLookup。类将加载,但除了给予你一个可以在应用程序日志中监视的日志消息外,没有任何意义,如果这样做会增加价值的话。

$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;
     }
 }

相关问题