2012-05-16 3 views
1

У меня есть приложение, которое работает с jdbc. Предполагается, что он будет использоваться на любом ПК, где есть JRE, но он не предполагает, что использование будет использовать командную строку -cp или изменить его/ее переменные pathpath. Таким образом, у пользователя есть мое приложение, JRE и драйвер jdbc где-то в файловой системе. Теперь он или она вводит информацию о соединении с базой данных, включая путь к jdbc jar, а затем делает запрос sql. Проблема в том, что я не сейчас, как сделать классы jdbc-драйверов доступными в этом приложении. Точно так же, как пользователь явно добавляет драйвер в classpath.Загрузка классов из приложения из файловой системы во время выполнения

+0

Если ваше приложение. имеет графический интерфейс, поставляйте его вместе с драйвером, используя [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. Он использует структуру JDBC, а не мой код напрямую. Из моих результатов могу сказать, что это не сработает. И я считаю, что ваш код работает. – itun

+0

Можете ли вы показать мне пример, где ваш код использует com.mysql.jdbc.Driver (make import com.mysql.jdbc.Driver), скомпилированный с этой зависимостью, но вы запускаете приложение без этой банки в вашем пути к классам и загружаете эту банку во время выполнения? – itun

+0

@itun - Нам не нужно явно импортировать драйвер базы данных. Если вы не хотите знать какую-либо конкретную информацию о драйвере, такую ​​как 'DriverPropertyInfo',' version' и т. Д., Вам не требуется ссылочная переменная для * специфического * jdbc-драйвера. Если у вас есть один, и если этот класс не находится в пути класса, доступного для поиска, он, очевидно, терпит неудачу. Это означает, что у вас не должно быть таких прямых ссылок, как «' pkgd.Driver driver = (pkgd.Driver) Class.forName (... '". Прочитайте заметки в 'java.sql.DriverManager', в котором предлагаются способы избежать *' Class.forName() '*, то есть вы можете не требовать загрузки контейнера соединителя из настраиваемого пути. –

1

Лучшим решением в этом случае было бы распространение необходимого драйвера с вашим приложением и включение либо исполняемой оболочки, либо скрипта оболочки, который соответствующим образом устанавливает необходимые переменные. Это позволяет пользователю использовать его из коробки без необходимости возиться со сложной конфигурацией, а также не требует, чтобы они загружали дополнительные файлы.

+0

Я не могу этого сделать. Любые другие решения? – itun

+0

@itun, вам нужно как-то поставить драйвер или сказать им, чтобы загрузить его. Вы можете искать в нем файловую систему, но это не идеальное решение –

+0

@itun, а почему бы и нет? –

0

Ну, jdbc использует Class.forName("org.postgresql.Driver"); для загрузки драйвера. Итак, однажды у вас есть файл jar и добавили его в класс-путь, эта часть проста. Просто сохраните хэш драйверов fqn classnames для имени файлов jar. Или вы можете сканировать банку для класса Driver.

Here's a convienent ответ на вопрос о том, как добавить файл jar в путь к классам, как только вы его найдете.

+0

Вот что я точно сделал: http://stackoverflow.com/questions/10624907/loading-jars-at-runtime. Но по какой-то причине это не сработает. – itun

+0

Какая ошибка? –

+0

java.lang.ClassNotFoundException, когда я использую этот класс.forName ("com.mysql.jdbc.Driver") – itun