-2

I am trying to create a Scala map from 2 Java classes:

TopicPartition(java.lang.String topic, int partition)
OffsetAndMetadata(long offset)

Does this look correct?

val topicPartition = new TopicPartition("sometopicname", 99)
val offsetAndMetadata = new OffsetAndMetadata(999999L,"tette")

val mapTopicOffset = Map(topicPartition -> offsetAndMetadata)

Also need to create a method that will accept this map as input parameter.

Tried something like:

  def commitSync(offsets: Map[TopicPartition, OffsetAndMetadata] ) = {

    }

Got error:

Error:(239, 37) type mismatch;
 found   : Map[org.apache.kafka.common.TopicPartition,org.apache.kafka.clients.consumer.OffsetAndMetadata] (in scala.collection.immutable) 
 required: Map[org.apache.kafka.common.TopicPartition,org.apache.kafka.clients.consumer.OffsetAndMetadata] (in java.util) 
    verify(kc, times(1)).commitSync(mapTopicOffset)

Is there a way to provide overloaded method that will take a scala map? (not sure how to write that)

Or maybe everything should be rewritten differently (from starting of creating objects etc.)?

Mike Allen
  • 8,139
  • 2
  • 24
  • 46
Joe
  • 11,983
  • 31
  • 109
  • 183
  • If you look at the error, you'll see that you're passing a `scala.collection.immutable.Map` when you need a `java.util.Map`. The two types are not the same. – Mike Allen May 03 '18 at 17:42
  • I can see that. How to fix it? (I am very new to scala and java) – Joe May 03 '18 at 17:43
  • Possible duplicate of [Using scala map in Java](https://stackoverflow.com/questions/21495117/using-scala-map-in-java) – Mike Allen May 03 '18 at 18:00

2 Answers2

1

For various reasons Scala has its own standard library including its own collections library with many of the same data structures with similar or even exactly the same names as in Java. Unfortunately you didn't provide a Minimal, Complete, and Verifiable example so we have to guess what exactly is the correct way to fix it.

  1. If both sides of the code are actually Scala just declare commitSync to use scala.collection.immutable.Map. If there is a clash in imports, you can either use full name with the package or rename one of the Map to an unambiguous name (such as JMap and/or SMap) as shown here.

  2. If this is a question about communication between Scala and Java code, then Scala provides wrappers and converters for both conversion such as scala.collection.JavaConverters or scala.collection.JavaConversions (which is deprecated in Scala 2.12 in favor of the first one).

SergGr
  • 23,570
  • 2
  • 30
  • 51
  • Thanks. How to mock a java call (so that can be equal with Scala call)? I have currently `val kc = mock[org.apache.kafka.clients.consumer.KafkaConsumer[String, Array[Byte]]]` and `kc.commitSync(mapTopicOffset)` but that does not match the type (Java call vs Scala method call). How to adjust that test case? thanks. – Joe May 03 '18 at 18:01
  • @Joe, you can't change signature while mocking. Mock will have exactly the same signature as the original type, actually this is the whole point of mocking. If `commitSync` is defined by a library to use `java.util.Map`, you'll have to go down the route #2 and convert your Scala Map into a Java Map before passing it to the `commitSync`. P.S. if you are using newer Scala (2.12) - use [scala.collection.JavaConverters](https://www.scala-lang.org/api/current/scala/collection/JavaConverters$.html) – SergGr May 03 '18 at 18:04
  • @Joe, have you look at the linked ScalaDoc pages? The simplest way in Scala 2.12 is to `import scala.collection.JavaConverters._` and the you can just use `.asJava` as in `kc.commitSync(mapTopicOffset.asJava)` – SergGr May 03 '18 at 18:18
1

I was trying to pass a Map[String, Double] to a Java method. But the problem was JavaConversions converts the Map to a java Map, but leaves the scala Double as is, instead of converting it to java.lang.Double. After a few hours of seaching I found [Alvaro Carrasco's answer])https://stackoverflow.com/a/40683561/1612432), it is as simple as doing:

val scalaMap = // Some Map[String, Double]
val javaMap = scalaMap.mapValues(Double.box)

After this, javaMap is a Map[String, java.lang.Double]. Then you can pass this to a java function that expects a Map<String, Double> and thanks to implicit conversions the Scala Map will be converted to java.util.Map

Alejandro Alcalde
  • 5,990
  • 6
  • 39
  • 79