FasterXML / FasterXML/jackson-module-scala

Custom serializer with type information and yaml output

Open
#192 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Scala
Stars
506
Forks
138
Avg merge
3h 6m
Merged PRs (30d)
48

Description

Hi, I'm trying to write a custom serializer for an Nd4j array (see http://nd4j.org). I was about to get it working with json but when I try yaml output I get an exception:

``` scala
Cause: com.fasterxml.jackson.dataformat.yaml.snakeyaml.emitter.EmitterException: expected NodeEvent, but got
at com.fasterxml.jackson.dataformat.yaml.snakeyaml.emitter.Emitter.expectNode(Emitter.java:409)
at com.fasterxml.jackson.dataformat.yaml.snakeyaml.emitter.Emitter.access$1600(Emitter.java:63)
at com.fasterxml.jackson.dataformat.yaml.snakeyaml.emitter.Emitter$ExpectBlockMappingValue.expect(Emitter.java:651)
at com.fasterxml.jackson.dataformat.yaml.snakeyaml.emitter.Emitter.emit(Emitter.java:217)
at com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.close(YAMLGenerator.java:308)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3398)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:2779)
```

In order to simplify the test I created dummy classes for `Nd4j` so I know the issue is not specific to that package. This test case:

``` scala
import com.fasterxml.jackson.databind.JsonSerializer
//import org.nd4j.linalg.api.ndarray.INDArray
import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.databind.SerializerProvider
//import org.nd4j.linalg.api.buffer.DataBuffer
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.fasterxml.jackson.databind.jsontype.TypeSerializer
//import org.nd4j.linalg.factory.Nd4j
import com.fasterxml.jackson.annotation.JsonTypeInfo
import org.scalatest.FunSuite

// Dummy INDArray
class INDArray {
val _data = new DataBuffer
def shape() = Array[Int](1, 3)
def data = _data
def ordering() = 'f'
}

// Dummy DataBuffer
class DataBuffer {
def dataType = 1
def asBytes() = Array[Byte](1, 2, 3)
}

// Custom serializer for INDArray
class NDArraySerializer extends JsonSerializer[INDArray] {

def serialize(
value: INDArray,
jgen: JsonGenerator,
provider: SerializerProvider) {

jgen.writeStartObject()

jgen.writeArrayFieldStart("shape")
for (i <- value.shape()) jgen.writeNumber(i)
jgen.writeEndArray()

val dtype =
if (value.data.dataType == 1 /*DataBuffer.FLOAT*/ )
"float"
else
"double"
jgen.writeStringField("dtype", dtype)

jgen.writeStringField("order", value.ordering().toString())

jgen.writeBinaryField("data", value.data.asBytes())

jgen.writeEndObject()
}

override def serializeWithType(
value: INDArray,
jgen: JsonGenerator,
provider: SerializerProvider,
typeSer: TypeSerializer) {

typeSer.writeTypePrefixForObject(value, jgen)
serialize(value, jgen, provider)
typeSer.writeTypeSuffixForObject(value, jgen)
}
}

class TestYAML extends FunSuite {

test("yaml") {

try {
val nd4jModule = new SimpleModule()

nd4jModule.addSerializer(classOf[INDArray], new NDArraySerializer())

val jsonMapper = new ObjectMapper

jsonMapper.registerModule(DefaultScalaModule)

jsonMapper.registerModule(nd4jModule)

jsonMapper.enableDefaultTyping(
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.PROPERTY)

val yamlMapper = new ObjectMapper(new YAMLFactory)

yamlMapper.registerModule(DefaultScalaModule)

yamlMapper.registerModule(nd4jModule)

yamlMapper.enableDefaultTyping(
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.PROPERTY)

val array = new INDArray

jsonMapper.writeValueAsString(array)

yamlMapper.writeValueAsString(array)
}
catch {
case e: Throwable => fail("shouldn't throw an exception.", e)
}
}
}

```

If I comment out the `enableDefaultTyping` call it works.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.