JVM をロードして OSGi フレームワークを起動する C++ プログラムがあります。OSGi フレームワークは Equinox、より正確にはorg.eclipse.osgi_3.8.1.v20120830-144521.jar
です。
ランチャー
OSGi ランチャーは、JNI を使用して C++ から呼び出され、次のようになります (簡潔にするために詳細は省略されています)。
// Create OSGi framework.
final ServiceLoader<FrameworkFactory> frameworkFactoryLoader =
ServiceLoader.load(FrameworkFactory.class);
final FrameworkFactory frameworkFactory =
getFrameworkFactory(frameworkFactoryLoader);
final Map<String, String> osgiConfig = ...
final Framework osgiFramework = frameworkFactory.newFramework(osgiConfig);
// Start the framework.
osgiFramework.start();
// Install some bundles.
final BundleContext frameworkBundleContext = osgiFramework.getBundleContext();
final Bundle bundle1 =
installBundle(frameworkBundleContext, "reference:" + bundle1URI, null);
installBundle(frameworkBundleContext, "reference:" + bundle2URI, 5);
installBundle(frameworkBundleContext, "reference:" + bundle3URI, 10);
...
// Explicitly starting a particular bundle.
bundle1.start();
...
// Raise the framework start level so bundles are started
// at the desired start levels.
final FrameworkStartLevel frameworkStartLevelObject =
bundleAdapt(systemBundle, FrameworkStartLevel.class);
frameworkStartLevelObject.setStartLevel(10, ...left-out...);
バンドルをインストールするためのヘルパー関数は次のようになります。
private Bundle installBundle(final BundleContext frameworkBundleContext,
final String bundleURI,
final Integer desiredStartLevel) {
final Bundle bundle = frameworkBundleContext.installBundle(bundleURI);
if (desiredStartLevel != null) {
// Set the level at which the bundle should start.
// (Otherwise, it will start at the default level.)
final BundleStartLevel bundleStartLevel =
bundleAdapt(bundle, BundleStartLevel.class);
bundleStartLevel.setStartLevel(desiredStartLevel);
}
}
これで、すべてのバンドルが解決されRESOLVED
、ACTIVE
またはのいずれかのSTARTED
状態になります。
で始まりますosgi.clean=true
osgi.clean=true
マップのオプションを使用して OSGi フレームワークを開始し、osgiConfig
インストールされているバンドルを実行ごとに変更すると、フレームワークにうまく反映されます。
たとえば、bundleX と bundleY を使用してフレームワークを開始し、呼び出す場合
frameworkBundleContext.getBundles();
それから私は正確に見ます
- システムバンドル (
ACTIVE
) - バンドルX (
RESOLVED
) - バンドルY (
RESOLVED
)
プログラムをシャットダウンして、今度は bundleX と bundleZ で再試行すると、(驚くことではありません)
- システムバンドル (
ACTIVE
) - バンドルX (
RESOLVED
) - バンドルZ (
RESOLVED
)
なしで開始osgi.clean
マップに設定せずに OSGi フレームワークを開始するとosgi.clean
、osgiConfig
インストールされたバンドルが実行から実行へと残り、新しいバンドルが解決されません。
したがって、bundleX と bundleY をロードして 1 回実行osgi.clean=true
し、プログラムをシャットダウンするとします。
ここで、再起動せずosgi.clean
に bundleZ のみをインストールすると、次のように表示されます。
- システムバンドル (
ACTIVE
) - バンドルX (
RESOLVED
) - バンドルY (
RESOLVED
) - bundleZ (
INSTALLED
) (つまり、まだ解決されていない)
したがって、bundleX と bundleY は、2 回目にインストールする必要なく、ある実行から別の実行まで存続しました。
一方、bundleZ は自動的に解決されません。RESOLVED
状態にするには、これを行う必要があります。
final FrameworkWiring frameworkWiring = systemBundle.adapt(FrameworkWiring.class);
frameworkWiring.resolveBundles(null);
質問: 使用するosgi.clean
必要がありますか?
osgi.clean=true
使用すると毎回新鮮なスタートが切れるようですが、使用しないと、バンドルの状態が実行ごとに存続することになります。キャッシングによりOSGiの起動が速くなると思いますが、私にとっては大したことではないようです(「参照:」プレフィックスを使用してバンドルをインストールするため、jarはキャッシュにコピーされず、元の参照のみが参照されます)ファイルの場所は保持されます)。
ただし、私のアプリケーションは、同じ OSGi 構成領域に対して実行されるマルチプロセス アプリケーションです。osgi.clean=true
この状況で常に実行するのは問題ですか?
osgi.clean
また、 OSGi (Equinox) でのキャッシングの正確な意味と仕組みについて、適切な説明を誰かが教えてくれれば、私は感謝します。