Search code examples
scalacompiler-errorsscala-collectionstype-mismatch

Scala can't seem to convert mutable maps into Java Maps


I have a Java POJO that I'm using inside a Scala app:

public class AppRuntimeContext {
  // Lots of stuff...
  public Map<Object,Object> contextMap;

  // Getters & setters, ctors, etc.  
}

In my Scala app:

val ctx : AppRuntimeContext = new AppRuntimeContext()
val ctxMap : Map[String,Fizz] = Map()
// Some code that populates 'ctxMap'
ctx.setContextMap(ctxMap)

This produces a compiler error on the setter method:

type mismatch; found : scala.collection.mutable.Map[String,com.me.myapp.Fizz] required: java.util.Map[Object,Object]

So I try converting ctxMap to a java.util.Map by adding the following import statement:

import collection.JavaConversions._

And then by changing the setter call to:

ctx.setContextMap(mapAsJavaMap(ctxMap))

However when I do this I still get a compiler error:

type mismatch; found : scala.collection.mutable.Map[String,com.me.myapp.Fizz] required: scala.collection.Map[Object,Object] Note: String <: Object, but trait Map is invariant in type A. You may wish to investigate a wildcard type such as _ <: Object. (SLS 3.2.10)

Any ideas what is causing this error and what the fix is?


Solution

  • One option is to cast the map into a Map[Object, Object]:

    ctx.setContextMap(mapAsJavaMap(ctxMap.asInstanceOf[mutable.Map[Object, Object]]))
    

    A better one would probably be to declare ctxMap as a Map[Object, Object] in the first place, although that would allow putting objects that do not conform to the expected [String, Fizz] types:

    val ctxMap : mutable.Map[Object, Object] = mutable.Map()
    // Some code that populates 'ctxMap'
    ctxMap.put("k", Fizz(1))
    
    ctx.setContextMap(mapAsJavaMap(ctxMap))