We've encountered a problem similar to
In my case , we are already using non-async logging for reurers' classes while the ArrayIndexOutOfBoundsException and NullPointerException keep coming up from toString() method or during payload parsing.
Example from log file shows the exception when handling RefreshMsg :
Exception in thread "pool-4-thread-1" java.lang.NullPointerException
at java.util.LinkedList$ListItr.next(LinkedList.java:893)
at com.thomsonreuters.ema.access.EmaIterator.next(EmaIterator.java:30)
at com.htsc.mdc.vss.refinitiv.message.MessageUtil.translate(MessageUtil.java:31)
at com.htsc.mdc.vss.refinitiv.client.ema.CallBackMsgHandler.handleEmaMsg(CallBackMsgHandler.java:51)
at com.htsc.mdc.vss.refinitiv.client.ema.EmaClient.onRefreshMsg(EmaClient.java:31)
Exception in thread "pool-4-thread-1" java.lang.NullPointerException
at java.util.LinkedList.node(LinkedList.java:577)
at java.util.LinkedList.get(LinkedList.java:477)
at com.thomsonreuters.ema.access.FieldListImpl.clearCollection(FieldListImpl.java:562)
at com.thomsonreuters.ema.access.FieldListImpl.fillCollection(FieldListImpl.java:332)
at com.thomsonreuters.ema.access.FieldListImpl.iterator(FieldListImpl.java:99)
at com.htsc.mdc.vss.refinitiv.message.MessageUtil.translate(MessageUtil.java:31)
at com.htsc.mdc.vss.refinitiv.client.ema.CallBackMsgHandler.handleEmaMsg(CallBackMsgHandler.java:51)
at com.htsc.mdc.vss.refinitiv.client.ema.EmaClient.onRefreshMsg(EmaClient.java:31)
java.lang.ArrayIndexOutOfBoundsException: -1
at com.thomsonreuters.upa.codec.Decoders.decodeFieldEntry(Decoders.java:2544)
at com.thomsonreuters.upa.codec.FieldEntryImpl.decode(FieldEntryImpl.java:140)
at com.thomsonreuters.ema.access.FieldListImpl.fillCollection(FieldListImpl.java:346)
at com.thomsonreuters.ema.access.FieldListImpl.toString(FieldListImpl.java:217)
at com.thomsonreuters.ema.access.RefreshMsgImpl.toString(RefreshMsgImpl.java:583)
at com.thomsonreuters.ema.access.RefreshMsgImpl.toString(RefreshMsgImpl.java:468)
at java.lang.String.valueOf(String.java:2994)
at org.apache.logging.log4j.message.ObjectMessage.getFormattedMessage(ObjectMessage.java:55)
at com.htsc.morphling.log4j2.Log4j2Util.getDefalutStackTrace(Log4j2Util.java:18)
at com.htsc.morphling.log4j2.Log4j2Producer.format(Log4j2Producer.java:41)
at com.htsc.octopus.log.KafkaSender.run(KafkaSender.java:67)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
As you might want to know , here is our relevant JAVA code
We use a simple "foreach iteration" in MessageUtil.translate to get and transfer data from FieldList into our Message
class EmaClient implements OmmConsumerClient { @Autowired CallBackMsgHandler callBackMsgHandler; @Override public void onRefreshMsg(RefreshMsg refreshMsg, OmmConsumerEvent event) { callBackMsgHandler.handleEmaMsg(refreshMsg); }
public class CallBackMsgHandler { public void handleEmaMsg(Msg msg) { Payload payload = msg.payload(); if (null == payload || DataType.DataTypes.FIELD_LIST != payload.dataType()) { return; } Message message = MessageUtil.translate(payload.fieldList()); } }
public static Message translate(FieldList fieldList) { Message message = new Message(); for (FieldEntry fieldEntry : fieldList) { Object field = parse(fieldEntry); int fid = fieldEntry.fieldId(); if (LONGNEXTLR == fid) { message.setNextLk(field); message.setDir(true); continue; } if (null != field && !BLANK_STRING.equals(field)) { switch (fid) { //symbol case DISPLY_NAME: message.setSymbol(field); break; case MNEMONIC: message.setSecurityID(field); break; case RDN_EXCHD2: message.setSecurityIDSource(field); break; case TRD_STATUS: message.setTradingPhaseCode(field); break; //price case TRDPRC_1: message.setLastPx(field); break; case HIGH_1: message.setHighPx(field); break; case LOW_1: message.setLowPx(field); break; case OPEN_PRC: message.setOpenPx(field); break; case OFF_CLOSE: message.setClosePx(field); break; case HST_CLOSE: message.setPreClosePx(field); break; case CEILG_PRC: message.setMaxPx(field); break; case FLOOR_PRC: message.setMinPx(field); break; //time case TRADE_DATE: message.setGMTDate(field); break; case SALTIM: message.setGMTTime(field); break; //handicap case NUM_MOVES: message.setNumTrades(field); break; case BID: message.setBuy1Price(field); break; case ASK: message.setSell1Price(field); break; case BIDSIZE: message.setBuy1OrderQty(field); break; case ASKSIZE: message.setSell1OrderQty(field); break; case ACVOL_1: message.setTotalVolumeTrade(field); break; case TURNOVER: message.setTotalValueTrade(field); break; default: if (LONGLINK1 <= fid && fid <= LONGLINK14) { message.add2List(field); } break; } } } return message; } public static Object parse(FieldEntry fieldEntry) { if(null == fieldEntry){ return BLANK_STRING; } if (Data.DataCode.BLANK == fieldEntry.code()) { return BLANK_STRING; } switch (fieldEntry.loadType()) { case DataType.DataTypes.NO_DATA: case DataType.DataTypes.REAL: return fieldEntry.real().asDouble(); case DataType.DataTypes.DATE: OmmDate date = fieldEntry.date(); return date.year() + TimeUtils.ZeroPad(date.month()) + TimeUtils.ZeroPad(date.day()); case DataType.DataTypes.TIME: OmmTime time = fieldEntry.time(); return TimeUtils.ZeroPad(time.hour()) + TimeUtils.ZeroPad(time.minute()) + TimeUtils.ZeroPad(time.second()) + TimeUtils.ZeroPad(time.millisecond(), 3); case DataType.DataTypes.INT: return fieldEntry.intValue(); case DataType.DataTypes.UINT: return fieldEntry.uintValue(); case DataType.DataTypes.ASCII: return fieldEntry.ascii().toString(); case DataType.DataTypes.RMTES: return fieldEntry.rmtes().toString(); case DataType.DataTypes.ENUM: return fieldEntry.hasEnumDisplay() ? fieldEntry.enumDisplay() : fieldEntry.enumValue(); case DataType.DataTypes.ERROR: return "(" + fieldEntry.error().errorCodeAsString() + ")"; default: return null; } }