Подтвердить что ты не робот

Как использовать драйвер JDBC из произвольного местоположения

Мне нужно проверить соединение JDBC с базой данных. Код java для этого должен быть таким же простым, как:

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

Менеджер драйверов будет искать соответствующий драйвер для данного URL-адреса подключения. Однако мне нужно иметь возможность загружать драйвер JDBC (jar) во время выполнения. I.e У меня нет драйвера JDBC в пути к классам Java-приложения, которое запускает фрагмент кода выше.

Поэтому я могу загрузить драйвер, используя этот код, например:

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

Но тогда менеджер драйверов все равно не подберет его, так как я не могу сказать, какой класс загрузчик использовать. Я попытался установить текущий загрузчик классов контекста потока, и он все еще не работает.

Кто-нибудь знает, как наилучшим образом достичь этого?

4b9b3361

Ответ 1

Из статьи Выберите драйвер JDBC во время выполнения; Я просто отправлю код здесь для справки.

Идея состоит в том, чтобы обмануть менеджера драйверов, считая, что драйвер был загружен из системного загрузчика. Для этого мы используем этот класс:

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

Таким образом, вы регистрируете драйвер типа DelegatingDriver, который загружается загрузчиком системного класса. Теперь вам просто нужно загрузить драйвер, который вы действительно хотите использовать, используя любой загрузчик классов, который вы хотите. Например:

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

Ответ 2

Проблема DriverManager выполняет "задачи с использованием экземпляра загрузчика класса немедленного вызова". См. Руководство 6-3 Правила безопасного кодирования для Язык программирования Java, версия 2.0. В этом случае загрузчик системного класса никоим образом не является особенным.

Просто для пинок, я написал запись по этому вопросу некоторое время назад. Мое решение, хотя и более сложное, тогда решение Ника Сайера, является более полным и даже работает от ненадежного кода. Также обратите внимание, что URLClassLoader.newInstance предпочтительнее new URLClassLoader.