How to implement the Java interface in Scala using several variable parameter methods (enter the problem with the eraser)?

I have a Scala class that is trying to implement a Java interface (specific EntityManager in JavaEE 7 for specific testing purposes). An interface has these two methods (among others):

public StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses); public StoredProcedureQuery createStoredProcedureQuery(String procedureName, String... resultSetMappings); 

In the Scala implementation, I have:

 override def createStoredProcedureQuery(procedureName: String, resultClasses: Class[_]*): StoredProcedureQuery = ??? override def createStoredProcedureQuery(procedureName: String, resultSetMappings: String*): StoredProcedureQuery = ??? 

However, I get the following error:

 MyTest.scala:134: error: double definition: method createStoredProcedureQuery:(procedureName: String, resultSetMappings: String*)javax.persistence.StoredProcedureQuery and method createStoredProcedureQuery:(procedureName: String, resultClasses: Class[_]*)javax.persistence.StoredProcedureQuery at line 133 have same type after erasure: (procedureName: String, resultSetMappings: Seq)javax.persistence.StoredProcedureQuery override def createStoredProcedureQuery(procedureName: String, resultSetMappings: String*): StoredProcedureQuery = ??? 

I could not find a job. My Google searches were also unable to find and respond. I am using Scala 2.10.4.

+6
source share
1 answer

AFAIK EntityManager The Java interface cannot be implemented directly in Scala. Java varargs are converted to Seq[Class[_]] in the first method and Seq[String] in the second method. Due to erasure, both methods appear as having the same signature createStoredProcedureQuery(String, Seq[_]) .

I can only suggest a workaround for this problem. You must write an abstract Java class that extends the EntityManager interface and implements two violation methods, delegating 2 to other abstract methods with different names in order to disambiguate:

 public abstract class EntityManagerWorkaround implements EntityManager { @Override public StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses) { return createStoredProcedureQueryForResultClasses(procedureName, resultClasses); } @Override public StoredProcedureQuery createStoredProcedureQuery(String procedureName, String... resultSetMappings) { return createStoredProcedureQueryForResultSetMappings(procedureName, resultSetMappings); } public abstract StoredProcedureQuery createStoredProcedureQueryForResultClasses(String procedureName, Class... resultClasses); public abstract StoredProcedureQuery createStoredProcedureQueryForResultSetMappings(String procedureName, String... resultSetMappings); 

}

Now you can extend the abstract class from Scala and implement ambiguous methods:

 class EntityManagerImpl extends EntityManagerWorkaround { override def createStoredProcedureQueryForResultClasses(procedureName: String, resultClasses: Class[_]*) = ??? override def createStoredProcedureQueryForResultSetMappings(procedureName: String, resultSetMappings: String*) = ??? } 
+2
source

Source: https://habr.com/ru/post/970597/


All Articles