title: Statically defined KeyDeserializer not found but if defined locally everything perfect
body: <p>I am baffled by how registering a custom <code>KeyDeserializer</code> works.</p>
  
  <p>Here is my code:</p>
  
  <h2>Matchday.java</h2>
  
  <pre><code>package com.example;
  
  import java.io.Serializable;
  import java.util.Objects;
  
  public class Matchday implements Serializable, Comparable&lt;Matchday&gt; {
      private static final long serialVersionUID = -8823049187525703664L;
  
      private final int matchdayNumber;
  
      public Matchday(final int matchdayNumber) {
          this.matchdayNumber = matchdayNumber;
      }
  
      public int getMatchdayNumber() {
          return matchdayNumber;
      }
  
      @Override
      public int compareTo(Matchday o) {
          return Integer.compare(matchdayNumber, o.getMatchdayNumber());
      }
  
      @Override
      public final int hashCode() {
          return Objects.hash(matchdayNumber);
      }
  
      @Override
      public final boolean equals(final Object obj) {
          return obj instanceof Matchday &amp;&amp; Integer.valueOf(matchdayNumber).equals(((Matchday) obj).matchdayNumber);
      }
  
      @Override
      public String toString() {
          return Integer.toString(matchdayNumber);
      }
  }
  </code></pre>
  
  <h2>TeamPlayer.java</h2>
  
  <pre><code>package com.example;
  
  import java.io.Serializable;
  
  import org.apache.commons.lang3.builder.ToStringBuilder;
  
  public class TeamPlayer implements Serializable {
      private static final long serialVersionUID = -6057852081020631549L;
  
      private int id;
      private String name;
      private String surname;
  
      public int getId() {
          return id;
      }
  
      public void setId(int id) {
          this.id = id;
      }
  
      public String getName() {
          return name;
      }
  
      public void setName(String name) {
          this.name = name;
      }
  
      public String getSurname() {
          return surname;
      }
  
      public void setSurname(String surname) {
          this.surname = surname;
      }
  
      @Override
      public String toString() {
          return new ToStringBuilder(this).append("id", id).append("name", name).append("surname", surname).build()
                  .toString();
      }
  }
  </code></pre>
  
  <p>Now if I define a custom map key deserializer for my class Matchday.java, it works like a charm if I do it like this.</p>
  
  <h2>KeyDeserializerTest.java</h2>
  
  <pre><code>package com.example;
  
  import java.io.ByteArrayInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.util.List;
  import java.util.SortedMap;
  
  import com.fasterxml.jackson.core.JsonProcessingException;
  import com.fasterxml.jackson.core.Version;
  import com.fasterxml.jackson.core.type.TypeReference;
  import com.fasterxml.jackson.databind.DeserializationContext;
  import com.fasterxml.jackson.databind.KeyDeserializer;
  import com.fasterxml.jackson.databind.ObjectMapper;
  import com.fasterxml.jackson.databind.module.SimpleModule;
  
  public class KeyDeserializerTest {
  
      public static void main(String[] args) throws IOException {
          final ObjectMapper objectMapper = new ObjectMapper();
          final SimpleModule mySimpleModule = new SimpleModule("dummy", new Version(0, 0, 0, "dummy", "dummy", "dummy"));
          mySimpleModule.addKeyDeserializer(Matchday.class, new KeyDeserializer() {
  
              @Override
              public Object deserializeKey(String arg0, DeserializationContext arg1)
                      throws IOException, JsonProcessingException {
                  return new Matchday(Integer.valueOf(arg0));
              }
          });
          objectMapper.registerModule(mySimpleModule);
  
          final InputStream inputStream = new ByteArrayInputStream(
                  "{\"1\":[{\"id\": 1, \"name\": \"Arkadiusz\", \"surname\": \"Malarz\"}]}".getBytes());
          SortedMap&lt;Matchday, List&lt;TeamPlayer&gt;&gt; map = objectMapper.readValue(inputStream,
                  new TypeReference&lt;SortedMap&lt;Matchday, List&lt;TeamPlayer&gt;&gt;&gt;() {
                  });
          System.out.println(map);
      }
  
  }
  </code></pre>
  
  <p>It prints</p>
  
  <pre><code>{1=[com.example.TeamPlayer@3a8624[id=1,name=Arkadiusz,surname=Malarz]]}
  </code></pre>
  
  <p>But if I define both the object mapper and my deserializer instances as static attributes then I get the following exception!</p>
  
  <h2>KeyDeserializerStaticTest.java</h2>
  
  <pre><code>package com.example;
  
  import java.io.ByteArrayInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.util.List;
  import java.util.SortedMap;
  
  import com.fasterxml.jackson.core.JsonProcessingException;
  import com.fasterxml.jackson.core.Version;
  import com.fasterxml.jackson.core.type.TypeReference;
  import com.fasterxml.jackson.databind.DeserializationContext;
  import com.fasterxml.jackson.databind.KeyDeserializer;
  import com.fasterxml.jackson.databind.Module;
  import com.fasterxml.jackson.databind.ObjectMapper;
  import com.fasterxml.jackson.databind.module.SimpleModule;
  
  public class KeyDeserializerStaticTest {
      public static final ObjectMapper OBJECT_MAPPER = createObjectMapper();
  
      private static final KeyDeserializer MATCHDAY_KEY_DESERIALIZER = new KeyDeserializer() {
  
          @Override
          public Object deserializeKey(String key, DeserializationContext ctxt)
                  throws IOException, JsonProcessingException {
              return new Matchday(Integer.valueOf(key));
          }
      };
  
      private static ObjectMapper createObjectMapper() {
          ObjectMapper objectMapper = new ObjectMapper();
          objectMapper.registerModule(createSimpleModule());
          return objectMapper;
      }
  
      private static Module createSimpleModule() {
          SimpleModule simpleModule = new SimpleModule("dummy", new Version(0, 0, 0, "dummy", "dummy", "dummy"));
          simpleModule.addKeyDeserializer(Matchday.class, MATCHDAY_KEY_DESERIALIZER);
          return simpleModule;
      }
  
      public static void main(String[] args) throws IOException {
          final InputStream inputStream = new ByteArrayInputStream(
                  "{\"1\":[{\"id\": 1, \"name\": \"Arkadiusz\", \"surname\": \"Malarz\"}]}".getBytes());
          SortedMap&lt;Matchday, List&lt;TeamPlayer&gt;&gt; map = OBJECT_MAPPER.readValue(inputStream,
                  new TypeReference&lt;SortedMap&lt;Matchday, List&lt;TeamPlayer&gt;&gt;&gt;() {
                  });
          System.out.println(map);
      }
  }
  </code></pre>
  
  <pre class="lang-none prettyprint-override"><code>Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class com.example.Matchday]
   at [Source: java.io.ByteArrayInputStream@bbc1e0; line: 1, column: 1]
      at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
      at com.fasterxml.jackson.databind.DeserializationContext.reportMappingException(DeserializationContext.java:1234)
      at com.fasterxml.jackson.databind.deser.DeserializerCache._handleUnknownKeyDeserializer(DeserializerCache.java:585)
      at com.fasterxml.jackson.databind.deser.DeserializerCache.findKeyDeserializer(DeserializerCache.java:168)
      at com.fasterxml.jackson.databind.DeserializationContext.findKeyDeserializer(DeserializationContext.java:499)
      at com.fasterxml.jackson.databind.deser.std.MapDeserializer.createContextual(MapDeserializer.java:247)
      at com.fasterxml.jackson.databind.DeserializationContext.handleSecondaryContextualization(DeserializationContext.java:681)
      at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:481)
      at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:3899)
      at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3794)
      at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2915)
      at com.example.KeyDeserializerStaticTest.main(KeyDeserializerStaticTest.java:43)
  </code></pre>
  
  <p>What is wrong here? Semantically there is no difference between the above presented main methods. Is this a feature that is somewhere documented or is it simply a bug in Jackson?</p>