Java: charger l'implémentation d'interface définie par l'utilisateur (à partir du fichier de configuration)


Je dois permettre à un utilisateur de spécifier l'implémentation d'une interface lors de l'exécution via un fichier de configuration, similaire à dans cette question: Spécifiez l'implémentation de l'interface Java à utiliser dans l'argument de ligne de commande

Cependant, ma situation est différente en ce que les implémentations ne sont pas connues au moment de la compilation, je devrai donc utiliser la réflexion pour instancier la classe. Ma question est la ... comment structurer mon application de telle sorte que ma classe puisse voir la nouvelle implémentation .jar, afin qu'il puisse charger la classe lorsque j'appelle:

Class.forName(fileObject.getClassName()).newInstance()

?

Author: Community, 2015-08-10

1 answers

Le commentaire est correct; tant que le .le fichier jar est dans votre chemin de classe, vous pouvez charger la classe.

J'ai utilisé quelque chose comme ça dans le passé:

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

Où le String userClass était le nom de classe défini par l'utilisateur à partir d'un fichier de configuration.


MODIFIER

À bien y penser, il est même possible de charger la classe que l'utilisateur spécifie à l'exécution (par exemple, après avoir téléchargé une nouvelle classe) en utilisant quelque chose comme ceci:

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 );
    }
}

Je me souviens avoir trouvé l'invocation addURL() utilisant la réflexion quelque part ici sur SO (bien sûr).

 2
Author: mvreijn, 2015-08-10 19:28:32