I need to allow a user to specify the implementation of an interface at runtime via a config file, similar to in this question: Specify which implementation of Java interface to use in command line argument
However, my situation is different in that the implementations are not known at compile time, so I will have to use reflection to instantiate the class. My question is ... how do I structure my application such that my class can see the new implementation's .jar, so that it can load the class when I call:
Class.forName(fileObject.getClassName()).newInstance()
?
The comment is correct; as long as the .jar file is in your classpath, you can load the class.
I have used something like this in the past:
public static MyInterface loadMyInterface( String userClass ) throws Exception
{
// Load the defined class by the user if it implements our interface
if ( MyInterface.class.isAssignableFrom( Class.forName( userClass ) ) )
{
return (MyInterface) Class.forName( userClass ).newInstance();
}
throw new Exception("Class "+userClass+" does not implement "+MyInterface.class.getName() );
}
Where the String userClass was the user-defined classname from a config file.
EDIT
Come to think of it, it is even possible to load the class that the user specifies at runtime (for example, after uploading a new class) using something like this:
public static void addToClassPath(String jarFile) throws IOException
{
URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class loaderClass = URLClassLoader.class;
try {
Method method = loaderClass.getDeclaredMethod("addURL", new Class[]{URL.class});
method.setAccessible(true);
method.invoke(classLoader, new Object[]{ new File(jarFile).toURL() });
} catch (Throwable t) {
t.printStackTrace();
throw new IOException( t );
}
}
I remember having found the addURL() invocation using reflection somewhere here on SO (of course).
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