2

Consider this code:

object A {
  object AA extends A
  object AB extends A
  object AC extends A
}; class A

How is it possible to "see" the objects defined within object A at runtime? I thought a method within object A with some simple reflection code would be enough, but it seems that the compiler flattens the object hierarchy at compile time and created the following class files:

  • A.class – The class A
  • A$class – The companion object of A
  • A$AA$.class – The AA object
  • A$AB$.class – The AB object
  • A$AC$.class – The AC object

After compilation there is no sign about AA, AB or AC in the companion object A, which would have my magicMethod.

It seems that the ClassLoader class has some related methods to what I plan to do, but all seem to expect the exact String name of the class. Is there a way to ask the ClassLoader to find all class files starting with the class from which this method is called (A$) in the path of that class?

soc
  • 27,983
  • 20
  • 111
  • 215
  • gee, you're **really** specific about how you want to declare these `MonthDate` objects. – Ken Bloom Nov 23 '10 at 04:09
  • Yes :-). Basically I want concise DRY code, the possibility to add my own methods, having the possibility for the user to instantiate their own instances without a type mismatch with the declared instances and need "self-awareness" so that the object knows how many objects it actually holds (and can retrieve them). Everything without inventing special syntaxes or rules like registering the instances. – soc Nov 23 '10 at 13:16

2 Answers2

3

The underlying problem is that the JVM has no concept of inner classes. They were added in Java 1.1, but the JVM spec remained completely unchanged between 1.0 and the introduction of invokedynamic (seriously!).

As a bit of a hack, you could always parse the class names and split on $

UPDATE

In order to do this, you'll unfortunately have to scan the classpath.

One of the better known applications of the technique is Apache Commons Discovery: http://commons.apache.org/discovery/ (which is something you could use to make your life easier)

Spring also uses the same approach.

Kevin Wright
  • 49,540
  • 9
  • 105
  • 155
  • 1
    How do you _find_ the class names in order to parse them? – Rex Kerr Nov 22 '10 at 18:48
  • sadly, You have to scan the classpath. It seems to be all the rage nowadays. – Kevin Wright Nov 22 '10 at 18:52
  • 1
    In that case, a link or example of a canonical way to do this would greatly enhance your answer! – Rex Kerr Nov 22 '10 at 19:08
  • Although the VM does not know inner classes, reflection is supposed to work and it does work as expected in Java code. It relly seems to be a bug in the Scala compiler. – soc Nov 23 '10 at 13:12
1

The code this.getClass.getDeclaredClasses should return the requested information.

But after experimenting a bit with various tools, it suspect that something is not working correctly here.

I tried various things in Scala with classes inside classes instead of objects and Java sources and judging from the behaviour it should clearly return the expected results but currently it doesn't.

Either I'm fundamentally wrong or scalac might be forgetting to put some bits of metadata into the class files it generates, resulting in incorrect reflection information.

See this bug report.

soc
  • 27,983
  • 20
  • 111
  • 215