9

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 :(

Mysterious Dan
  • 1,316
  • 10
  • 25
  • 1
    you're already deep in reflection hell, why not call private method through reflection as well? it won't be worst of your headaches when checking for compatibility with new scala versions. – Denis Tulskiy Mar 30 '13 at 18:00
  • I was really just wondering if there was an endorsed way to do this. It looks like there used to be, but it was moved into private land at some point. I'm also not sure how to call those private methods since the entire class they're in is private. It would be kind of amusing to use reflection to call reflection methods though :) Unfortunately all the methods are in a trait, and I'm not sure how I'd get an instance of it, even if I could reflect my way in. Any pointers? – Mysterious Dan Mar 30 '13 at 18:05
  • 1
    You'd have to use `getDeclaredClasses()` to get private class – Denis Tulskiy Mar 30 '13 at 18:10
  • 1
    https://gist.github.com/xeno-by/5277805 – Eugene Burmako Mar 30 '13 at 18:28
  • 1
    @EugeneBurmako thanks! It seems to work, but I assume I should expect that to break at any time? Is this functionality eventually going to be public or is it just a strong incentive to move all my reflection over to Scala's reflection API? :) I want to do that ASAP but don't have time right now. – Mysterious Dan Mar 30 '13 at 18:36
  • (feel free to post it as an answer if you'd like to get the points, too) – Mysterious Dan Mar 30 '13 at 18:38
  • Please file an issue at https://issues.scala-lang.org/ about this API and assign it to me. I think, it's a reasonable feature request. – Eugene Burmako Mar 31 '13 at 00:42
  • Done! Thanks for being so helpful :) https://issues.scala-lang.org/browse/SI-7317 – Mysterious Dan Mar 31 '13 at 00:50

1 Answers1

3

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

gzm0
  • 14,752
  • 1
  • 36
  • 64