OSGi Felix и BndTools — загрузка класса по имени

В моей среде OSGi я пытаюсь предварительно загрузить драйвер базы данных для дальнейшего использования. Обычно это можно сделать так:

Class.forName("com.mysql.jdbc.Driver");

После этого можно создать соединение. Однако, если я использую это в OSGi под Феликсом, он говорит, что класс не может быть найден (ClassNotFoundException) и соединение не может быть создано. Но когда я делаю что-то подобное (try-catch опущено):

com.mysql.jdbc.Driver d = new com.mysql.jdbcDriver
Class.forName("com.mysql.jdbc.Driver");

Тогда все работает нормально и соединение создается. Однако это не очень красиво, потому что класс драйвера не может быть заменен.

Есть ли способ загрузить класс первым методом? Я предполагаю, что я должен предоставить правильный загрузчик классов. Но откуда я это взял?

Драйвер MySQL предоставляется в виде пакета оболочки OSGi.


person Nico Schertler    schedule 05.03.2012    source источник
comment
Никогда не нужно загружать класс динамически с помощью Class.forName, если у вас есть имя класса в исходном коде. Динамическую загрузку класса следует использовать ТОЛЬКО в том случае, если вы получаете имя класса через механизм времени выполнения.   -  person Peter Kriens    schedule 06.03.2012


Ответы (2)


Как именно вы создаете свой манифест пакета? Если вы используете инструменты для автоматического разрешения операторов импорта OSGi вашего пакета, они потерпят неудачу при первом методе, поскольку они не распознают простую строку как зависимость пакета. Второй метод выражает зависимость как жесткую зависимость Java, поэтому она распознается инструментом, который добавляет требуемый оператор импорта OSGi (и, таким образом, средой выполнения OSGi в путь к классам вашего пакета).

Итак, чтобы ваш первый метод заработал, вы должны добавить зависимость пакета com.mysql.jdbc к операторам импорта OSGi вашего пакета. Как это достигается, зависит от инструмента, Bnd использует параметр конфигурации Import-Statement.

person Heri    schedule 05.03.2012

Все, что @Heri сказал в своем ответе, было правильным. Однако, если вы хотите сделать эту систему более гибкой, используйте службы OSGi.

Вы хотите установить соединение с базой данных, но не хотите жестко связывать свой код с конкретной базой данных или драйвером JDBC. Почему бы не написать небольшой пакет-оболочку JDBC, который публикует javax.sql.DataSource сервис? Затем ваш пакет логики может связываться со службой, когда он хочет запросить базу данных, и ему не нужно ничего знать о физическом соединении с базой данных.

Обратите внимание, что пакет оболочки JDBC должен знать о конкретном драйвере JDBC, однако это будет чрезвычайно тонкий пакет, и вы можете создать альтернативные оболочки для каждого из драйверов, которые вы, возможно, захотите использовать.

person Neil Bartlett    schedule 06.03.2012