【问题标题】:Why does runtime loaded MySQL driver output "No suitable driver found"?为什么运行时加载的 MySQL 驱动程序输出“找不到合适的驱动程序”?
【发布时间】:2021-01-19 07:48:47
【问题描述】:

我尝试在我的应用程序运行时加载 MySQL 驱动程序。因此,我将 jar 文件加载方法设为“loadJobJars”,以使用给定的 jar 文件列表创建 URLClassLoader 对象。我调用了 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)

【问题讨论】:

  • 你为什么要这样加载jar文件?为什么不能将它们放在应用程序的类路径中并让 JVM 处理它们?

标签: java mysql jdbc urlclassloader


【解决方案1】:

DriverManager 创建连接的方式对调用代码的类加载器很敏感。用于创建连接的Driver 必须对调用类的类加载器可见(或者当调用代码没有类加载器时,上下文类加载器)。你加载的驱动对调用代码的类加载器是不可见的,所以DriverManager不会使用驱动来创建连接。

您必须使用使用相同类加载器的代码(或至少在带有驱动程序的类加载器可见的地方)创建连接。或者,您需要直接使用java.sql.Driver,完全跳过DriverManager

【讨论】:

    【解决方案2】:

    感谢您的友好回答。
    看了你的回答,终于通过直接加载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);
    

    【讨论】:

      猜你喜欢
      • 2016-04-02
      • 2016-07-18
      • 1970-01-01
      • 2012-07-14
      • 1970-01-01
      • 2012-12-09
      • 2014-09-17
      相关资源
      最近更新 更多