NullPointerException from RefreshMsgImpl.toString and during payload parsing

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;
}
}

Best Answer

  • Hello @xinlong,

    Can we confirm, where CallBackMsgHandler is constructed?

    I have tried running an excerpt of the code included, without defining all variables, and it appears to result in the same exception.

    Can you try this modification:

    class AppClient implements OmmConsumerClient
    {
        CallBackMsgHandler callBackMsgHandler_;

        AppClient() {
            callBackMsgHandler_ = new CallBackMsgHandler();
        }

        public void onRefreshMsg(RefreshMsg refreshMsg, OmmConsumerEvent event)

            callBackMsgHandler_.handleEmaMsg(refreshMsg);
        }

    Let us know if this helps?


Answers

  • The version of ema SDK we are using is

    <!-- ESDK -->
    <dependency>
    <groupId>com.thomsonreuters.ema</groupId>
    <artifactId>ema</artifactId>
    <version>3.5.0.0</version>
    </dependency>

    <dependency>
    <groupId>com.thomsonreuters.upa</groupId>
    <artifactId>upa</artifactId>
    <version>3.5.0.0</version>
    </dependency>

    <dependency>
    <groupId>com.thomsonreuters.upa.valueadd</groupId>
    <artifactId>upaValueAdd</artifactId>
    <version>3.5.0.0</version>
    </dependency>

    <dependency>
    <groupId>com.thomsonreuters.upa.valueadd.cache</groupId>
    <artifactId>upaValueAddCache</artifactId>
    <version>3.5.0.0</version>
    </dependency>

    <dependency>
    <groupId>com.thomsonreuters.upa.ansi</groupId>
    <artifactId>ansipage</artifactId>
    <version>3.5.0.0</version>
    </dependency>
  • ConcurrentModificationException occurs too...

    Exception in thread "pool-4-thread-1" java.util.ConcurrentModificationException

    at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:966)

    at java.util.LinkedList$ListItr.next(LinkedList.java:888)

    at com.thomsonreuters.ema.access.EmaIterator.next(EmaIterator.java:30)

    at com.htsc.mdc.vss.refinitiv.message.MessageUtil.translate(MessageUtil.java:29)

    at com.htsc.mdc.vss.refinitiv.client.ema.CallBackMsgHandler.handleEmaMsg(CallBackMsgHandler.java:51)


    With due inspection , we have no concurrent modification to the fieldList.


    Wish you could tell us how to fix or avoid all the exceptions occurred so far.


    Many thanks



  • CallBackMsgHandler instance is a bean injected by Spring container

    I've tried your modification.However nothing was getting any better;

  • Hello @xinlong,

    Sorry to hear this.

    Please share a minimal, fully executable example of this issue, and I will run it on my side to reproduce.

    I have modified your code shared, to make it runnable, based on the SDK example Market Price Streaming 100. Please find it attached:

    • Let me know how it runs for you.
    • Feel free to use it for the minimal example, to reproduce the issue that you see.
    • Please note, I would rather not create callBackMsgHandler inside AppClient. I tried to follow what you were doing, to help you pinpoint the issue. Rather, create it outside AppClient, and pass it in.

    example100__MarketPrice_ConcurrentIssueModif2.zip