1

I have java app that loads the database driver jar file into the classpath with the following code

    for (int i = 0; i < fileNames.length; i++)
    {
         Method method = (URLClassLoader.class).getDeclaredMethod("addURL", new Class[] {URL.class});
         method.setAccessible(true);
         method.invoke((URLClassLoader)ClassLoader.getSystemClassLoader(), new Object[] { new File(fileNames[i]).toURI().toURL() });
    }

    Class.forName(driverClassName); 
    con = DriverManager.getConnection(_url, _uid, _pwd);

This does not work with Java 9 because it gets a cast exception when casting system class loader to URLClassLoader. How can you to do this in java 9?

Here is new code

String[] fileNames = m_dbDriverFileName.split(";");

URL[] path = new URL[fileNames.length];

for (int i = 0; i < fileNames.length; i++)
{
     path[i] = new File(fileNames[i]).toURI().toURL();
}

URLClassLoader child = new URLClassLoader(path, this.getClass().getClassLoader());
Class.forName(m_dbDriverClass, true, child);
user3375401
  • 481
  • 1
  • 9
  • 19
  • 3
    The code fragment could potentially fail with ClassCastException in JDK 8 and older too, esp. when the system class loader is configured. In any case, the right thing to do is create a URLClassLoader that loads classes from the JAR file. If you could paste in a code fragment on how you specify the open the database connection then we can add see if other changes are needed -- you might have you change your TCCL for example so that the JDBC API can locate your driver. – Alan Bateman Mar 01 '18 at 07:13
  • Thanks for the help. – user3375401 Mar 01 '18 at 15:39
  • The driver is loaded with Class.forName(driverClassName); con = DriverManager.getConnection(_url, _uid, _pwd); – user3375401 Mar 01 '18 at 15:39
  • 3
    So why can't you create a URLClassLoader and pass that class loader to Class.forName to load the driver class? – Alan Bateman Mar 01 '18 at 15:46
  • I am getting "No suitable driver found". I added my new code above – user3375401 Mar 01 '18 at 17:31
  • Did DriverManager.register work? – Alan Bateman Mar 01 '18 at 18:03
  • I am calling DriverManager.getConnection(url, uid, pwd). That is what is failing with no suitable driver found. – user3375401 Mar 02 '18 at 13:01
  • If you aren't using register then are you setting the thread context class loader before calling getConnection? I believe this is what JDBC needs in order to find your driver loaded by a custom class loader. – Alan Bateman Mar 02 '18 at 14:30

1 Answers1

4

On Java 9 the system class loader is no longer a URLClassLoader (which was never specified anyway - that was an implementation detail) and it is not possible to append JARs to the class path at run time.

You should instead create a new class loader, e.g. a URLClassLoader, with the desired path and the system class loader as parent. For more details you should extend your question to show how you go on to load the driver.

Nicolai Parlog
  • 47,972
  • 24
  • 125
  • 255