Let JsonFormatter implement Serializer#3102
Conversation
Once in a while I need to write json output in some of my plugins as well but it is surprisingly hard to do so as the API to do so is all internal and non trivial to implement. On the other hand the JsonFormatter already has everything we need here, so this lets JsonFormatter now implement Serializer to conviently support this use-case
|
Would the Though admittedly I'm a bit confused about what your use case is exactly.
Here it sounds like you want to write arbitrary json. But the |
Good catch, that would be a better place to implement that interface But it has the same limitations as JsonFormatter:
No, I want exactly that:
So this hopefully makes it more clear:
This all is used to observer the test-run of a forked cucumber test in eclipse-cucumber plugin. |
|
Unfortunately Java doesn't come with a builtin JSON serializer/deserializer. The I don't mean to XY-problem you, but it really seems like you need a JSON serializer/deserializer. What is the reason you can't bring your own serializer?
I did see you were working on something similar for JUnit (junit-team/junit-framework#5096, ota4j-team/open-test-reporting#728). There it seems writing to an output stream is sufficient? But for what it is worth, the ByteArrayOutputStream delegate = new ByteArrayOutputStream();
OutputStream outputStream = new OutputStream() {
private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@Override
public void write(int b) throws IOException {
if (b == '\n') {
delegate.write(buffer.size());
buffer.writeTo(delegate);
buffer.reset();
} else {
buffer.write(b);
}
}
};
MessageFormatter messageFormatter = new MessageFormatter(outputStream); |
|
Alternatively would it help if messages implemented the serializable interface? |
That's why I found it quite smart if the ones here implement the Serializer interface (same for HTml of course by the way).
The plugin should be as minimal as possible (as I don't know what people are using) and I don't want to bring in something new, and as cucumber already support this and I want exactly this it seems wasted effort anyways.
The protocol requires an ACK (so I can hold on the remote process for debugging steps), the formatters only write and forget (what is good!) so I really need to know the boundaries. Also i probably want to send other commands over the channel and the writer possibly do not give me enough control (e.g about flush).
So as said its all possible somehow but not very convenient and I'm bound to how the internal implementation works and I'm not sure I want to put to much burden on it. To be concrete, would you say it will always be the case now and in the future?! And always a single
Not really as then it would require exact same class versions on client/server. |
|
Would this be sufficient? public final class ObjectToJsonWriter {
@Override
public void writeValue(Writer writer, Object value) throws IOException {
Jackson.OBJECT_MAPPER.writeValue(writer, value);
}
} |
|
@mpkorstanje yes that would of course be suitable as well, I just noticed that in this case an output stream might be more flexible? (and one maybe want to use that in the Message/Jsonformater then as well for consistency). it would of course be great to have the reverse as well for symmetry: Thinking further in the sense of the API consistency it might be better to simply have a class implement
this would also make clear that we write/get an Envelope here... |
|
I'm going to think about it for a bit. Providing a json serializer/deserializer has a lot of complexity attached. And I'm worried that it could open a maintaince sinkhole. |
Any progress on this? Because I noticed that the Can you explain what maintenance problem you see here? The mapper is already so it does not feel anything is specifically needed here except the proposed class that almost never changes! |
Not really. I'm in the middle of upgrading everything to Java 17 at the moment.
There are multiple problems to solve:
This all points towards creating a dedicated dependency for dealing with serialization and deserialization of messages. But I'm in the middle of upgrading everything to Java 17 at the moment so I haven't exactly gotten around to that yet. |
I don't think it should be generic just for
That's why I would love it to be abstracted here, I really don't mind how it works (e.g. jsonb would be my personal preference but as long as it works I don'T mind the technique). So if there is a implementation agnostic way to convert an envelope to / from json I could use that without have to care much about the used technique.
I would say if is use JSonFormatter to print the messages I want to have something to read it... what would then the purpose of it anyways? Sure I can use any json parser but as the structure is quite complex it seems natural to reuse the same lib to parse it into an object model that was used to produce the json.
If you want that jakarta json / jsonb might be a good choice as it defines the API that then one can plug in any of the providers. Anyways it would be perfectly possible to still provide such reader/writer specifically targeting envelope so users do not need to know the details.
I can wait a bit longer, but using json as the transport for cuumber events has just become a crucial part when interfacing different endpoint version so it is really powerful for the cucumber-eclipse so removing the need for replicate what cucumber already does would be a big win! |
|
Cheers! Superseded by cucumber/messages-ndjson#1.
I had a look at that in cucumber/messages-ndjson#2 but jsonb isn't adopted by Gson or Jackson at the moment. And I'm not sure I'm up to writing my own wrapper. 😄 |
Working towards: - cucumber/messages-ndjson#2 - #3102
Working towards: - cucumber/messages-ndjson#2 - #3102
Working towards: - cucumber/messages-ndjson#2 - #3102
Working towards: - cucumber/messages-ndjson#2 - #3102
|
@laeubi you can now use
In conjunction with:
For the latter you'll have to pass |
Yeah that's too bad. Sadly even though json is very popular there is almost no common denominator for an API (yet) leading to all kind of brittle problems with dependency.
I'll take a look! Created
I'm a bit confused where |
It's located in the It will be a transitive dependency of But I just realized I forgot to put the OSGI module name in. I'll do that soonish. |
Once in a while I need to write json output in some of my plugins as well but it is surprisingly hard to do so as the API to do so is all internal and non trivial to implement.
On the other hand the JsonFormatter already has everything we need here, so this lets JsonFormatter now implement Serializer to conviently support this use-case
@mpkorstanje what do you think? I just (again) encountered the problem that my custom hack for this broke the Eclipse-Cucumber plugin, having a semi official API for that would be great and it does not exposes to much of the internals but still allow to reliable write out the JSON (e.g. to a file or websocket) in custom plugins.