9
votes

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
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
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
You'd have to use getDeclaredClasses() to get private classDenis Tulskiy
@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

1 Answers

3
votes

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