How to Serialize OMMItemEvent into String ?
Client's developer had try to use ObjectMapper to serialize , but get error.
Hello @jessie.lin,
I believe that you are trying to parse OMMItemEvent to JSON String using ObjectMapper (from Jackson library).
In my opinion, this Jackson library was created to facilitate mapping between Plain Old Java Object (POJO) and JSON.
However, the main point is that RFA Java’s OMMItemEvent and associated properties’ structures are not POJOs. Nevertheless, the implementation of OMM’s complex type (e.g. FieldList, Vector, Map) in RFA Java is more specific and quite different from Java’s com.util.Collections package. So, I don’t think that the Jackson library is able to properly cover these proprietary data types from Thomson Reuters either.
Here this is the result when I used the following snippet code to convert OMMItemEvent to JSON String:
Snippet Code – in processEvent() method
OMMItemEvent ie = (OMMItemEvent)event; String jsonInString = null; try { jsonInString = mapper.writeValueAsString(ie); } catch (JsonProcessingException e) { e.printStackTrace(); } System.out.println(jsonInString);
As the result, an error occurred from a reference in an Event object.
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.reuters.rfa.internal.common.Stack and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.reuters.rfa.internal.session.omm.OMMItemEventMsg["callStack"]->com.reuters.rfa.internal.common.CallStack["_stack"]) at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1188) at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:260) at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:69) at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:32) at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:717) at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:717) at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:481) at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:320) at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3826) at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3140) at com.reuters.rfa.example.omm.cons.ItemManager.processEvent(ItemManager.java:182) at com.reuters.rfa.internal.common.ResponseMessage.dispatchToClient(Unknown Source) at com.reuters.rfa.internal.common.ResponseMessage.dispatch(Unknown Source) at com.reuters.rfa.internal.common.EventQueueImpl.localDispatch(Unknown Source) at com.reuters.rfa.internal.common.EventQueueImpl.dispatch(Unknown Source) at com.reuters.rfa.example.omm.cons.StarterConsumer.run(StarterConsumer.java:219) at com.reuters.rfa.example.omm.cons.StarterConsumer.main(StarterConsumer.java:335)
Then, I tried to fix ‘No serializer’ error by disabling SerializationFeature.FAIL_ON_EMPTY_BEANS and null object:
OMMItemEvent ie = (OMMItemEvent)event; ObjectMapper mapper = new ObjectMapper(); mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); mapper.setSerializationInclusion(Include.NON_NULL); String jsonInString = null; try { jsonInString = mapper.writeValueAsString(ie); } catch (JsonProcessingException e) { e.printStackTrace(); } System.out.println(jsonInString);
Still, there was an error from NullPointerException.
com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.reuters.rfa.internal.session.omm.OMMItemEventMsg["msg"]->com.reuters.rfa.internal.rwf.RwfMsgOverride["pool"]->com.reuters.rfa.internal.rwf.RwfPool["carrierMessage"]) at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:391) at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:351) at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316) at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:725) at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:717) at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:717) at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:481) at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:320) at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3826) at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3140) at com.reuters.rfa.example.omm.cons.ItemManager.processEvent(ItemManager.java:182) at com.reuters.rfa.internal.common.ResponseMessage.dispatchToClient(Unknown Source) at com.reuters.rfa.internal.common.ResponseMessage.dispatch(Unknown Source) at com.reuters.rfa.internal.common.EventQueueImpl.localDispatch(Unknown Source) at com.reuters.rfa.internal.common.EventQueueImpl.dispatch(Unknown Source) at com.reuters.rfa.example.omm.cons.StarterConsumer.run(StarterConsumer.java:219) at com.reuters.rfa.example.omm.cons.StarterConsumer.main(StarterConsumer.java:335) Caused by: java.lang.NullPointerException at com.reuters.rfa.internal.rwf.RwfPool.getCarrierMessage(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:687) at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:717) ... 18 more
Note that RFA Java’s Event object also provides methods such as getClosure(), getInterestSpec(), getEventQueue(), and etc., which are non-information and should not be generated as JSON anyway.
At this rate, if you still want to convert RFA Java’s Event and associated structures to JSON String via this Jackson library, I suggest you create your own wrapper POJO classes for keeping necessary information that you want it to be in JSON result, and then you convert your POJOs to JSON instead.
Otherwise, if you just want a plain String format output (non-JSON), you may consider to modify/customize a com.reuters.rfa.example.utility.GenericOMMParser class. Here this is the output example just in case you might be interested in it:
MESSAGE Msg Type: MsgType.UPDATE_RESP Msg Model Type: MARKET_PRICE Indication Flags: DO_NOT_CONFLATE Hint Flags: HAS_ATTRIB_INFO | HAS_RESP_TYPE_NUM | HAS_SEQ_NUM SeqNum: 22782 RespTypeNum: 0 (UNSPECIFIED) AttribInfo ServiceName: API_ELEKTRON_EPD_RSSL ServiceId: 2115 Name: JPY= NameType: 1 (RIC) Payload: 13 bytes FIELD_LIST FIELD_ENTRY 114/BID_NET_CH: -0.28 FIELD_ENTRY 372/IRGPRC: -0.25
Hope this helps!
Hi @jessie.lin
OMMItemEvent in RFA C++ and .NET does not support serialization.
Why the client want to serialize OMMItemEvent into String?
If you want to keep it for later use, then they can just clone the event.
Or if they want to access the raw encoded buffer in message level and save it to disk or database, then they can just call getEncodedBuffer() from Msg object to get the raw buffer and then save the raw buffer.
(assuming this an RFA Java question)
What is "ObjectMapper" ? The only ObjectMapper I know is the one from Jackson library. Nothing to do with RFA API.
If you really want to do this then I guess you can use
event.getMsg().getBytes()
and then Base64 encode that.
But the fundamental question is: What is it you're trying to achieve?
Hi sirs
Thank you for the answers. The reason to make serialize, is client want to save the real time source data into messages, and then process those data with Multiple threads asynchronously, in order to get better performance and no lost of real time data.
@jessie.lin, instead of saving data into messages, you can also use OMMPool.acquireCopy() to copy an OMMMsg from OMMItemEvent into the memory (or the application's queue). Then, the application can use another thread to process copied objects later as an alternative.
You can find the detail of OMMPool.acquireCopy() from Developer Guide:
The OMM Item Event (and the encapsulated message) is only valid during the Client callback. If the application wishes to retain the message or data beyond the scope of the callback, it must make a copy of the message or data. Application can use the RFA-managed memory to save the message or data using the OMMPool or acquireCopy() method.
Hope this helps.