How do I call a method of a class dynamically + conditionally?
(Class is eventually not in classpath)
Let's say, I need the class NimbusLookAndFeel
, but on some systems it's not available (i.e. OpenJDK-6
).
So I must be able to:
public static void setNimbusUI(final IMethod<UIDefaults> method)
throws UnsupportedLookAndFeelException {
// NimbusLookAndFeel may be now available
UIManager.setLookAndFeel(new NimbusLookAndFeel() {
@Override
public UIDefaults getDefaults() {
UIDefaults ret = super.getDefaults();
method.perform(ret);
return ret;
}
});
}
EDIT:
Now I edited my code, as it was suggested, to intercept NoClassDefFoundError
using try-catch. It fails. I don't know, if it's OpenJDK's fault. I get InvocationTargetException
, caused by NoClassDefFoundError
. Funny, that I can't catch InvocationTargetException
: It's thrown anyway.
EDIT2::
Cause found: I was wrapping SwingUtilities.invokeAndWait(...)
around the tested method, and that very invokeAndWait
call throws NoClassDefFoundError
when loading Nimbus fails.
EDIT3::
Can anyone please clarify where NoClassDefFoundError
can occur at all? Because it seems that it's always the calling method, not the actual method which uses the non-existing class.
You can do the following: A anA = new A() { public void method1() { ... } }; This is the same as: private static class myA extends A { public void method1() { ... } }
When overriding a method, you might want to use the @Override annotation that instructs the compiler that you intend to override a method in the superclass. If, for some reason, the compiler detects that the method does not exist in one of the superclasses, then it will generate an error.
If a method cannot be inherited, then it cannot be overridden. A subclass within the same package as the instance's superclass can override any superclass method that is not declared private or final. A subclass in a different package can only override the non-final methods declared public or protected.
Get to know it that class is available (at runtime)
Put the usage in a try block ...
If it's not the case, skip the whole thing
... and leave the catch block empty (code smell?!).
How do I manage to override a method of a dynamically-loaded class
Just do it and make sure the compile-time dependency is satisfied. You are mixing things up here. Overriding takes place at compile time while class loading is a runtime thing.
For completeness, every class you write is dynamically loaded by the runtime environment when it is required.
So your code may look like:
public static void setNimbusUI(final IMethod<UIDefaults> method)
throws UnsupportedLookAndFeelException {
try {
// NimbusLookAndFeel may be now available
UIManager.setLookAndFeel(new NimbusLookAndFeel() {
@Override
public UIDefaults getDefaults() {
final UIDefaults defaults = super.getDefaults();
method.perform(defaults);
return defaults;
}
});
} catch (NoClassDefFoundError e) {
throw new UnsupportedLookAndFeelException(e);
}
}
Use BCEL to generate your dynamic subclass on the fly.
http://jakarta.apache.org/bcel/manual.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With