英文:
Using ojdbc5 and ojdbc8 driver in the same application with java11+
问题
在我的程序中,我必须连接到多个数据库。出于某些原因,我必须使用多个不同的ojdbc驱动程序,例如ojdbc5.jar,ojdbc8.jar等。关于这一点无法进行更改。
在Java 8中,它的工作原理如下:
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Driver;
import java.util.Properties;
public class JdbcMain {
public static void main(final String[] args) throws Exception {
final File driverOne = new File("C:\\workspace\\lib\\ojdbc5.jar");
final File driverTwo = new File("C:\\workspace\\lib\\ojdbc8.jar");
getJDBCForDriver(driverOne);
getJDBCForDriver(driverTwo);
}
private static void getJDBCForDriver(final File jdbcDriverFile) throws Exception {
final URL url = jdbcDriverFile.toURI().toURL();
final URL[] array = new URL[] {url};
final URLClassLoader ucl = new URLClassLoader(array, null);
final Class driverClass = ucl.loadClass("oracle.jdbc.driver.OracleDriver");
final Driver driver = (Driver) driverClass.getDeclaredConstructor().newInstance();
final Properties prop = new Properties();
prop.put("user", "myUser");
prop.put("password", "myPassword");
try (final Connection connection = driver.connect("jdbc:oracle:thin:@localhost:1521:xe", prop)) {
final DatabaseMetaData metaData = connection.getMetaData();
final int jdbcMajorVersion = metaData.getJDBCMajorVersion();
final int jdbcMinorVersion = metaData.getJDBCMinorVersion();
System.out.println("JDBC Version for File " + jdbcDriverFile.getName() + ": " + jdbcMajorVersion + "." + jdbcMinorVersion);
}
}
}
在Java 8的输出结果如下:
JDBC Version for File ojdbc5.jar: 11.1
JDBC Version for File ojdbc8.jar: 4.2
然而,从Java 11(或9)开始,这不再起作用。 这里会出现以下错误:
Exception in thread "main" java.lang.NoClassDefFoundError: java/sql/Driver
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:550)
at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:458)
at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:452)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:451)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at zzzz_Jdbc.JdbcMain.getJDBCForDriver(JdbcMain.java:26)
at zzzz_Jdbc.JdbcMain.main(JdbcMain.java:17)
Caused by: java.lang.ClassNotFoundException: java.sql.Driver
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 12 more
有什么方法可以解决这个问题吗?
英文:
In my program I have to connect to several databases. For certain reasons I have to use several different ojdbc drivers, e.g. ojdbc5.jar, ojdbc8.jar, etc. Nothing can be changed about that.
With Java 8 it works like this:
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Driver;
import java.util.Properties;
public class JdbcMain {
public static void main(final String[] args) throws Exception {
final File driverOne = new File("C:\\workspace\\lib\\ojdbc5.jar");
final File driverTwo = new File("C:\\workspace\\lib\\ojdbc8.jar");
getJDBCForDriver(driverOne);
getJDBCForDriver(driverTwo);
}
private static void getJDBCForDriver(final File jdbcDriverFile) throws Exception {
final URL url = jdbcDriverFile.toURI().toURL();
final URL[] array = new URL[] {url};
final URLClassLoader ucl = new URLClassLoader(array, null);
final Class driverClass = ucl.loadClass("oracle.jdbc.driver.OracleDriver");
final Driver driver = (Driver) driverClass.getDeclaredConstructor().newInstance();
final Properties prop = new Properties();
prop.put("user", "myUser");
prop.put("password", "myPassword");
try (final Connection connection = driver.connect("jdbc:oracle:thin:@localhost:1521:xe", prop)) {
final DatabaseMetaData metaData = connection.getMetaData();
final int jdbcMajorVersion = metaData.getJDBCMajorVersion();
final int jdbcMinorVersion = metaData.getJDBCMinorVersion();
System.out.println("JDBC Version for File " + jdbcDriverFile.getName() + ": " + jdbcMajorVersion + "." + jdbcMinorVersion);
}
}
}
The output for Java 8 is:
JDBC Version for File ojdbc5.jar: 11.1
JDBC Version for File ojdbc8.jar: 4.2
Since Java 11 (or 9), however, this no longer works. The following error occurs here:
Exception in thread "main" java.lang.NoClassDefFoundError: java/sql/Driver
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:550)
at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:458)
at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:452)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:451)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at zzzz_Jdbc.JdbcMain.getJDBCForDriver(JdbcMain.java:26)
at zzzz_Jdbc.JdbcMain.main(JdbcMain.java:17)
Caused by: java.lang.ClassNotFoundException: java.sql.Driver
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 12 more
Any ideas how to solve this?
专注分享java语言的经验与见解,让所有开发者获益!
评论