question

Upvote
Accepted
31 0 0 4

Periodic NullPointerException on unregister and reissue when using payload view in EMA Java Api

We've recently started using ViewPayload in RT-SDK EMA (version 3.7.0.0 and 3.6.1.2 on Linux) to limit the number of fields that we receive in two of our applications. This works ok for receiving the data but unfortunately for reissue and during unregistration we are seeing issues in the API the end up with exceptions. It looks like there may be a race condition or a bug in the logic of the library (unless we are using it wrong, but we followed the examples from: https://github.com/Refinitiv/Real-Time-SDK/blob/master/Java/Ema/Examples/src/main/java/com/refinitiv/ema/examples/training/consumer/series300/ex360_MP_View/Consumer.java)


Sample code that is equivalent of what we do during registration is:

OmmConsumerClient ommConsumerClient = ...;// custom consumer client
ItemRequest itemRequest = ...; // custom class keeping domainType, serviceName, itemName
Set<String> fields = ....;
Map<String, Integer> fieldIdLookup = ...;

Request request = EmaFactory.createReqMsg();
request.clear();
ElementList viewElementList = EmaFactory.createElementList();
OmmArray ommArray = EmaFactory.createOmmArray();
ommArray.clear();
ommArray.fixedWidth(2);
int fieldPosition = 0;
for (String field : fields) {
  if (fieldIdLookup.containsKey(field)) {
    ommArray.add(EmaFactory.createOmmArrayEntry().intValue(fieldIdLookup.get(field)));
    fieldPosition++;
  } else {
    LOG.warn("[{}] requested field {} was not found in dictionary for {}", name, field, itemRequest);
  }
}
if (fieldPosition > 0) {
  ElementEntry viewType = EmaFactory.createElementEntry().uintValue(EmaRdm.ENAME_VIEW_TYPE, 1);
  viewElementList.add(viewType);
  viewElementList.add(EmaFactory.createElementEntry().array(EmaRdm.ENAME_VIEW_DATA, ommArray));
  request.payload(viewElementList);
}
request
  .domainType(itemRequest.domainType())
  .serviceName(itemRequest.serviceName())
  .name(itemRequest.itemName())
  .interestAfterRefresh(interestAfterRefresh);
long itemHandle = ommConsumer.registerClient(request, ommConsumerClient, closure);


On the reissue side what we do is:

// reusing the same request, using the itemHandle obtained in the code above
request.clear();
ommConsumer.reissue(request, itemHandle);


And unregister:

// using the itemHandle obtained in the code above
ommConsumer.unregister(itemHandle);


The issues do not occur every time and there is no specific pattern of them happening but when they happen they produce results like the ones below:


Reissue (using version 3.7.0.0):

java.lang.NullPointerException: null
        at com.refinitiv.eta.valueadd.reactor.WlViewHandler.removeRequestView(WlViewHandler.java:381) 
        at com.refinitiv.eta.valueadd.reactor.WlItemHandler.removeRequestView(WlItemHandler.java:3816) 
        at com.refinitiv.eta.valueadd.reactor.WlItemHandler.handleReissue(WlItemHandler.java:1030) 
        at com.refinitiv.eta.valueadd.reactor.WlItemHandler.submitRequest(WlItemHandler.java:228) 
        at com.refinitiv.eta.valueadd.reactor.Watchlist.submitMsg(Watchlist.java:162) 
        at com.refinitiv.eta.valueadd.reactor.ReactorChannel.submit(ReactorChannel.java:802) 
        at com.refinitiv.ema.access.SingleItem.rsslSubmit(ItemCallbackClient.java:3026) 
        at com.refinitiv.ema.access.SingleItem.modify(ItemCallbackClient.java:2892) 
        at com.refinitiv.ema.access.ItemCallbackClient.reissue(ItemCallbackClient.java:2320) 
        at com.refinitiv.ema.access.OmmBaseImpl.reissue(OmmBaseImpl.java:581) 
        at com.refinitiv.ema.access.OmmConsumerImpl.reissue(OmmConsumerImpl.java:273) 


Unregister (using older version 3.6.1.2):

