Using Scala reflection with Java reflection

2019-06-16 23:48发布

问题:

I have a lot of code that has been using Java reflection to invoke arbitrary user-specified methods on Java objects, as part of a DSL.

However, a lot of those Java objects, in practice, are Scala objects, and some of the methods on them are marked with the Scala @deprecated annotation. Unfortunately, Java's annotations mechanism cannot see Scala annotations, and until Scala 2.10 there was no convenient way (that I know of?) to get access to those annotations.

I have finally upgraded to 2.10, and would like to be able to emit deprecation warnings from my DSL. However, I don't want to rewrite the entire evaluator (for now, at least) to use Scala reflection, so is there a convenient way to go from a java.lang.reflect.Method to something I can use Scala reflection on to figure out if the Scala method in question is deprecated? Or will I have to duplicate a lot of the existing method resolution logic using Scala reflection before I can get at that information?

It looks like a JavaToScala class used to exist in Scala reflection, which had a methodToScala method in it that did what I want. The only trace I can find is here, in a google code project. Why was the functionality moved out of core reflection? Or is it still there under a different name?

Edit: It looks like the code in question lives on in scala.reflect.runtime.JavaMirrors, but unfortunately it's private (there's another JavaMirrors that is part of the public API, but doesn't provide any of what I need.) I can't figure out for the life of me if there's a "path" of invocations through a public API that takes me all the way down to the private methodAsScala buried deep within the private JavaMirrors. It's frustrating, to say the least :(

回答1:

Here is a quick fix (credits to @EugeneBurmako)

https://gist.github.com/xeno-by/5277805

An issue has been filed for this (credits to @MysteriousDan):

https://issues.scala-lang.org/browse/SI-7317