Использование API поиска за пределами платформы NetBeans

Я пытаюсь оценить, уместно ли для нашего магазина использовать API поиска NetBeans без всей платформы NetBeans.

До сих пор мне удалось создать проект с этим кодом:

 for (SomeInterface si : Lookup.getDefault().lookupAll(SomeInterface.class)) {
     si.doSomething();
 }

Я также создал пару других проектов, каждый с классом AnImplementation, реализующим SomeInterface, и сопровождающим файлом META-INF/services/path.to.SomeInterface, содержащим строку, ссылающуюся на класс (например, «other.path.to.AnImplementation» ).

Когда я добавляю эти реализующие проекты в библиотеки (зависимости) основного проекта в среде IDE NetBeans, все работает нормально, и я вижу последовательные результаты doSomething() из обеих реализаций.

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

Если я не ошибаюсь, это поведение рекламируется в документации Lookup API. Заранее спасибо.

Изменить. На данный момент я пришел к выводу, что без платформы NetBeans (или OSGi?) невозможно определить, какие поставщики услуг присутствуют во время запуска. Вам нужно ссылаться на их банки в вашем пути к классам и, таким образом, идентифицировать их перед запуском. Не стесняйтесь доказывать, что я ошибаюсь.


person Manur    schedule 30.05.2011    source источник


Ответы (2)


Вы должны ссылаться на подпроект в вызывающем приложении, так как это помещает его в путь к классам. Если jar/библиотека не находится в пути к классам, то такие API, как Lookup и ServiceLoader, не смогут его найти.

Если вы используете OSGI или платформу NetBeans, эти системы позволяют изменять путь к классам во время выполнения.

В в блоге Geertjans есть запись именно об этом (с использованием API поиска за пределами платформы NetBeans). ), в своем блоге он также ссылается на блог Джона О'Коннорса что отличает API ServiceLoader и Lookup

ИЗМЕНИТЬ

Я только что видел ответ Джона Скитса на похожий вопрос. Вы можете использовать свойство -Djava.ext.dirs=lib, чтобы установить папку (в данном случае «libs») в качестве места, где он должен искать банки для вашего пути к классам.

person Tim Sparg    schedule 31.05.2011
comment
Я попытался использовать блог Джона О'Коннорса, чтобы провести тест. . - person Manur; 31.05.2011
comment
(извините) ... в проекте DictionaryService/DictionaryUser я создал папку lib/ (на корневом уровне проекта). Я добавил lib/ в путь к классам проекта благодаря «Свойства»> «Добавить JAR или папку». Я скопировал GeneralDictionary.jar в lib/. Но этот провайдер не был обнаружен... - person Manur; 31.05.2011
comment
Это вводит в заблуждение — NetBeans не позволяет вам ссылаться только на папку, вы должны ссылаться на все jar-файлы, которые хотите использовать. Это можно сделать из командного файла, однако есть одно предостережение: вы не можете использовать java -jar для запуска вашего приложения, ваш синтаксис должен быть java -cp lib/*;yourapplication.jar com.my.example. StartApp - person Tim Sparg; 31.05.2011
comment
Ссылка на статью О'Коннера не работает. Теперь он находится здесь. - person predi; 11.10.2013

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

  • использование ServiceLoader напрямую лучше подходит для вашей проблемы или
  • некоторые фреймворки DI, такие как Guice, стоит попробовать или
  • если OSGI предлагает что-то полезное и для вас, используйте это.

Не поймите меня неправильно, я очень люблю NetBeans и платформу NetBeans, но, по моему мнению, использование только Lookup имеет ограниченное применение из-за перечисленных выше возможностей.

person Waldheinz    schedule 30.05.2011
comment
Спасибо за ответ. Мы также рассмотрим ServiceLoader, но его ограничение для JDK6 может не соответствовать нашим требованиям. Будет использоваться структура DI, но, если я правильно понимаю, она должна знать, какие классы доступны во время разработки/упаковки. Вариант использования, который я пытаюсь здесь протестировать, — это приложение, которое работает одинаково, независимо от того, есть какой-то jar-модуль или нет, и само адаптируется. - person Manur; 31.05.2011
comment
Lookup существовал до serviceLoader, поэтому вы можете использовать его, например, в java 1.4. - person Tim Sparg; 31.05.2011
comment
@ Тим, я знаю, я просто подумал, что в наши дни это не аргумент, когда даже 1,5 устарели. Но вы правы, если вы пишете программное обеспечение для жизни, вам приходится иметь дело с ... интересными установками. - person Waldheinz; 31.05.2011