Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: load User-defined interface implementation (from config file)

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()

?

like image 601
Eric Avatar asked Aug 23 '26 21:08

Eric


1 Answers

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).

like image 91
mvreijn Avatar answered Aug 26 '26 10:08

mvreijn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!