2012-05-16 129 views
1

我有一個應用程序處理jdbc。它假設在任何有JRE的PC中使用,但它不認爲使用將使用-cp命令行或更改他/她的類路徑變量。所以用戶有我的應用程序,JRE和文件系統中的某個jdbc驅動程序。現在他或她輸入數據庫連接信息,包括jdbc驅動程序jar的路徑,然後發出sql請求。問題是我現在不知道如何使jdbc驅動程序類在此應用程序中可訪問。與用戶明確將驅動程序添加到類路徑的方式相同。在運行時將文件系統中的類加載到文件系統中

+0

如果您的應用程序。有一個GUI,使用[Java Web Start](http://stackoverflow.com/tags/java-web-start/info)與驅動程序一起提供。這使用戶很容易。 –

回答

2

我剛剛更改了miks answer的部分內容以供您發佈。

執行下面的代碼讓我獲得了成功。

import java.io.File; 
import java.lang.reflect.Constructor; 
import java.net.URL; 
import java.net.URLClassLoader; 

public class URLClassLoaderSample { 
    public static void main(String [] args) throws Exception { 
    File f = new File("/home/ravinder/Desktop/mysql-connector-java-5.1.18-bin.jar"); 
    URLClassLoader urlCl = new URLClassLoader(new URL[] { f.toURL() }, System.class.getClassLoader()); 

    Class mySqlDriver = urlCl.loadClass("com.mysql.jdbc.Driver"); 
    System.out.println(mySqlDriver.newInstance()); 
    System.out.println("Is this interface? = " + mySqlDriver.isInterface()); 

    Class interfaces[] = mySqlDriver.getInterfaces(); 
    int i = 1; 
    for(Class _interface : interfaces) { 
     System.out.println("Implemented Interface Name " + (i++) + " = " + _interface.getName()); 
    } // for(...) 

    Constructor constructors[] = mySqlDriver.getConstructors(); 
    for(Constructor constructor : constructors) { 
     System.out.println("Constructor Name = " + constructor.getName()); 
     System.out.println("Is Constructor Accessible? = " + constructor.isAccessible()); 
    } // for(...) 
    } // psvm(...) 
} // class URLClassLoaderSample 

產出看如下:

[email protected] 
Is this interface? = false 
Implemented Interface Name 1 = java.sql.Driver 
Constructor Name = com.mysql.jdbc.Driver 
Is Constructor Accessible? = false 

And I don't understand what I should with log4jClass variable in my case *(com.mysql.jdbc.Driver)
現在讓我希望你得到它。

+0

我仍然無法這樣做,因爲我沒有創建或使用jdbc Driver執行某些操作。它使用JDBC框架,而不是我的代碼直接。從我的結果中我可以說它不起作用。我相信你的代碼有效。 – itun

+0

你能告訴我你的代碼中使用com.mysql.jdbc.Driver(使進口com.mysql.jdbc.Driver)與這種依賴性編譯的例子,但是你沒有這個罐子啓動應用程序在類路徑中,並加載這個jar在運行時? – itun

+0

@itun - 我們不需要顯式地導入數據庫驅動程序。除非你想知道'DriverPropertyInfo','version'等一些驅動程序的具體信息,否則你不需要* specific * jdbc驅動程序的引用變量。如果你有一個,如果這個類不在可搜索的類路徑中,它顯然會失敗。這意味着你不應該有像''pkgd.Driver driver =(pkgd.Driver)Class.forName(...'「)那樣的直接引用。請閱讀'java.sql.DriverManager'的註釋,它建議避免*' Class.forName()'*即你可能不需要從自定義路徑加載連接器jar。 –

1

在這種情況下,最好的解決方案是將所需的驅動程序與應用程序一起分發,幷包含一個可執行的包裝器或一個相應設置所需變量的shell腳本。這使得用戶可以在不使用任何複雜配置的情況下使用它,並且不需要它們下載任何附加文件。

+0

我不能那樣做。其他解決方案? – itun

+0

@itun,以及你需要以某種方式提供驅動程序,或告訴他們下載它。您可以搜索文件系統,但這不是一個完美的解決方案 –

+0

@itun,爲什麼不呢? –

0

那麼,jdbc使用Class.forName("org.postgresql.Driver");加載驅動程序。所以有一次,你有jar文件,並將它添加到類路徑,這部分很容易。只需將驅動程序fqn類名的哈希值保存爲jar文件名即可。或者您可以掃描Driver類的jar。

Here's a convienent回答如何將jar文件添加到類路徑中,一旦找到它。

+0

這正是我所做的:http://stackoverflow.com/questions/10624907/loading-jars-at-runtime。但由於某種原因,它不起作用。 – itun

+0

什麼是錯誤? –

+0

當我使用這個Class.forName(「com.mysql.jdbc.Driver」)時,java.lang.ClassNotFoundException – itun