Question

Je dois tester une connexion JDBC à une base de données. Le code Java à faire devrait être aussi simple que:

DriverManager.getConnection("jdbc connection URL", "username", "password");

Le gestionnaire de pilotes recherchera le pilote approprié pour l'URL de connexion donnée. Cependant, je dois pouvoir charger le pilote JDBC (jar) au moment de l'exécution. Je n’ai pas le pilote JDBC sur le chemin de classe de l’application Java qui exécute l’extrait de code ci-dessus.

Je peux donc charger le pilote en utilisant ce code, par exemple:

URLClassLoader classLoader = new URLClassLoader(new URL[]{"jar URL"}, this.getClass().getClassLoader());
Driver driver = (Driver) Class.forName("jdbc driver class name", true, classLoader).newInstance();

Mais dans ce cas, le gestionnaire de pilotes ne le détectera toujours pas car je ne peux pas lui dire quel chargeur de classe utiliser. J'ai essayé de définir le chargeur de classe de contexte du fil actuel et cela ne fonctionne toujours pas.

Quelqu'un a-t-il une idée sur la meilleure façon d'y parvenir?

Était-ce utile?

La solution

Extrait de l'article Choisissez votre pilote JDBC au moment de l'exécution ; Je vais simplement poster le code ici pour référence.

L’idée est de faire croire au gestionnaire de pilotes que le pilote a été chargé à partir du chargeur de classes du système. Pour ce faire, nous utilisons cette classe:

public class DelegatingDriver implements Driver
{
    private final Driver driver;

    public DelegatingDriver(Driver driver)
    {
        if (driver == null)
        {
            throw new IllegalArgumentException("Driver must not be null.");
        }
        this.driver = driver;
    }

    public Connection connect(String url, Properties info) throws SQLException
    {
       return driver.connect(url, info);
    }

    public boolean acceptsURL(String url) throws SQLException
    {
       return driver.acceptsURL(url);
    }

    public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException
    {
        return driver.getPropertyInfo(url, info);
    }

    public int getMajorVersion()
    {
        return driver.getMajorVersion();
    }

    public int getMinorVersion()
    {
        return driver.getMinorVersion();
    }

    public boolean jdbcCompliant()
    { 
        return driver.jdbcCompliant();
    }
}

Ainsi, le pilote que vous enregistrez est de type DelegatingDriver qui est chargé avec le chargeur de classes du système. Il ne vous reste plus qu'à charger le pilote que vous voulez vraiment utiliser en utilisant le chargeur de classe que vous voulez. Par exemple:

URLClassLoader classLoader = new URLClassLoader(new URL[]{"path to my jdbc driver jar"}, this.getClass().getClassLoader());
Driver driver = (Driver) Class.forName("org.postgresql.Driver", true, classLoader).newInstance();
DriverManager.registerDriver(new DelegatingDriver(driver)); // register using the Delegating Driver

DriverManager.getDriver("jdbc:postgresql://host/db"); // checks that the driver is found

Autres conseils

Le problème est que DriverManager effectue des "tâches en utilisant l'instance de chargeur de classe de l'appelant immédiat". Voir la directive 6-3 des Consignes de codage sécurisé pour les Langage de programmation Java, version 2.0 . Le chargeur de classe système n’est en aucun cas spécial dans ce cas.

Juste pour le plaisir, j’ai écrit une entrée de blog sur ce sujet il y a quelque temps. Ma solution, bien que plus compliquée que la solution de Nick Sayer , est plus complète et fonctionne même à partir de code non fiable. Notez également que URLClassLoader.newInstance est préférable à new URLClassLoader .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top