I'm loading in classes from a JAR that implement an interface from a public API. The interface itself will remain constant but other classes associated with the API may change over time. Clearly once the API changes we will no longer be able to support implementations of the interface that were written with the old version. However some of the interface methods provide simple meta-data of type String
that we can assume will never change and never rely on the other parts of the API that may change. I would like to be able to extract this meta-data even when the API has changed.
For example consider the following implementation that might be loaded in where Foo
is the interface and Bar
is an another class in the API. I want to call the name
method even when the class Bar
no longer exists.
class MyFoo implements Foo {
Bar bar = null;
@Override public String name() {
return "MyFoo"
}
}
As far as I can see the obvious approach is to override loadClass(String name)
in my custom ClassLoader
and return some "fake" class for Bar
. The meta-data methods can be assumed to never create or use a Bar
object. The question is how to generate this "fake" class when asked to load Bar
. I've thought about the following approaches:
- Simply return any old existing class. I've tried returning
Object.class
but this still results in aNoClassDefFoundError
forBar
when I try to instantiate an instance ofFoo
. - Use ASM to generate the byte code for a new class from scratch.
- Use ASM to rename some sort of empty template class to match
Bar
and load that.
Both 2. and 3. seem quite involved, so I was wondering if there was an easier way to achieve my goal?