2012-05-16 79 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