我正在用Java編寫一個數據庫驗證工具,並具有首選項屏幕,因此用戶可以定義它們的數據庫連接。該工具應該至少能夠處理DB2,Oracle,Postgresql和Mysql。查找已安裝的JDBC驅動程序
我真正想要的是能夠向用戶顯示安裝的jdbc驅動程序列表,作爲此過程的一部分。
任何人都可以提供用於發現已安裝的JDBC驅動程序的代碼片段嗎?
我正在用Java編寫一個數據庫驗證工具,並具有首選項屏幕,因此用戶可以定義它們的數據庫連接。該工具應該至少能夠處理DB2,Oracle,Postgresql和Mysql。查找已安裝的JDBC驅動程序
我真正想要的是能夠向用戶顯示安裝的jdbc驅動程序列表,作爲此過程的一部分。
任何人都可以提供用於發現已安裝的JDBC驅動程序的代碼片段嗎?
至此,您需要掃描整個類路徑(和子文件夾)以實現java.sql.Driver
的類。這樣,您還將涵蓋的驅動程序是而不是由Class#forName()
手動加載或由META-INF/services
自動加載。
這裏有一個基本的例子:
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;
}
相反,你也可以考慮使用哪個,這一切在一個單一的線Google Reflections API:
Set<Class<? extends Driver>> drivers = reflections.getSubTypesOf(Driver.class);
這應有助於:
java.sql.DriverManager.getDrivers()
由於這是恕我直言不正確接受,我只是會強調更多:這隻適用*如果驅動程序實際上**加載;可以通過'Class#forName()'手動地或'META-INF/services'自動地進行。這不會檢測哪些*是在classpath中的驅動程序,但它們是* not *加載的。 – BalusC 2009-12-03 14:03:28
java.sql.DriverManager.getDrivers()
還不是全部。
由於doc說
檢索與所有的 當前已加載JDBC驅動程序 枚舉當前調用者可以訪問。
這意味着加載的驅動程序(與Class.forName()),未安裝(通過JAR可用)。
通常情況下,您需要爲您的軟件提供您的程序可以工作的所有JDBC驅動程序罐。依賴於用戶將連接到(oracle,access,db2)程序必須加載相應的驅動程序。
我的印象是,在我自己的罐子裏分發第三方驅動程序會違反版權 - 或者任何合法的東西 – 2009-12-03 13:43:37
實際上它會包含通過'jdbc.drivers'系統屬性引用的驅動程序和通過服務提供程序提供的驅動程序( META-INF/services')機制。 – 2009-12-03 13:44:19
在這個解決方案中,你不是在正在測試的類上執行靜態塊嗎? – 2009-12-03 15:31:09
是的,他們會被執行。你無法繞過那個。 – BalusC 2009-12-03 15:37:58
Thx bigtime,BalusC – 2009-12-03 17:48:50