Implementing Java interface in Scala results in incompatible type map

Issue

I have a Java interface that I want to implement in Scala. The interface contains the following method-declaration:

 List<Map<String, Object>> xyz(Map<String, Object> var1, Map<String, Object> var2);

My Scala implementation is:

override def testComponent( input: java.util.Map[String, Object], metadata: java.util.Map[String, Object] )
  {

    val list: util.List[Map[String, AnyRef]]  new util.ArrayList[Map[String, AnyRef]]

     return list
  }

ERROR : overriding method xyz in trait ITester of type (x$1: java.util.Map[String,Object], x$2: java.util.Map[String,Object])java.util.List[java.util.Map[String,Object]]; method testComponent has incompatible type override def testComponent( input: java.util.Map[String, Object], metadata: java.util.Map[String, Object] )

I don’t know what exactly the issue is.

Solution

Your definition of testComponent has type Unit because it’s defined using the (deprecated in recent versions of Scala) procedure syntax of def name(args) { } (i.e. no {). It first passes compilation because Scala allows a value to be discarded when Unit is expected (that behavior can be made a warning with the compiler option -Ywarn-value-discard). You can solve this by being explicit that you want this method to be called for value by including the “.

override def testComponent(input: java.util.Map[String, Object], metadata: java.util.Map[String, Object])  {
  val list: util.List[Map[String, AnyRef]]  new util.ArrayList[Map[String, AnyRef]]
  list  // return should be avoided in Scala: it's not necessary and can introduce some really subtle bugs
}

It’s generally a good idea to be explicit about the result type of a public method. Alternatively, this should also work:

override def testComponent(input: java.util.Map[String, Object], metadata: java.util.Map[String, Object]) 
  new ArrayList[Map[String, AnyRef]]

Answered By – Levi Ramsey

Leave a Comment