Or maybe? 1) Connecting to Oracle 8i w / ojdbc5 or ojdbc6 2) Many ojdbc containers

I am creating an application that collects data from several data sources. From these data sources, we have several instances of Oracle.

I found that the only way to connect to my Oracle 8i instance is to use ojdbc14.jar and the following:

String driver = "oracle.jdbc.OracleDriver"; String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=$HOST)(PORT=$PORT)))(CONNECT_DATA=(SID=$SID)))" Class.forName(driver); Connection c = DriverManager.getConnection(url, $USER, $PASSWORD); c.close(); 

When I try to update ojdbc5.jar or ojdbc6.jar using the same code, I get an ArrayIndexOutofBoundsException. The same thing if I only use the url "jdbc: oracle: thin: $ user / $ password @ $ host: $ port: $ sid", which works against more recent Oracle instances that I connect with.

I would prefer not to focus on using the older ojdbc14.jar (especially since I use Java 6), as I may have to support higher Oracle databases in the future.

So, I hope that one of two scenarios is possible:

1) There, the connection string, which I simply ignore, can be used to connect to Oracle 8i with newer OJDBC banks.

2) I can have several OJDBC tanks in my class path so that I can use ojdbc14.jar in the exception database and ojdbc6.jar everywhere. The trick here, of course, is how to determine which jar connection to use for the class "oracle.jdbc.OracleDriver".

Any thoughts?

+4
source share
1 answer

Just out of curiosity, I implemented your second approach through an isolated class loader. It seems to work:

 public class DriverWrapper implements Driver { private Driver target; private String fakePrefix; private String realPrefix; protected DriverWrapper(Driver target, String fakePrefix, String realPrefix) { this.target = target; this.fakePrefix = fakePrefix; this.realPrefix = realPrefix; } public static void loadDriver(URL[] classPath, String className, String fakePrefix, String actualPrefix) throws Exception{ URLClassLoader cl = new URLClassLoader(classPath, DriverWrapper.class.getClassLoader()); Class<?> c = cl.loadClass(className); // It rather rude, but we haven't access to the existing instance anyway Driver d = (Driver) c.newInstance(); Driver w = new DriverWrapper(d, fakePrefix, actualPrefix); // We don't care about already registerd instance, // because driver loaded in isolated classloader // is not visible to the rest of application, see DriverManager javadoc DriverManager.registerDriver(w); } private String resolveURL(String url) { if (url.startsWith(fakePrefix)) { return realPrefix + url.substring(fakePrefix.length()); } else { return null; } } public boolean acceptsURL(String url) throws SQLException { url = resolveURL(url); if (url == null) { return false; } else { return target.acceptsURL(url); } } public Connection connect(String url, Properties info) throws SQLException { url = resolveURL(url); if (url == null) { return null; } else { return target.connect(url, info); } } public int getMajorVersion() { return target.getMajorVersion(); } public int getMinorVersion() { return target.getMinorVersion(); } public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { return target.getPropertyInfo(url, info); } public boolean jdbcCompliant() { return target.jdbcCompliant(); } } 

Used as follows (driver banks should not be in the main path):

 DriverWrapper.loadDriver(new URL[] { new File("ojdbc5.jar").toURL() }, "oracle.jdbc.OracleDriver", "jdbc:oracle5", "jdbc:oracle"); DriverWrapper.loadDriver(new URL[] { new File("ojdbc14.jar").toURL() }, "oracle.jdbc.OracleDriver", "jdbc:oracle14", "jdbc:oracle"); ... DriverManager.getConnection("jdbc:oracle14:...", ...); ... DriverManager.getConnection("jdbc:oracle5:...", ...); 
+4
source

All Articles