简体   繁体   中英

Finding Installed JDBC Drivers

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 ?

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);

这应该有所帮助:

java.sql.DriverManager.getDrivers()
java.sql.DriverManager.getDrivers()

is not all.

As the doc says

Retrieves an Enumeration with all of the currently loaded JDBC drivers to which the current caller has access.

That means loaded drivers (with Class.forName()), not installed (say available thru a JAR).

Normally you would deliver your software with all JDBC driver jars that your program can work. Dependent what the user will connect to (oracle, access, db2) the program must load the appropiated driver.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM