mercredi 23 décembre 2020

NullPointerException can't figure out

Recently I encounted a NullPointerException issue from a third party jar, still can't figure out how it happened after I dig into the code. Here is the error stacktraces

java.lang.NullPointerException
 at com.fasterxml.jackson.databind.introspect.AnnotatedCreatorCollector._findPotentialFactories(AnnotatedCreatorCollector.java:183)
 at com.fasterxml.jackson.databind.introspect.AnnotatedCreatorCollector.collect(AnnotatedCreatorCollector.java:57)
 at com.fasterxml.jackson.databind.introspect.AnnotatedCreatorCollector.collectCreators(AnnotatedCreatorCollector.java:47)
 at com.fasterxml.jackson.databind.introspect.AnnotatedClass._creators(AnnotatedClass.java:381)
 at com.fasterxml.jackson.databind.introspect.AnnotatedClass.getFactoryMethods(AnnotatedClass.java:293)
 at com.fasterxml.jackson.databind.introspect.BasicBeanDescription.getFactoryMethods(BasicBeanDescription.java:534)
 at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._addDeserializerFactoryMethods(BasicDeserializerFactory.java:852)
 at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._constructDefaultValueInstantiator(BasicDeserializerFactory.java:349)
 at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:269)
 at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.createCollectionDeserializer(BasicDeserializerFactory.java:1222)
 at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:399)
 at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:349)
 at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)

it says the npe happen in line 183 of class AnnotatedCreatorCollector, here is the code and line num of AnnotatedCreatorCollector

177    private List<AnnotatedMethod> _findPotentialFactories(JavaType type, Class<?> primaryMixIn)
178    {
179        List<Method> candidates = null;
180
181        // First find all potentially relevant static methods
182        for (Method m : ClassUtil.getClassMethods(type.getRawClass())) {
183            if (!Modifier.isStatic(m.getModifiers())) {
184                continue;
185            }
186            // all factory methods are fine:
187            //int argCount = m.getParameterTypes().length;
188            if (candidates == null) {
189                candidates = new ArrayList<>();
190            }
191            candidates.add(m);
192        }

The only cercumstance I can imagine this npe will happen is the local variable 'm' is null, then I dig into the class ClassUtil and it goes

    public static Method[] getClassMethods(Class<?> cls)
    {
        try {
            return ClassUtil.getDeclaredMethods(cls);
        } catch (final NoClassDefFoundError ex) {
            // One of the methods had a class that was not found in the cls.getClassLoader.
            // Maybe the developer was nice and has a different class loader for this context.
            final ClassLoader loader = Thread.currentThread().getContextClassLoader();
            if (loader == null){
                // Nope... this is going to end poorly
                throw ex;
            }
            final Class<?> contextClass;
            try {
                contextClass = loader.loadClass(cls.getName());
            } catch (ClassNotFoundException e) {
                ex.addSuppressed(e);
                throw ex;
            }
            return contextClass.getDeclaredMethods(); // Cross fingers
        }
    }
    public static Method[] getDeclaredMethods(Class<?> cls) {
        return cls.getDeclaredMethods();
    }

I can see ClassUtil return an methods array using java reflection, but I think it's impossible that the array contain a null object, then I got stuck.

Here is my code

public class JsonUtil
{
...
  public static <T> T strToObj(String str, Class<T> clazz)
  {
    try
    {
      ObjectMapper objectMapper = new ObjectMapper();
      return objectMapper.readValue(str, clazz);
    } catch (JsonParseException e) {
      e.printStackTrace();
    } catch (JsonMappingException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return null;
  }
...
}




Aucun commentaire:

Enregistrer un commentaire