Home > Software engineering >  NoSuchMethodError Exception causing service to not receive subsequent REST calls
NoSuchMethodError Exception causing service to not receive subsequent REST calls

Time:04-23

I'm facing this issue for the first time, here's the exception that gets thrown in the service

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)

and once this exception is thrown, the service stops receiving the subsequent api calls made to the service ( even though i have caught the exception ) , pod is still in running state. I'm curious about two things here

  1. The exception that gets thrown, how to fix that ? Change in POM file?
  2. Why would the exception that has been caught would stop service from receiving further REST api calls. Basically after the exception , all the apis in service start timing out.

Below is the piece of code where exception gets thrown

at this line

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

and here's the loadDefaultObject from message method

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

CodePudding user response:

NoSuchMethodError is an Error (not an Exception) that occurs when the classpath during compilation differs from the classpath at runtime.

It says: I could find that method during compilation, but I can't find that method now at runtime.

It typically occurs when the runtime classpath differs from the compilation classpath. This gets more complex if your project A depends on jar B which depends on jar C. Presume all three projects (A, B and C) are compiled/released at a different time.

Start with doing mvn dependency:tree on your project. Ask the verbose version of that. One typical cause is dependency versions overrides with a lower version. For example your project A depends on C 1.2 and B 3.0 but B 3.0 depends on C 1.4. What if B was compiled using a method of C that only exists since C 1.3? When B is run in project A with C 1.2 instead of C 1.4, it doesn't find that method and NoSuchMethodError is thrown.

Note: there is an enforcer rule to enforce not downgrading transitive dependencies. It's very useful to avoid such surprises at runtime.

  • Related