when reflection doesn't work

Discussions

General J2EE: when reflection doesn't work

  1. when reflection doesn't work (12 messages)

    I'm having trouble to make my jsp use reflection to instantiate an object at runtime.

    I use Class.forName("my.class.Name.Innerclass") to instantiate a public static inner class object of the my.class.Name class.

    The exception is ClassNotFoundException: my.class.Name.Innerclass

    If i instantiate my.class.JustSomeClass it works. I'm sure my.class.JustSomeClass is in the same jar as my.class.Name. and my.class.Name.Innerclass.

    I tried J2EE ri and jboss; same behaviour.

    Threaded Messages (12)

  2. when reflection doesn't work[ Go to top ]

    The class file of your inner class is actually something like "my.class.Name$InnerClass", but I don't know if this naming convention is mandated by the spec (I seem to remember one compiler, perhaps the AspectJ comiler(???), that generated inner classes with names like "Outer$$Inner"). Even though it is possible to instantiate inner classes reflectively, I'm not sure it is a good idea to do so.
  3. thanks![ Go to top ]

    The $ makes the difference!

    That's quite a shock to me...
  4. when reflection doesn't work[ Go to top ]

    Tim P-

    You're right about the use of $ in class names. I believethis is to distinguish it from a class called "InnerClass" in a package called "my.class.Name"

    AFAIK there is no reason why static inner classes should not be instantiated reflectively like normal classes.

    I'm interested in what leads you to the idea that there was some problem with doing this?
  5. It's because i don't want to write big if then elses, or program mappings, for code that is only used by me or other developers.

    Our application has a command pattern. There is an administrator entrance where you can invoke any command by giving the clommand-class-name + an xml structure that holds the command parameters.

    Some commands are defined as static nested classes of the interface in which they can be performed (for example the CreateUserCommand is a static nested class of the Users interface).
  6. when reflection doesn't work[ Go to top ]

    <tim fox>
    I'm interested in what leads you to the idea that there was some problem with doing this?
    <tim fox>

    I guess I would be hestant to use Class.forName() if you were depending on the name of the inner class always being "Outer$Inner". If another compiler produced "Outer$$Inner", for example, you might be in trouble.
  7. don't like $[ Go to top ]

    You're right, if the single '$' is not in the specifications.

    I can hardly believe that (except if there is another way to load an nested class based on the classname).
  8. don't like $[ Go to top ]

    Dieter,

    <gal>
    As for the naming issue, as far as I know the only rule given by the binary compatabillity requirements of the JLS is (section 13.1, "The Form of a Binary"):

    "The binary name of any nested type must have, as a prefix, the binary name of its enclosing top-level class."
    </gal>

    This is from the JLS. However, I checked in the VM spec and found, from the JDK1.1.8 inner class spec (referenced by the current VM Spec as the authorative document on inner classes):

    "The bytecode name of a class C which is a non-private member of another class, and which is not contained (directly or indirectly) in any block or private class, is defined as the bytecode name of the immediately-enclosing class, followed by `$', followed by the simple name of C."

    I'm not sure which of the two specs takes precedence, but all implementations would probably adhere to the stronger rule, i.e the VM spec rule. So I guess it would be safe to assume the format of OuterClassFullName$InnerClassSimpleName.

    Gal
  9. when reflection doesn't work[ Go to top ]

    <tim p>
    I guess I would be hestant to use Class.forName() if you were depending on the name of the inner class always being "Outer$Inner". If another compiler produced "Outer$$Inner", for example, you might be in trouble.
    </tim p>
    Tim - as Gal has pointed out, it is a requirement that the class be named Outer$Inner, so don't worry about it.
  10. when reflection doesn't work[ Go to top ]

    Follow up: I found the requirement from the VM spec in the JLS as well. It simply slipped my eyes the last time I looked. So it's formal :) the name of a non-private member class is of from Outer$Inner. For private member classes or non-member inner classes (i.e anonymous classes) the only rule is that they must have the name of the outer class as a prefix.

    Gal
  11. hurray[ Go to top ]

    wooh! i'll have a beer on that :) thanks guys!
  12. when reflection doesn't work[ Go to top ]

    The code generated for an inner class constructor contains an additional implicit parameter of the enclosing class's type. Using Class.forName(...) will fail, as the class has no default constructor. This is not true, of course, for static nested classes, which do not have a reference to their enclosing instance.

    As for the naming issue, as far as I know the only rule given by the binary compatabillity requirements of the JLS is (section 13.1, "The Form of a Binary"):

    "The binary name of any nested type must have, as a prefix, the binary name of its enclosing top-level class."

    Gal
  13. when reflection doesn't work[ Go to top ]

    I just noticed you wrote "static inner class". My first comment was about non-static inner classes, which are called, in JLS terms, "inner classes". Static inner classes are called, in JLS terms, "static nested classes". Please interpert my comment accordingly.

    Gal