2009-12-03 11 views
7

मैं जावा में डेटाबेस सत्यापन उपकरण लिख रहा हूं और वरीयता स्क्रीन है ताकि उपयोगकर्ता अपने डेटाबेस कनेक्शन को परिभाषित कर सके। उपकरण कम से कम डीबी 2, ओरेकल, पोस्टग्रेस्क्ल और माइस्क्ल से निपटने में सक्षम होना चाहिए।स्थापित जेडीबीसी ड्राइवर्स ढूँढना

मुझे वास्तव में क्या पसंद है यह इस प्रक्रिया के हिस्से के रूप में उपयोगकर्ता को अपने स्थापित जेडीबीसी ड्राइवरों की एक सूची के साथ प्रस्तुत करने में सक्षम होना है।

क्या कोई भी स्थापित जेडीबीसी ड्राइवरों की खोज के लिए कोड स्निपेट की आपूर्ति कर सकता है?

उत्तर

9

बिंदु पर, आपको 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); 
+0

इस समाधान में, आप जिन कक्षाओं का परीक्षण कर रहे हैं उन पर स्थिर ब्लॉक निष्पादित नहीं कर रहे हैं? –

+0

हां, वे निष्पादित हो जाएंगे। आप उसके चारों ओर नहीं जा सकते। – BalusC

+1

Thx bigtime, बलुस –

3

यह मदद करनी चाहिए:

java.sql.DriverManager.getDrivers() 
+6

इस के बाद से है IMHO गलत तरीके से स्वीकार किए जाते हैं, मैं सिर्फ होगा अधिक जोर दें: यह * केवल * काम करता है यदि ड्राइवर ** वास्तव में ** लोड होते हैं; मैन्युअल रूप से 'मेटा-आईएनएफ/सेवाओं 'द्वारा' कक्षा # के लिए नाम()' या स्वचालित रूप से 'मैन्युअल रूप से' द्वारा। यह क्लासपाथ में * ड्राइवर * का पता नहीं लगाता है, लेकिन जो * लोड नहीं होते हैं। – BalusC

3
java.sql.DriverManager.getDrivers() 

सब नहीं है।

doc के रूप में कहते हैं

को वर्तमान में लोड JDBC चालकों के सभी के साथ एक गणन जो वर्तमान फोन करने वाले पहुंच है पुन: प्राप्त करता।

इसका मतलब है कि लोड किए गए ड्राइवर (क्लास.forनाम() के साथ) स्थापित नहीं है (एक जार के माध्यम से उपलब्ध कहें)।

आम तौर पर आप अपने सॉफ्टवेयर को सभी जेडीबीसी ड्राइवर जार के साथ वितरित करेंगे जो आपका प्रोग्राम काम कर सकता है। आश्रित जो उपयोगकर्ता कनेक्ट करेगा (ऑरैकल, एक्सेस, डीबी 2) प्रोग्राम को एप्रोपीएटेड ड्राइवर लोड करना होगा।

+1

मैं इस धारणा के तहत था कि अपने स्वयं के जारों में तीसरे पक्ष के ड्राइवरों को वितरित करना कॉपीराइट का उल्लंघन करेगा - या फिर कुछ कानूनी –

+1

असल में इसमें 'jdbc.drivers' सिस्टम प्रॉपर्टी के माध्यम से संदर्भित ड्राइवर शामिल होंगे और सेवा प्रदाता के माध्यम से उपलब्ध कराए गए ड्राइवर शामिल होंगे ('मेटा-आईएनएफ/सेवाएं') तंत्र। –