java.lang.NullPointerException: null
        at com.refinitiv.eta.valueadd.reactor.WlViewHandler.removeRequestView(WlViewHandler.java:373) ~[etaValueAdd-3.6.1.2.jar!/:etaj3.6.1.G1.all.rrg]
        at com.refinitiv.eta.valueadd.reactor.WlItemHandler.removeRequestView(WlItemHandler.java:3727) ~[etaValueAdd-3.6.1.2.jar!/:etaj3.6.1.G1.all.rrg]
        at com.refinitiv.eta.valueadd.reactor.WlItemHandler.removeUserRequestFromOpenStream(WlItemHandler.java:1601) ~[etaValueAdd-3.6.1.2.jar!/:etaj3.6.1.G1.all.rrg]
        at com.refinitiv.eta.valueadd.reactor.WlItemHandler.submitMsg(WlItemHandler.java:1466) ~[etaValueAdd-3.6.1.2.jar!/:etaj3.6.1.G1.all.rrg]
        at com.refinitiv.eta.valueadd.reactor.Watchlist.submitMsg(Watchlist.java:191) ~[etaValueAdd-3.6.1.2.jar!/:etaj3.6.1.G1.all.rrg]
        at com.refinitiv.eta.valueadd.reactor.ReactorChannel.submit(ReactorChannel.java:690) ~[etaValueAdd-3.6.1.2.jar!/:etaj3.6.1.G1.all.rrg]
        at com.refinitiv.ema.access.SingleItem.rsslSubmit(ItemCallbackClient.java:3055) ~[ema-3.6.1.2.jar!/:emaj3.6.1.G1.all.rrg]
        at com.refinitiv.ema.access.SingleItem.close(ItemCallbackClient.java:2907) ~[ema-3.6.1.2.jar!/:emaj3.6.1.G1.all.rrg]
        at com.refinitiv.ema.access.ItemCallbackClient.unregister(ItemCallbackClient.java:2301) ~[ema-3.6.1.2.jar!/:emaj3.6.1.G1.all.rrg]
        at com.refinitiv.ema.access.OmmBaseImpl.unregister(OmmBaseImpl.java:525) ~[ema-3.6.1.2.jar!/:emaj3.6.1.G1.all.rrg]
        at com.refinitiv.ema.access.OmmConsumerImpl.unregister(OmmConsumerImpl.java:165) ~[ema-3.6.1.2.jar!/:emaj3.6.1.G1.all.rrg]
        at com.mi.ahl.pubsub.rtapi.ema.consumer.CountableOmmConsumerClientManager.unregister(CountableOmmConsumerClientManager.java:61) ~[pubsub-elektron-3141.jar!/:?]
        at com.mi.ahl.pubsub.rtapi.ema.registration.SimpleOmmConsumerRegistration.unregister(SimpleOmmConsumerRegistration.java:70) ~[pubsub-elektron-3141.jar!/:?]
        at com.mi.ahl.pubsub.rtapi.ema.registration.operation.RegistrationProcessor.unregister(RegistrationProcessor.java:277) ~[pubsub-elektron-3141.jar!/:?]
        at com.mi.ahl.pubsub.rtapi.ema.registration.operation.RegistrationProcessor.execute(RegistrationProcessor.java:194) ~[pubsub-elektron-3141.jar!/:?]
        at com.mi.ahl.pubsub.rtapi.ema.SimpleTaskScheduler.executeTimeDependentTask(SimpleTaskScheduler.java:109) ~[pubsub-elektron-3141.jar!/:?]
        at com.mi.ahl.pubsub.rtapi.ema.SimpleTaskScheduler.executeTimeDependentTasks(SimpleTaskScheduler.java:84) ~[pubsub-elektron-3141.jar!/:?]
        at com.mi.ahl.pubsub.rtapi.ema.SimpleTaskScheduler.mainLoop(SimpleTaskScheduler.java:70) ~[pubsub-elektron-3141.jar!/:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at java.lang.Thread.run(Thread.java:834) [?:?]


Please let me know if you need any further details you may need for the investigation.

Thanks, Grzegorz

ema-api#productrefinitiv-realtime-sdk
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.

Upvote
Accepted
81.1k 264 53 76

@grzegorz.ligas01

Sorry for the confusion.

You need to contact the API support team to investigate this issue. If you are an RDC (Refinitiv Developer Connect) named user, you can contact the API support team via Contact Premium Support.

Otherwise, you can submit this issue on GitHub.


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.

This has been raised as a GitHub issue and is being investigated by developers:

https://github.com/Refinitiv/Real-Time-SDK/issues/239

Upvotes
81.1k 264 53 76

@grzegorz.ligas01

Thanks for reaching out to us.

You can't use the handle returned by a batch request to call the unregister and reissue methods because this handle will be closed by the API, as shown below.

1685499825175.png

To unregister or reissue a requested item, you need to use an item handle returned in the callback.

    public void onRefreshMsg(RefreshMsg refreshMsg, OmmConsumerEvent event)
    {
        long itemhandle = event.handle();
        System.out.println(refreshMsg);
    }

You can call the event.handle() method in the callback function to get an item handle. Each item will have its own handle.

I hope that this information is of help.


1685499825175.png (38.8 KiB)
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.

Upvote
31 0 0 4

Hi @Jirapongse
Thank you for such a quick response!

Just want to double check one thing as I think I caused some confusion by pointing at the sample code...

We are not using batching mechanism at all. I just pointed at example that uses View Payload (it also shows batching that we do not use). My sample code as you may notice is not using any batching and in real code we are not using it either.

I had a brief look on the code and it seems like the state of the committed field list in valueAdd watchlist is not consistent (state is showing that view is committed but the committed field list is null). Could that be some race condition?

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.

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.