question

Upvotes
Accepted
1 1 1 0

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;
    }
}
refinitiv-realtimeelektronelektron-sdkema-apirrtelektron-message-api
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

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



1 Answer

· Write an Answer
Upvotes
Accepted
32.2k 41 11 20

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?


icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

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

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.