Я создал пакет, в котором есть файл Activator, который в основном запускает другие пакеты по их правильному порядку. Я нуждался в этом, потому что Framework запустил некоторые пакеты до завершения их зависимостей. Например, мои пакеты в зависимости от моей службы журналов начнутся до этого, поэтому сообщения журнала не будут храниться для этих пакетов. С помощью этого активатора я могу выбрать, кто начнет сначала, так как нет четкого способа сделать это в felix.Как правильно запустить и закрыть контейнер OSGi?
Код для этого здесь:
package lumina.launcher;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
public final class Launcher implements BundleActivator {
private BundleContext context;
private final String relativePath = "./bundle/";
private final void print(String msg) {
// System.out.println(msg);
}
private Bundle install(String path) throws BundleException {
Bundle bundle = this.context.installBundle("file:/" + path);
print("\tInstalling: " + bundle.getSymbolicName());
return bundle;
}
private boolean isJar(String fileName) {
final String[] tokens = fileName.split("\\.");
return tokens.length != 0 && "jar".equals(tokens[tokens.length - 1]);
}
private String[] listFilesForFolder(final File folder)
throws BundleException {
final List<String> bundles = new ArrayList<String>();
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesForFolder(fileEntry);
} else {
if (isJar(fileEntry.getName())) {
bundles.add(fileEntry.getAbsolutePath().replace(
File.separatorChar, '/'));
}
}
}
return bundles.toArray(new String[0]);
}
@Override
public void start(BundleContext context) throws Exception {
this.context = context;
installStart("third-party");
installStart("shared-components");
installStart("lumina");
installStart("webconsole");
System.out
.println("-> You can access Felix WebConsole at http://localhost:8080/system/console");
Thread.sleep(2000);
installStart("plugins");
}
private final void installStart(String path) throws BundleException {
print("Installing " + path);
final String[] targetBundles = listFilesForFolder(new File(relativePath
+ path));
final Bundle[] bundles = new Bundle[targetBundles.length];
for (int i = 0; i < targetBundles.length; i++) {
bundles[i] = install(targetBundles[i]);
}
print("\tStarting installed bundles...");
for (Bundle b : bundles)
b.start();
}
@Override
public void stop(BundleContext arg0) throws Exception {
}
}
И это, как я организовал свои связки в Феликси расслоении/папки.
C:\felix\BUNDLE
│ .gitignore
│ lumina.launcher-1.0.0-SNAPSHOT.jar
│
├───lumina
│ .gitignore
│ lumina.api-0.0.4-SNAPSHOT.jar
│
├───plugins
│ .gitignore
│ lumina.assembler-0.0.1-SNAPSHOT.jar
│ lumina.extensions.drivers.ip-0.0.1-SNAPSHOT.jar
│ lumina.rest-0.0.4-SNAPSHOT.jar
│ shared.extensions.base.logger-1.0.2-SNAPSHOT.jar
│ smartcampuskndriver.gateway-0.0.1-SNAPSHOT.jar
│ smartcampusmetersip.gateway-0.0.1-SNAPSHOT.jar
│
├───shared-components
│ codebase-2.0.0.jar
│ shared.osgi.services-1.3.0-SNAPSHOT.jar
│ shared.osgi.services.logger-1.0.0-SNAPSHOT.jar
│ shared.properties.api-5.2.1-SNAPSHOT.jar
│
├───third-party
│ com.googlecode.json-simple_1.1.0.jar
│ org.apache.felix.bundlerepository-2.0.2.jar
│ org.apache.servicemix.bundles.joda-time-2.3_1.jar
│ org.apache.servicemix.bundles.junit-4.11_1.jar
│ org.osgi.compendium-1.4.0.jar
│ org.osgi.core-1.4.0.jar
│ org.restlet.ext.json_2.1.0.M1.jar
│ org.restlet.jse.org.restlet.lib.org.json_2.0.0.jar
│ org.restlet_2.1.0.M1.jar
│ OSGiJMX.jar
│
├───unused
│ org.apache.felix.gogo.command-0.14.0.jar
│ org.apache.felix.gogo.runtime-0.12.1.jar
│ org.apache.felix.gogo.shell-0.10.0.jar
│
└───webconsole
org.apache.felix.http.api-2.3.2.jar
org.apache.felix.http.jetty-2.3.2.jar
org.apache.felix.http.servlet-api-1.0.1.jar
org.apache.felix.webconsole-4.2.4-all.jar
Обратите внимание, что lumina.launcher-1.0.0-SNAPSHOT.jar где моя Активатор и является единственным расслоением запускается автоматически Феликсом.
Это прекрасно работает, кстати, не знаю, есть ли более разумный способ сделать это. Таким образом, идея приведенного выше кода состоит в том, чтобы запустить все пакеты из каждой директории в следующем порядке: сторонние, общие компоненты, lumina, webconsole и плагины.
С другой стороны, когда я нажимаю^C на терминале, когда контейнер OSGi запущен, он начинает останавливать все пакеты один за другим. Это нормально, но служба журнала является одним из первых пакетов, которые нужно остановить, и я хочу, чтобы это был один из последних пакетов. Есть ли способ установить порядок блокировки пакетов при закрытии контейнера OSGi?
Спасибо!
Я должен установить заказ, и я думаю, что нереально не устанавливать порядок запуска. В моей ситуации у меня есть реестр регистрации журнала в пакете (A), затем у меня есть некоторые версии logger в другом комплекте (B), тогда у меня есть один пакет, который записывает материал (C). Одна вещь, которую OSGi никогда не сделает, - это запустить B перед запуском A. Однако он может запустить C перед запуском B. Таким образом C начнет записывать материал, прежде чем у меня будут установлены какие-либо реализации реестров. – PedroD
В моей ситуации OSGi запускает пакеты в порядке A, C и B, и все, что мне нужно, это запустить его как A, B и C. То же самое касается закрытия, правильным порядком для остановки пакетов будет C, B и A. Как определить начальные уровни в Felix Framework? – PedroD
Вы можете настроить felix для запуска пакетов с определенным начальным уровнем. См. Описание настройки конфигурации felix.auto.start. по адресу http://felix.apache.org/site/apache-felix-framework-configuration-properties.html. Также см. Описание других параметров конфигурации, в которых упоминается начальный уровень. –