This discussion is archived
1 2 Previous Next 15 Replies Latest reply: Sep 14, 2012 3:30 AM by EJP RSS

Load interfaced classes from jars

809019 Newbie
Currently Being Moderated
Hi,

I'm trying to create instances of Driver classes from jar files in a folder without knowing the class names by using the java.sql.Driver interface.

So, far I've tried...
URLClassLoader loader = URLClassLoader.newInstance(new URL[] { file.toURI().toURL() }, java.sql.Driver.class.getClassLoader());
Class driverClass = Class.forName(java.sql.Driver.class.getName());
Driver driver = (Driver) driverClass.newInstance();
and...
URLClassLoader loader = new URLClassLoader(new URL[] { file.toURI().toURL() });
Class driverClass = Class.forName(java.sql.Driver.class.getName());
Driver driver = (Driver) driverClass.newInstance();
Could I please get some help with regards to this?

Basically, I would like to open JDBC connections straight from Jar files, and I don't see the need to know the class names.

Thanks in advance
  • 1. Re: Load interfaced classes from jars
    EJP Guru
    Currently Being Moderated
    Basically, I would like to open JDBC connections straight from Jar files, and I don't see the need to know the class names.
    There isn't a need any more. The need to call Class.forName() on a JDBC Driver class vanished years ago.
  • 2. Re: Load interfaced classes from jars
    809019 Newbie
    Currently Being Moderated
    Fair enough, but, don't you still require the Driver object to connect?
  • 3. Re: Load interfaced classes from jars
    809019 Newbie
    Currently Being Moderated
    All I'm trying to do is pull the Driver object from the Jar file. It seems I require the Driver class name to do it.
  • 4. Re: Load interfaced classes from jars
    809019 Newbie
    Currently Being Moderated
    If you go into netbeans server tab and add a driver, you simply pick your db file (jar file) and it picks up the required class and datasource prefix, that is exactly what I'm tying to do.
  • 5. Re: Load interfaced classes from jars
    809019 Newbie
    Currently Being Moderated
    The other one I tried was:
    URLClassLoader loader = new URLClassLoader(new URL[] { file.toURI().toURL() });
    Class driverClass = loader.loadClass(java.sql.Driver.class.getName());
    Driver driver = (Driver) driverClass.newInstance();
  • 6. Re: Load interfaced classes from jars
    EJP Guru
    Currently Being Moderated
    But you don't need to do that. You just need to call DriverManager.getConnection() with an appropriate URL. It will do all the classpath searching for you. You don't have to do anything with the Driver class whatsoever.
  • 7. Re: Load interfaced classes from jars
    809019 Newbie
    Currently Being Moderated
    But, I'm loading from external Jars... and the Drivers haven't been registered.
  • 8. Re: Load interfaced classes from jars
    EJP Guru
    Currently Being Moderated
    JDBC driver registration is a thing of the past, as I've said about six times already. To get DriverManager to use JARs that aren't on the CLASSPATH, if that's what you're trying to do (why?) you might have to create that class loader and set the thread context classloader to it, with the current thread context classloader as its parent. Or you might have to flip yourself into a context that uses that classloader some more way: not really my area.
  • 9. Re: Load interfaced classes from jars
    jtahlborn Expert
    Currently Being Moderated
    EJP wrote:
    JDBC driver registration is a thing if the past, as I've said about six times already.
    this is only true if the jdbc driver in question correctly uses the ServiceLoader framework.
    That_Gui wrote:
    But, I'm loading from external Jars... and the Drivers haven't been registered.
    by "external" jars, do you mean jars not on the classpath?
  • 10. Re: Load interfaced classes from jars
    809019 Newbie
    Currently Being Moderated
    Jar files in a folder, I wan't to dynamically load the jar files, without knowing the class names, purely by using the java.sql.Driver interface.

    I have done something similar in C#, but with my own interface, like a plugin system, I don't think Java should be less capable or is less capable then a second rate language like C#.

    Netbeans allows one to add a Driver via a jar file, it automatically picks up the Driver class name, and an example of the URL. Is it pre-determined? Does the Jar contain this information? That is what I'm trying to establish.

    I know that I can get the Driver by using Reflection with the java.sql.Driver interface, but how?

    I just want to create instances of Driver's from a couple of Jar's in a folder.
    List<Driver> drivers = new ArrayList();
    
    drivers.add(/* jt400.jar com.ibm.as400.jdbc.AS400JDBCDriver.class */);
    drivers.add(/* derby.jar org.apache.derby.jdbc.EmbeddedDriver.class */);
    
    drivers.get(1).connect(/* URL */);
    Along the lines of that.
  • 11. Re: Load interfaced classes from jars
    809019 Newbie
    Currently Being Moderated
    http://stackoverflow.com/questions/435890/find-java-classes-implementing-an-interface

    I think the ServiceLoader is the answer to creating instances of interfaces that are contained within Jar files.
  • 12. Re: Load interfaced classes from jars
    jtahlborn Expert
    Currently Being Moderated
    That_Gui wrote:
    http://stackoverflow.com/questions/435890/find-java-classes-implementing-an-interface

    I think the ServiceLoader is the answer to creating instances of interfaces that are contained within Jar files.
    you still haven't answered my question. it is an important question, because it makes the problem more difficult depending on the answer. are the jars part of the application classpath?

    Aside from that, there are generally 2 ways to load jdbc drivers.

    Newer drivers can "automatically" be loaded (as EJP already indicated). this automatic loading uses the ServiceLoader mechanism under the hood. if you have a jdbc driver with the appropriate ServiceLoader entries on the application classpath, then you don't have to do anything "extra", just use the correct jdbc url and the driver will be automatically loaded.

    For older drivers, there was an extra step where you needed to manually load the class first using
    Class.forName("driverClassName")
    this causes the driver to register itself with the jdbc driver manager such that when you use the relevant jdbc url, your driver will be loaded. like the previous option, this assumes that the driver is already on the application classpath.

    If, however, the jar is not part of the application classpath, then everything becomes more complicated. you must create a separate ClassLoader with the appropriate jars and work from there. (and jdbc drivers are particularly difficult to load from separate ClassLoaders due to "special" behavior in the DriverManager).

    as a side note, in none of these situations requires doing anything reflective with the "java.sql.Driver" class.
  • 13. Re: Load interfaced classes from jars
    809019 Newbie
    Currently Being Moderated
    Sorry... the Jars are definitely not in the classpath.
  • 14. Re: Load interfaced classes from jars
    809019 Newbie
    Currently Being Moderated
    Could I just add "./<Librarys Folder>/*.jar" to the classpath and then use this below?
    DriverManager.getConnection(/* URL */);
1 2 Previous Next

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points