NoSuchMethodError 导致服务无法接收后续 REST 调用的异常

NoSuchMethodError Exception causing service to not receive subsequent REST calls

我第一次遇到这个问题,这是服务中抛出的异常

Exception in thread "Thread-1" java.lang.NoSuchMethodError: org.codehaus.jackson.type.JavaType.<init>(Ljava/lang/Class;)V
    at org.codehaus.jackson.map.type.TypeBase.<init>(TypeBase.java:13)
    at org.codehaus.jackson.map.type.SimpleType.<init>(SimpleType.java:45)
    at org.codehaus.jackson.map.type.SimpleType.<init>(SimpleType.java:40)
    at org.codehaus.jackson.map.type.TypeFactory._fromClass(TypeFactory.java:374)
    at org.codehaus.jackson.map.type.TypeFactory._fromType(TypeFactory.java:434)
    at org.codehaus.jackson.map.type.TypeFactory.type(TypeFactory.java:61)
    at org.codehaus.jackson.map.ObjectMapper.<clinit>(ObjectMapper.java:174)
    at com.kx.proto.validation.util.Common.<clinit>(Common.java:41)

并且一旦抛出此异常,服务将停止接收对该服务进行的后续 api 调用(即使我已捕获异常),pod 仍处于 运行 状态。 我对这里的两件事很好奇

  1. 抛出异常,如何解决? POM 文件有变化吗?
  2. 为什么已捕获的异常会阻止服务接收进一步的 REST api 调用。基本上在异常之后,服务中的所有 apis 开始超时。

下面是抛出异常的代码

在这一行

        GeneratedMessageV3 messageV3 = Common.loadDefaultObjectFromMessage("com.kx.proto.", recordId.toUpperCase() + "Record");

这里是来自消息方法的 loadDefaultObject

  public static GeneratedMessageV3 loadDefaultObjectFromMessage(String pkg, String messageName) {
        try {
            Class<?> record = Class.forName(pkg + messageName);
            Optional<Method> getDefaultInstance = Arrays.asList(record.getDeclaredMethods()).stream().filter((method) -> {
                return method.getName().equals("getDefaultInstance");
            }).findFirst();
            if (getDefaultInstance.isPresent()) {
                Object obj = ((Method)getDefaultInstance.get()).invoke((Object)null, (Object[])null);
                return (GeneratedMessageV3)obj;
            }
        } catch (ClassNotFoundException var5) {
            System.out.println("class not found " + var5.getMessage());
        } catch (Exception var6) {
            var6.printStackTrace();
        }

        return null;
    }

NoSuchMethodError 是编译期间的类路径与 运行 时的类路径不同时发生的错误(不是异常)。

它说:我在编译时可以找到那个方法,但是我现在运行时找不到那个方法了。

通常在运行时间类路径与编译类路径不同时发生。如果您的项目 A 依赖于 jar B,而 jar B 又依赖于 jar C,这将变得更加复杂。假设所有三个项目(A、B 和 C)在不同的时间 compiled/released。

开始对您的项目进行mvn dependency:tree。询问那个的详细版本。 一个典型的原因是依赖版本被较低版本覆盖。例如,您的项目 A 依赖于 C 1.2 和 B 3.0,但 B 3.0 依赖于 C 1.4。如果 B 是使用自 C 1.3 以来才存在的 C 方法编译的怎么办?当 B 在项目 A 中使用 C 1.2 而不是 C 1.4 时 运行,它找不到该方法并抛出 NoSuchMethodError。

注意:有一个执行器规则来强制不降级传递依赖项。在 运行 时间避免此类意外非常有用。