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);
This should help:
java.sql.DriverManager.getDrivers()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With