javajsonjsonb-api

JSON-B hitting NPE serializing with adapter though setting withNullValues(true)


Problem

The JSON-B user guide suggests here that I should be able to serialize null values with my code of:

    Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()
            .withNullValues(true)
            .withAdapters(new StatusAdapter()));

    jsonb.toJson(status,Status.class);

Here StatusAdapter is my own JsonbAdapter impl to serialize the app's Status class and looks something like this:

StatusAdapter

@Override
public JsonObject adaptToJson(Status status) throws Exception {

   // ... 

   return Json.createObjectBuilder()

            .add("field1", status.getField1())               
            .add("field2", status.getField2())               

             // ... continues ...

            .build();

But when one of these getters returns null, I end up getting exceptions like:

Caused by: java.lang.NullPointerException: Value in JsonObjects name/value pair cannot be null at org.glassfish.json.JsonObjectBuilderImpl.validateValue(JsonObjectBuilderImpl.java:222) at org.glassfish.json.JsonObjectBuilderImpl.add(JsonObjectBuilderImpl.java:90) at mypkg.StatusAdapter.adaptToJson(StatusAdapter.java:47) at mypkg.StatusAdapter.adaptToJson(StatusAdapter.java:14) at org.eclipse.yasson.internal.serializer.AdaptedObjectSerializer.serialize(AdaptedObjectSerializer.java:103)

pom.xml

I used the latest versions of the Maven dependencies from the JSON-B Getting Started page:

            <dependency>
                    <groupId>javax.json.bind</groupId>
                    <artifactId>javax.json.bind-api</artifactId>
                    <version>1.0</version>
            </dependency>

            <dependency>
                    <groupId>org.eclipse</groupId>
                    <artifactId>yasson</artifactId>
                    <version>1.0.2</version>
            </dependency>

            <dependency>
                    <groupId>org.glassfish</groupId>
                    <artifactId>javax.json</artifactId>
                    <version>1.1.3</version>
            </dependency>

Question

So am I misunderstanding the API? Or is this an incorrect combination of JSON-related libraries? A bug in one of them?

I realize too, that serializing a null might leave me with a second problem when it's time to deserialize it. I am going to want to use JSON-B to deserialize later, if that helps guide the answer. Thank you.

Update:

This yasson issue suggests it might be a bug. Added more detail there.


Solution

  • Exception which you get is basically telling you that you can't pass a null into JsonObjectBuilder#add method, which is thrown by JSONP implementation org.glassfish:javax.json.

    Setting JsonbConfig#withNullValues(true) does not relate to it.

    JSONB and JSONP are two different APIs, even so JSONB does depend on JSONP. org.eclipse:yasson is an implementation of JSONB API which in your case does use org.glassfish:javax.json - an implementation of JSONP API, because you provided it in your POM.

    Setting JsonbConfig#withNullValues(true) is a call on JSONB API which does mean "print null values to JSON" for example:

    { firstname: null, lastname: null }

    So when org.eclipse:yasson (JSONB) encounters a null value in a pojo object property it does something like javax.json.stream.JsonGenerator#writeNull(key).

    This does not relate in any way to your code in StatusAdapter which is basically calling JSONP API JsonObjectBuilder#add with a null value, which is not allowed.