Программно выполнять консольные команды OSGI

Может ли кто-нибудь привести рабочий пример того, как программно выполнять консольные команды OSGI?

Я загружаю OSGI через код и хочу выполнять консольные команды OSGI (я получаю команды через другую систему). Это то, что я делаю как простой тест:

ServiceLoader<FrameworkFactory> frameworkFactoryService = ServiceLoader.load(FrameworkFactory.class);
FrameworkFactory frameworkFactory = frameworkFactoryService.iterator().next();

Map<String, String> config = new HashMap<String,String>();
config.put("org.osgi.framework.storage", "../workspace/.config");
config.put("org.osgi.framework.storage.clean", "onFirstInit");

framework = frameworkFactory.newFramework(config);

framework.init();
framework.start();  

// install required bundles
String bundleLocation = "org.eclipse.equinox.common_3.8.0.20181108-1144.jar";
Bundle bundle = framework.getBundleContext().installBundle(bundleLocation);

bundleLocation = "org.eclipse.update.configurator_3.4.2.M20090103-1001-RCP20181108-1144.jar";
bundle = framework.getBundleContext().installBundle(bundleLocation);
bundle.start();

bundleLocation = "org.apache.felix.gogo.runtime_0.10.0.v201209301036.jar";
bundle = framework.getBundleContext().installBundle(bundleLocation);
bundle.start();

bundleLocation = "org.apache.felix.gogo.command_0.10.0.v201209301215.jar";
bundle = framework.getBundleContext().installBundle(bundleLocation);
bundle.start();

bundleLocation = "org.apache.felix.gogo.shell_0.10.0.v201212101605.jar";
bundle = framework.getBundleContext().installBundle(bundleLocation);
bundle.start();

bundleLocation = "org.eclipse.equinox.console_1.1.200.v20150929-1405.jar";
bundle = framework.getBundleContext().installBundle(bundleLocation);
bundle.start();

CommandProcessorImpl commandProcessor = new CommandProcessorImpl();
CommandSession commandSession = commandProcessor.createSession(System.in, System.out, System.err);

commandSession.execute("ss");

Все загружается правильно, и если я программно перебираю все пакеты, я вижу, что все загружено и запущено. К сожалению, я получаю исключение «Команда не найдена: ss» в строке «Выполнить». Что я делаю не так? У кого-нибудь есть простой рабочий пример?


person user2287359    schedule 18.06.2019    source источник


Ответы (1)


Вы сами начинаете CommandProcessImpl. Вместо этого вы должны получить услугу CommandProcessor. Созданный вами экземпляр не имеет подключения к платформе и поэтому не может найти команды, зарегистрированные как службы.

 BundleContext context = framework.getBundleContext();
 ServiceReference<CommandProcessor> cpr = 
     context.getServiceReference(CommandProcessor.class);
 CommandProcessor cp = context.getService(cpr);

 CommandSession session = cp.createSession(System.in, System.out, System.err);

 session.execute("lsb");

Ясно, что этот код не защищен. Получить справку об услуге, а затем получить услугу — это очень плохо, поскольку услуги могут приходить и уходить.

У bnd есть удаленный агент (biz.aQute.bnd.remote), который можно легко вызвать из внешнего процесса. У него также есть программа bndremote, которую вы можете запустить на любой машине, а затем загрузить фреймворк + пакеты на эту машину. Это может быть проще, чем построить это самостоятельно?

person Peter Kriens    schedule 18.06.2019
comment
Спасибо. Это было хорошим руководством. Мне не хватало связи между фреймворком и CommandProcessor, как было предложено в этом посте. Мне также пришлось использовать Reflection, так как мой код работает вне среды OSGI и должен использовать классы из пакетов внутри бандлов во время выполнения. На bnd тоже посмотрю. - person user2287359; 18.06.2019
comment
Если вам нужны команды, зарегистрируйте службу через фреймворк. Его заберут. Многое из того, что вы хотите сделать, было сделано много раз в самых разных условиях. Если это не хобби-проект, обратитесь за помощью, чтобы не изобретать велосипед и, что еще хуже, не делать много ошибок в этой области, подверженной ошибкам. Лаунчеры сложные! - person Peter Kriens; 19.06.2019