Почему драйвер MySQL, загруженный во время выполнения, выводит Не найден подходящий драйвер?

Я попытался загрузить драйвер MySQL во время работы моего приложения. Поэтому я сделал метод загрузки файла jar как loadJobJars, чтобы создать объект URLClassLoader с заданным списком файлов jar. И я вызвал метод Class.forName, а затем метод DriverManager.getConnection. Но выдавало, что на терминале не найдено подходящего драйвера.

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

Мой код ниже.

    public DBConnectionManager(Path jarPath) throws MalformedURLException {
        this.urlClassLoader = loadJobJars(listJarFiles(jarPath));
    }

    public Connection createConnection(String dbName, String host, int port, String db, String user,
            String password) throws NoSuchFieldException, SecurityException, IllegalArgumentException,
            IllegalAccessException, ClassNotFoundException, SQLException, InstantiationException {
        dbName = dbName.toLowerCase();
        String url = "jdbc:" + dbName + "://" + host + ":" + port + "/" + db;
        String driverName = DBDriver.getDriverName(dbName.toUpperCase());
        Logger.getInstance().info("connection url: "+url+"   driver: "+driverName);

        Class.forName(driverName, true, this.urlClassLoader);
        Connection conn = DriverManager.getConnection(url, user, password); //Here is it was happened code line.
        return conn;
    }

    public URLClassLoader loadJobJars(File[] jarFiles) throws MalformedURLException {
        URL[] urls = Arrays.asList(jarFiles).stream().map(f -> {
            try {
                System.out.println(f.getAbsolutePath());
                return f.toURI().toURL();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
            return null;
        }).filter(u -> u != null).toArray(URL[]::new);
        return URLClassLoader.newInstance(urls, ClassLoader.getPlatformClassLoader());
    }

    public File[] listJarFiles(Path jarPath) {
        return jarPath.toFile().listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith(".jar");
            }            
        });
    }

Вывод консоли ниже.

[INFO][DBConnectionManager:77][20210119152004] connection url: jdbc:mysql://localhost:3306/mysql   driver: com.mysql.jdbc.Driver
Exception in thread "main" java.sql.SQLException: No suitable driver found for jdbc:mysql://192.168.1.157:3306/mysql
        at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:702)
        at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:251)
        at com.innotree.innoquartz.iqjobgen.DBConnectionManager.createConnection(DBConnectionManager.java:35)
        at com.innotree.innoquartz.iqjobgen.DBConnectionManager.main(DBConnectionManager.java:77)

person Kooin-Shin    schedule 19.01.2021    source источник
comment
Почему вы так загружаете файлы jar? Любая причина, по которой вы не можете иметь их в пути к классам вашего приложения и позволить JVM обрабатывать их?   -  person Bogdan    schedule 19.01.2021


Ответы (2)


Способ, которым DriverManager создает соединения, зависит от загрузчика классов вызывающего кода. Driver, используемый для создания соединения, должен быть виден загрузчику классов вызывающего класса (или, если вызывающий код не имеет загрузчика классов, загрузчику классов контекста). Загруженный вами драйвер невидим для загрузчика классов вызывающего кода, поэтому DriverManager не будет использовать драйвер для создания соединения.

Вы должны создать соединение, используя код, который использует тот же загрузчик классов (или, по крайней мере, там, где виден загрузчик классов с драйвером). В качестве альтернативы вам нужно использовать java.sql.Driver напрямую, полностью пропуская DriverManager.

person Mark Rotteveel    schedule 19.01.2021

Спасибо за ваш любезный ответ.
Я увидел ваш ответ и, наконец, понял проблему, загрузив драйвер MySQL напрямую. Ваша помощь была очень полезна, чтобы решить эту проблему. Код решения приведен ниже.

String url = "jdbc:mysql://localhost:3306/mysql";
URLClassLoader loader = new URLClassLoader(urls, ClassLoader.getSystemClassLoader()); 
Class cls = loader.loadClass("com.mysql.jdbc.Driver"); 
Driver driver = (Driver)cls.newInstance(); 

Properties info = new Properties(); 
info.put("user", "admin"); 
info.put("password", "1234"); 
Connection conn = driver.connect(url, info);
person Kooin-Shin    schedule 20.01.2021