自定义 URLClassLoader 不使用自定义类路径
Custom URLClassLoader does not use the custom classpath
我正在尝试使用多个 Oralce JDBC 驱动程序按照 的说明连接到 2 个 Oracle 数据库。
我在默认 ClassLoader 的 class 路径中有 ojdbc6.jar
以连接到 Oracle 11g。
为了连接另一个数据库,Oracle 8i,我写了一段代码如下
File driverJar = new File("D:/workspace/ccbs/lib/classes12.jar");
String driverClassName = "oracle.jdbc.OracleDriver";
String con = "jdbc:oracle:thin:@db1host:5555:db1";
URL[] classpath = new URL[] {driverJar.toURI().toURL()};
URLClassLoader driverLoader = new URLClassLoader(classpath, ClassLoader.getSystemClassLoader());
Class driverClass = driverLoader.loadClass(driverClassName);
System.out.println(driverClass.getProtectionDomain().getCodeSource().getLocation());
最后一行打印了驱动程序class的位置。 运行 程序和我得到了
file:/D:/workspace/ccbs/lib/oravl01/oracle/11.2.0.2/jdbc/lib/ojdbc6.jar
当我从 class 路径中删除 ojdbc6.jar
并再次 运行 程序时,我得到了
file:/D:/workspace/ccbs/lib/classes12.jar
请说明为什么我的自定义 URLClassLoader 从默认 class 路径中的 ojdbc6.jar
加载 oracle.jdbc.OracleDriver
而不是自定义 class 路径中的 classes12.jar
。
我对你的代码进行了一些调试,确实出现了。显然,父 class 加载程序先于您的 class 加载顺序,并且仍然加载他在 classpath
上找到的另一个 ojdbc jar
此线程概述了创建您自己的自定义父最后 classloader 的解决方案:How do I create a parent-last / child-first ClassLoader in Java, or How to override an old Xerces version that was already loaded in the parent CL?
我已经尝试过这个线程的公认解决方案,它似乎按预期工作;加载在 driverJar 变量中定义的 jar。使用 ParentLastURLClassLoader
只需更改以下两行代码
ParentLastURLClassLoader driverLoader = new ParentLastURLClassLoader(Arrays.asList(classpath));
Class driverClass = driverLoader.loadClass(driverClassName);
答案是 class 加载程序委派模型。 ClassLoader documentation描述了它。
要解决您的问题,请尝试更换
URLClassLoader driverLoader = new URLClassLoader(classpath, ClassLoader.getSystemClassLoader());
和
URLClassLoader driverLoader = new URLClassLoader(classpath, null);
这样可以确保 URLClassLoader 不使用应用程序 class 路径。
我正在尝试使用多个 Oralce JDBC 驱动程序按照
我在默认 ClassLoader 的 class 路径中有 ojdbc6.jar
以连接到 Oracle 11g。
为了连接另一个数据库,Oracle 8i,我写了一段代码如下
File driverJar = new File("D:/workspace/ccbs/lib/classes12.jar");
String driverClassName = "oracle.jdbc.OracleDriver";
String con = "jdbc:oracle:thin:@db1host:5555:db1";
URL[] classpath = new URL[] {driverJar.toURI().toURL()};
URLClassLoader driverLoader = new URLClassLoader(classpath, ClassLoader.getSystemClassLoader());
Class driverClass = driverLoader.loadClass(driverClassName);
System.out.println(driverClass.getProtectionDomain().getCodeSource().getLocation());
最后一行打印了驱动程序class的位置。 运行 程序和我得到了
file:/D:/workspace/ccbs/lib/oravl01/oracle/11.2.0.2/jdbc/lib/ojdbc6.jar
当我从 class 路径中删除 ojdbc6.jar
并再次 运行 程序时,我得到了
file:/D:/workspace/ccbs/lib/classes12.jar
请说明为什么我的自定义 URLClassLoader 从默认 class 路径中的 ojdbc6.jar
加载 oracle.jdbc.OracleDriver
而不是自定义 class 路径中的 classes12.jar
。
我对你的代码进行了一些调试,确实出现了。显然,父 class 加载程序先于您的 class 加载顺序,并且仍然加载他在 classpath
上找到的另一个 ojdbc jar此线程概述了创建您自己的自定义父最后 classloader 的解决方案:How do I create a parent-last / child-first ClassLoader in Java, or How to override an old Xerces version that was already loaded in the parent CL?
我已经尝试过这个线程的公认解决方案,它似乎按预期工作;加载在 driverJar 变量中定义的 jar。使用 ParentLastURLClassLoader
只需更改以下两行代码ParentLastURLClassLoader driverLoader = new ParentLastURLClassLoader(Arrays.asList(classpath));
Class driverClass = driverLoader.loadClass(driverClassName);
答案是 class 加载程序委派模型。 ClassLoader documentation描述了它。
要解决您的问题,请尝试更换
URLClassLoader driverLoader = new URLClassLoader(classpath, ClassLoader.getSystemClassLoader());
和
URLClassLoader driverLoader = new URLClassLoader(classpath, null);
这样可以确保 URLClassLoader 不使用应用程序 class 路径。