Как написать приложение командной строки OSGI
В настоящее время я намочил ноги от OSGI и решил пойти на слегка нетипичный сценарий использования OSGI. Я хотел бы использовать его в приложении командной строки. я хочу main(..)
метод, который принимает некоторые флаги и аргументы, что-то делает и снова выключается. Чего я не хочу, так это запускать Apache Karaf (или аналогичный) и запускать команды в консоли OSGI (хотя это может стать дополнительной функцией).
Почему OSGI для приложения командной строки в первую очередь? Предполагается, что приложение будет использовать разные версии одной и той же библиотеки (то есть эластичного поиска). И просто потому, что это плохо, конечно.
Должен ли я использовать услугу в комплекте или снаружи? Как можно это сделать? Какие проблемы могут возникнуть?
2 ответа
Существует очень простой способ написания приложений командной строки при использовании bnd. В bnd есть функция для создания исполняемого файла jar с помощью команды package:
$ bnd run xyz.bnd
.... whatever your app does
$ bnd package xyz.bnd
$ ls
xyz.jar xyz.bnd .....
$ java -jar xyz.jar ...
.... whatever your app does
Обратите внимание, что этот файл jar завершен, он содержит ВСЕ пакеты, фреймворк, модуль запуска и свойства для его запуска. Нет внешних зависимостей.
Хитрость заключается в том, чтобы получить основной поток (где вызывается статический основной). Единственное, что вам нужно сделать, это зарегистрировать сервис Runnable со свойством main.thread=true
, После этого программа запуска вызовет run() для этой службы и завершит работу (вы можете оставаться в беге столько времени, сколько захотите).
Чтобы получить аргументы командной строки, вы можете получить сервис Object с launcher.arguments
имущество. Это свойство будет иметь аргументы вашей команды. Или сделать это с помощью компонента DS:
@Component(immediate=true, property="main.thread=true")
public class Main implements Runnable {
String[] args;
public void run(){ ... }
@Reference(target="(launcher.arguments=*)")
void setArgs(Object service, Map<String,Object> props) {
this.args = (String[]) props.get("launcher.arguments");
}
}
Лучший способ сделать это - использовать bndtools, поскольку он позволяет легко тестировать / отлаживать ваш код. Вы, вероятно, хотите использовать файлы bndrun.
PS В последней версии bnd вы можете использовать Callable
Чтобы ответить на мой собственный вопрос ( стиль вопросов и ответов): в настоящее время я считаю, что было бы лучше
- запустить OSGI встроенный (чистый)
- запустить контейнер
- пакет API экспорта (
org.osgi.framework.system.packages.extra
) - установить и запустить необходимые пакеты
- потреблять услуги за пределами OSGI
- закрыть контейнер
- выйти из приложения
После запуска всех пакетов можно с уверенностью предположить, что необходимые сервисы доступны. Это также позволяет избежать передачи конфигурации в OSGI, который фактически является только аргументами для вызова службы.