Java - How to find all classes implementing an interface
For my state machine code I’d like to determine at runtime what states the user has created and what there hierarchy. I’ve created an interface that all states of a state machine must implement. My first thought was to use Annotation, but that didn’t work out, Android doesn’t seem to implement retrieving the annotation at runtime. So today I came up with the idea of using getClasses():
Class cl = this.getClass();
Class classes[] = cl.getClasses();Log.v(df, “Hsm: Hsm() classes.length=” + classes.length);
for (Class c : classes) {
Log.v(df, “Hsm: class %s”, c.getName());
}
But that doesn’t work either:
I/ ( 587): Client: MyHsm() E name=TestHsmClient0
W/dalvikvm( 587): No implementation found for native java/lang/Class.getDeclaredClasses (Ljava/lang/Class;Z)[Ljava/lang/Class;
D/dalvikvm( 587): Exception java/lang/UnsatisfiedLinkError from Class.java:414 not caught locally
W/dalvikvm( 587): threadid=15: thread exiting with uncaught exception (group=0×4000e648)
E/AndroidRuntime( 587): Uncaught handler: thread TestHsmClient0 exiting due to uncaught exception
E/AndroidRuntime( 587): java.lang.UnsatisfiedLinkError: getDeclaredClasses
E/AndroidRuntime( 587): at java.lang.Class.getDeclaredClasses(Native Method)
E/AndroidRuntime( 587): at java.lang.Class.getFullListOfClasses(Class.java:414)
E/AndroidRuntime( 587): at java.lang.Class.getClasses(Class.java:172)
E/AndroidRuntime( 587): at com.saville.android.testhsm1.TestHsmClient$MyHsm.build(TestHsmClient.java:40)
E/AndroidRuntime( 587): at com.saville.android.testhsm1.TestHsmClient$MyHsm.<init>(TestHsmClient.java:34)
E/AndroidRuntime( 587): at com.saville.android.testhsm1.TestHsmClient.InitHsm(TestHsmClient.java:21)
E/AndroidRuntime( 587): at com.saville.android.hsm1.ActiveHsm.run(ActiveHsm.java:59)
E/AndroidRuntime( 587): at java.lang.Thread.run(Thread.java:896)
I/Process ( 461): Sending signal. PID: 587 SIG: 3
I/dalvikvm( 587): threadid=7: reacting to signal 3
Bummer.
I then searched for <java find all private classes> and came across this. “Locating all classes implementing a given interface?”. Exactly what I wanted, there were two replies to the post. One says use “ServiceLoader” the other says; “Manually scan the classes in the jar file” or “in your manifest.mf file”. Its interesting that Android has taken the approach of a manifest file. I did a quick search for ServiceLoader its manifest based also.