#Help with reading updated values from ConcurrentHashMap from Java to Scala

19 messages · Page 1 of 1 (latest)

west jetty
#

Hello everyone,
Forgive me if this doesn't belong here and kindly point me to the right direction, as my question is based on Java-Scala inter-operable code base that I am working on.

I have
public static ConcurrentHashMap<String, Long> certMetrics = new ConcurrentHashMap<String, Long>();

in a Java class that is invoked in scala code.

This is read in scala as

if (channelBuilder.certMetrics.isPresent) {
    val certMetrics = channelBuilder.certMetrics.get
    certMetrics.forEach((key, value) => metricsGroup.newGauge(key, () => {value}, providerTag))
  }

This works fine when the server starts. This is used by yammer and exposed as JMX.

However, when the value of certMetrics gets updated from the base java class, the updated value doesn't get reflected where this is populated, which is in the scala code. We have verbose logging in java when the certmetrics gets updated, so I am sure that the value is getting updated, and it is thrown into the logs, but the jmx metric values doesn't reflect the value that it gets updated to.

My intution is, the concurrenthashmap, or the value which is a Long, is cloned rather than referenced, but please correct me if I am wrong.
I don't want to run a periodic task here in a thread that refreshes the data, unless that's the only option here.

What am I doing wrong here?

Thanks.

unkempt doveBOT
#

This post has been reserved for your question.

Hey @west jetty! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.

TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.

outer relic
#

@west jetty Can you mark certMetrics as final?

#

my first guess is that somehow channelBuilder.certMetrics.get gives you a different map

#

i don't see how, but tis a guess

#
if (channelBuilder.certMetrics.isPresent) {
    val certMetrics = channelBuilder.certMetrics.get

clearly somewhere it gets wrapped in an Optional or Option

west jetty
#

Thank you @outer relic .Oh yes, in the interface that this exposes it, it is an Optional

unkempt doveBOT
west jetty
#

But the underlying type is public static ConcurrentHashMap<String, Long> certMetrics = new ConcurrentHashMap<String, Long>(); that gets wrapped in an Optional.

#

This is an internal library, so I can update it to final, but this ConcurrentHashMap gets updated once in a while at runtime, so is it ok to mark it a final?

outer relic
#

well ideally you shouldn't be replacing the map

#

just updating it in place

#

thats the point

#

even so that might not be where your issues are coming from

#

but mark it final see if that breaks anything

#

it probably wont

west jetty
#

Ahh, I see. I will test that and will get back, and meanwhile, I will keep the question open.

#

Thank you.