Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding Installed JDBC Drivers

Tags:

java

jdbc

I'm writing a database validation tool in Java and have preference screens so the user can define their database connections. The tool should be able to cope with DB2, Oracle, Postgresql and Mysql as a minimum.

What I would really like is to be able to present the user with a list of their installed jdbc drivers as part of this process.

Can anyone supply a code snippet for discovering installed JDBC drivers ?

like image 904
Steve De Caux Avatar asked Dec 03 '09 12:12

Steve De Caux


2 Answers

To the point, you need to scan the entire classpath (and subfolders) for classes implementing java.sql.Driver. This way you will also cover drivers which are not loaded manually by Class#forName() or automagically by META-INF/services.

Here's a basic example:

public static void main(String[] args) throws Exception {
    List<Class<Driver>> drivers = findClassesImplementing(Driver.class);
    System.out.println(drivers);
}        

public static <T extends Object> List<Class<T>> findClassesImplementing(Class<T> cls) throws IOException {
    List<Class<T>> classes = new ArrayList<Class<T>>();

    for (URL root : Collections.list(Thread.currentThread().getContextClassLoader().getResources(""))) {
        for (File file : findFiles(new File(root.getFile()), ".+\\.jar$")) {
            JarFile jarFile = new JarFile(file);
            for (JarEntry jarEntry : Collections.list(jarFile.entries())) {
                String name = jarEntry.getName();
                if (name.endsWith(".class")) try {
                    Class<?> found = Class.forName(name.replace("/", ".").replaceAll("\\.class$", ""));
                    if (cls.isAssignableFrom(found)) {
                        classes.add((Class<T>) found);
                    }
                } catch (Throwable ignore) {
                    // No real class file, or JAR not in classpath, or missing links.
                }
            }
        }
    }

    return classes;
}

public static List<File> findFiles(File directory, final String pattern) throws IOException {
    File[] files = directory.listFiles(new FileFilter() {
        public boolean accept(File file) {
            return file.isDirectory() || file.getName().matches(pattern);
        }
    });

    List<File> found = new ArrayList<File>(files.length);

    for (File file : files) {
        if (file.isDirectory()) {
            found.addAll(findFiles(file, pattern));
        } else {
            found.add(file);
        }
    }

    return found;
}

Instead you can also consider to use the Google Reflections API which does this all in a single line:

Set<Class<? extends Driver>> drivers = reflections.getSubTypesOf(Driver.class);
like image 138
BalusC Avatar answered Sep 19 '22 21:09

BalusC


This should help:

java.sql.DriverManager.getDrivers()
like image 35
Kico Lobo Avatar answered Sep 17 '22 21:09

Kico Lobo