【问题标题】:Extract version of dynamically loaded JDBC drivers动态加载的 JDBC 驱动程序的提取版本
【发布时间】:2013-08-13 20:06:21
【问题描述】:

我正在尝试以编程方式提取不同 JDBC 驱动程序的次要/主要版本。这些驱动程序在 jar 文件中动态提供并按如下方式加载:

URLClassLoader loader = new URLClassLoader(new URL[] { new URL("theNameOfTheJar") });
Driver driver = (Driver) Class.forName("theClassNameOfTheDriver", true, loader).newInstance();

System.out.println(driver.getMajorVersion());
System.out.println(driver.getMinorVersion());

我遇到的问题是,如果应用程序本身使用 Oracle 11g 驱动程序(首先在 DriverManager 中注册),之后就无法提取正确的 Oracle 10g 驱动程序版本。在这种情况下,上面的代码总是显示 11g 驱动程序版本,而不是正确的 10g 版本。

我也尝试过先注销所有驱动程序,但没有成功:

    Enumeration<Driver> drivers = DriverManager.getDrivers();

    while(drivers.hasMoreElements()) {

        Driver d = drivers.nextElement();

        try {
            DriverManager.deregisterDriver(d);
        } catch (SQLException ex) {
            // TODO Auto-generated catch block
            ex.printStackTrace();
        }
    }

是否有可能提取正确的驱动程序信息?

【问题讨论】:

  • 不能从类路径中删除 11g 驱动程序类吗?
  • 很遗憾没有。应用需要11g的驱动,还需要提取老驱动的版本信息。

标签: java jdbc classloader


【解决方案1】:

好的,我终于找到了问题所在。这只是一个类加载器问题。

默认情况下,类加载器首先询问其父级是否可以加载该类。在我的情况下,“默认”类加载器已经加载了驱动程序。所以 URLClassLoader 没有从 jar 文件中加载它。解决方案是将父类加载器显式设置为 null:

URLClassLoader loader = URLClassLoader.newInstance(new URL[] { url },
            null);

非常感谢@Evgeniy Dorofeev 将我推向正确的方向。

【讨论】:

    【解决方案2】:

    如果您有 2 个版本不同但类名相同的驱动程序,则只会加载其中一个。您需要 2 个不同的类加载器来加载这两个类。

    【讨论】:

    • 愚蠢的问题:URLClassLoader 是第二个类加载器,不是吗?
    • 你需要一个带有 jar 1 的 URLCLassLoader 和另一个带有 jar 2 的 URLCLassLoader
    • 好的,很抱歉造成混淆:第一个 oracle 驱动程序 jar (11g) 是类路径中的静态依赖项,不是由 URLClassLoader 加载的。
    • OK,然后用Class.forName加载驱动1,用loader.loadClass加载驱动2
    猜你喜欢
    • 2011-08-24
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 2014-06-26
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    相关资源
    最近更新 更多