JsonArray element class inconsistency

43 views
Skip to first unread message

Thomas Gilbert

unread,
Aug 22, 2017, 9:02:25 AM8/22/17
to vert.x
Hi All,

I'm a vertx beginner, so apologizes if I misunderstood something.
I noticed the following, if I send a JSONArray of JsonObjects through the event bus, the consumer receives a list of:
- JSONObject if the consumer if running locally, in the same JVM (which is nice)
- LinkedHashMap objects if the consumer is running in a other node of the vertx cluster

I find this very inconvenient because I cannot assume that my consumer always receives JSONObjects (or maps) and have lots of type safety checks to add in order to avoid exceptions. 
I would have expected that either:
- JsonObject implements Map so that whatever I receive I can cast it to a map
- all my consumers receive JsonObjects (and their convenient methods) whereever they run

Thanks for your feedback,

Thomas

Julien Viet

unread,
Aug 22, 2017, 9:39:56 AM8/22/17
to ve...@googlegroups.com
normally they should receive json object

can you show us some code or give a reproducer ?

--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
Visit this group at https://groups.google.com/group/vertx.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/56b6eee7-4df7-4eab-8957-85718a5783c8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Thomas Gilbert

unread,
Aug 22, 2017, 10:33:23 AM8/22/17
to vert.x
Thank you for your answer. Here is a code sample. The goal is to create a simple vertx cluster and send objects including a jsonarray.


import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.core.eventbus.Message;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.spi.cluster.hazelcast.HazelcastClusterManager;

public class Main {

public static void main(String[] args) {
Vertx.clusteredVertx(new VertxOptions().setClusterManager(new HazelcastClusterManager()), res -> {
if (res.succeeded()) {
Vertx vertx = res.result();

vertx.eventBus().consumer("example", Main::handleExample);

JsonObject request = new JsonObject()
.put("foo", "bar")
.put("array", new JsonArray()
.add(new JsonObject().put("foo", "bar"))
.add(new JsonObject().put("foo", "bar"))
);

vertx.setPeriodic(1000, id -> {
vertx.eventBus().send("example", request, response -> {
JsonObject jsonResponse = (JsonObject) response.result().body();
System.out.println(jsonResponse.getJsonArray("array").getList().get(0).getClass() + " received in the response");
});
});

} else {
// failed!
}
});
}

private static void handleExample(Message<JsonObject> message) {
JsonObject response = new JsonObject()
.put("baz", "qux")
.put("array", new JsonArray()
.add(new JsonObject().put("baz", "quz"))
.add(new JsonObject().put("baz", "quz"))
);

JsonArray requestArray = message.body().getJsonArray("array");
System.out.println(requestArray.getList().get(0).getClass() + " received in the request");

message.reply(response);
}

}



If you look at the output, it's saying:

class io.vertx.core.json.JsonObject received in the request
class io.vertx.core.json.JsonObject received in the response
class io.vertx.core.json.JsonObject received in the request
class io.vertx.core.json.JsonObject received in the response
class io.vertx.core.json.JsonObject received in the request
class io.vertx.core.json.JsonObject received in the response


if I start only one instance of this program. As soon as I start multiple onces (and Vertx starts distributing the messages), I've got things like this:

class java.util.LinkedHashMap received in the request
class java.util.LinkedHashMap received in the response
class io.vertx.core.json.JsonObject received in the request
class io.vertx.core.json.JsonObject received in the response
class java.util.LinkedHashMap received in the request
class java.util.LinkedHashMap received in the response
class io.vertx.core.json.JsonObject received in the request
class io.vertx.core.json.JsonObject received in the response
class java.util.LinkedHashMap received in the request
class java.util.LinkedHashMap received in the response


Julien Viet

unread,
Aug 22, 2017, 10:40:55 AM8/22/17
to ve...@googlegroups.com
ah,

you should not use the getList() or getMap() methods as they return the raw data (the doc says “Get the underlying list”).

instead you should do jsonResponse.getJsonArray(array).getValue(0)

Julien

--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
Visit this group at https://groups.google.com/group/vertx.

Thomas Gilbert

unread,
Aug 22, 2017, 10:57:30 AM8/22/17
to vert.x
I see. Thanks!
This can indeed help if I wanna get one element at a time.

On the other hand, I cannot do things such as:
- array.getList().sort() to sort the results after I receive them
- array.sublist() to make chunks of requests received by my web handler

etc... 

Again, too bad that JsonObject does not implement Map, it would have make things a lot easier in my opinion.

Julien Viet

unread,
Aug 22, 2017, 11:16:09 AM8/22/17
to ve...@googlegroups.com
if you iterate the list first, it will change all LinkedHashMap value to JsonArray and then you can use the underlying list

--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
Visit this group at https://groups.google.com/group/vertx.
Reply all
Reply to author
Forward
0 new messages