自定义URLClassLoader不使用自定义类路径

时间:2016-10-29 12:00:30

标签: java oracle jdbc classloader

我正在尝试使用多个Oralce JDBC驱动程序按照this Question的说明连接到2个Oracle数据库。

我在默认ClassLoader的类路径中有ojdbc6.jar来连接到Oracle 11g。

enter image description here

要连接到另一个数据库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());

在最后一行中,将打印驱动程序类的位置。运行程序,我得到了

file:/D:/workspace/ccbs/lib/oravl01/oracle/11.2.0.2/jdbc/lib/ojdbc6.jar

当我从类路径中删除ojdbc6.jar并再次运行程序时,我得到了

file:/D:/workspace/ccbs/lib/classes12.jar

请为我的自定义URLClassLoader在自定义类路径中的默认类路径而不是oracle.jdbc.OracleDriver中加载ojdbc6.jar classes12.jar

2 个答案:

答案 0 :(得分:1)

我已经对你的代码进行了一些调试,确实发生了。显然,父类加载器在您的类加载之前按顺序加载,并且仍然加载他在类路径中找到的另一个ojdbc jar

此主题概述了创建自己的自定义父级最后一个类加载器的解决方案: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);

答案 1 :(得分:1)

答案是类加载器委派模型。 ClassLoader documentation描述了它。

要解决您的问题,请尝试更换

URLClassLoader driverLoader = new URLClassLoader(classpath, null);

"1"

这样可以确保URLClassLoader不使用应用程序类路径。