We've encountered a problem similar to
https://community.developers.refinitiv.com/questions/29297/nullpointerexception-from-updatemsgimpltostring.html
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;
}
}