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 仍处于 运行 状态。
我对这里的两件事很好奇
- 抛出异常,如何解决? POM 文件有变化吗?
- 为什么已捕获的异常会阻止服务接收进一步的 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。
注意:有一个执行器规则来强制不降级传递依赖项。在 运行 时间避免此类意外非常有用。
我第一次遇到这个问题,这是服务中抛出的异常
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 仍处于 运行 状态。 我对这里的两件事很好奇
- 抛出异常,如何解决? POM 文件有变化吗?
- 为什么已捕获的异常会阻止服务接收进一步的 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。
注意:有一个执行器规则来强制不降级传递依赖项。在 运行 时间避免此类意外非常有用。