开发者

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开发者_如何学Python 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);


This should help:

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