title: Custom json serialization java primitives from kotlin by Jackson
body: <p>In my project there are java and kotlin modules. In some kotlin module I need a custom serialization. All long values should be serialized as string. I use Jackson. </p>
  
  <p>Example: </p>
  
  <p><strong>kotlin</strong> </p>
  
  <pre><code>data class KotlinRecord(val id: Long)
  </code></pre>
  
  <p><strong>java</strong></p>
  
  <pre><code>public class JavaRecord {
      private Long id;
  
      public Long getId() {
          return id;
      }
  
      public JavaRecord setId(Long id) {
          this.id = id;
          return this;
      }
  }
  </code></pre>
  
  <p>When ObjectMapper is configured in <strong>java</strong> module and I serialize value like this: </p>
  
  <pre><code> ObjectMapper mapper = new ObjectMapper()
              .registerModule(new KotlinModule())
              .registerModule(new JavaTimeModule())
              .registerModule(
                      new SimpleModule()
                              .addSerializer(Long.class, LongToStringJSONSerializer.ofObject())
                              .addSerializer(long.class, LongToStringJSONSerializer.ofPrimitive())
              );
  
  JavaRecord javaRecord = new JavaRecord().setId(Long.MAX_VALUE);
  KotlinRecord kotlinRecord = new KotlinRecord(Long.MAX_VALUE);
  
  System.out.println("Java record:   " + mapper.writeValueAsString(javaRecord));
  System.out.println("Kotlin record: " + mapper.writeValueAsString(kotlinRecord));
  </code></pre>
  
  <p>I get the following result: </p>
  
  <pre><code>Java record:   {"id":"9223372036854775807"}
  Kotlin record: {"id":"9223372036854775807"}
  </code></pre>
  
  <p>It's fine. That's what i need. </p>
  
  <p>But if I do the same in <strong>kotlin</strong> module like this: </p>
  
  <pre><code>val mapper = ObjectMapper()
          .registerModule(KotlinModule())
          .registerModule(JavaTimeModule())
          .registerModule(
                  SimpleModule()
                          .addSerializer(Long::class.java, LongToStringJSONSerializer.ofObject())
                          .addSerializer(Long::class.javaPrimitiveType, LongToStringJSONSerializer.ofPrimitive())
          )
  
  val javaRecord = JavaRecord().setId(Long.MAX_VALUE)
  val kotlinRecord = KotlinRecord(Long.MAX_VALUE)
  
  println("Java record:   ${mapper.writeValueAsString(javaRecord)}")
  println("Kotlin record: ${mapper.writeValueAsString(kotlinRecord)}")
  </code></pre>
  
  <p>I get: </p>
  
  <pre><code>Java record:   {"id":9223372036854775807}
  Kotlin record: {"id":"9223372036854775807"}
  </code></pre>
  
  <p>For record defined as java class long value wasn't conveted to string. </p>
  
  <p>My custom serializer: </p>
  
  <pre><code>public class LongToStringJSONSerializer extends JsonSerializer&lt;Long&gt; {
      private boolean forPrimitive;
  
      private LongToStringJSONSerializer(boolean forPrimitive) {
          this.forPrimitive = forPrimitive;
      }
  
      @Override
      public void serialize(Long longVal, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws
              IOException {
          jsonGenerator.writeObject(longVal == null ? "" : String.valueOf(longVal));
      }
  
      @Override
      public Class&lt;Long&gt; handledType() {
          return forPrimitive ? long.class : Long.class;
      }
  
      public static LongToStringJSONSerializer ofPrimitive() {
          return new LongToStringJSONSerializer(true);
      }
  
      public static LongToStringJSONSerializer ofObject() {
          return new LongToStringJSONSerializer(false);
      }
  } 
  </code></pre>
  
  <p>Can anyone explain this behavior and what needs to be done to fix it? Thanks! </p>