3

I am writing Java code in which I need to call a Scala function that is defined like so:

def func[T: TypeTag: ClassTag ](name: String): RDD[T] = ...

In Scala I'd simple call func String The Java code should be something like: func( "a" , arg1 , arg2 ) where arg1 is a TypeTag< T > and arg2 is a ClassTag< T >

I am not sure how to generate arg1 and arg2 in java

S S
  • 920
  • 1
  • 17
  • 34
Harel Gliksman
  • 734
  • 1
  • 7
  • 19

1 Answers1

1

Do you want to do it for generic T or for specific one? For generic, there is no way to do it, accept ClassTag<T> and TypeTag<T> as arguments instead (just like Scala code actually does). For specific, I'd suggest writing a wrapper in Scala, e.g. def func_String(name: String) = func[String](name) and calling it from Java.

Or more generically, but undesirably complex:

import scala.reflect.ClassTag
import scala.reflect.runtime.universe._

def func1[T](name: String, clazz: Class[T]) = {
  val classTag = ClassTag[T](clazz)

  val m = runtimeMirror(clazz.getClassLoader)
  val tpe = m.classSymbol(clazz).toType
  val typeCreator = new scala.reflect.api.TypeCreator {
    def apply[U <: Universe with Singleton](m1: scala.reflect.api.Mirror[U]): U # Type = 
      if (m1 != m) throw new RuntimeException("wrong mirror") else tpe.asInstanceOf[U#Type]
  }
  val typeTag = TypeTag[T](m, typeCreator)

  func(name)(typeTag, classTag)
}

(you could write the equivalent in Java as well.)

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • 3
    solved my problem by adding the generic solution in Scala. For completeness maybe you can post the Java solution as well so that those who are limited to Java-only can still get their answer ( as this was my original intent in the question ), thanks you so much! – Harel Gliksman Jul 26 '16 at 18:27
  • Hi @Alexey, Could you please provide Java equivalent for same? – Vasu Oct 02 '18 at 14:21
  • 2
    Quetion: "How to get TypeTag in Java?", Answer: "Here is Scala code" :) – VB_ Mar 04 '19 at 16:15
  • 1
    @VB_ Main part of the answer: "I'd suggest writing a wrapper in Scala, e.g. def func_String(name: String) = func[String](name) and calling it from Java". The Scala code is also something you'd call from Java. – Alexey Romanov Mar 04 '19 at 17:29
  • 1
    @Vasu I suspect that `TypeCreator` can't be overridden in pure Java because of the method signature. `@Override public scala.reflect.api.Types.TypeApi apply(scala.reflect.api.Mirror m1)` `... is not abstract and does not override abstract method apply(scala.reflect.api.Mirror) in scala.reflect.api.TypeCreator` – Dmytro Mitin Oct 21 '22 at 12:34