1

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);
    }
}

これで、すべてのバンドルが解決されRESOLVEDACTIVEまたはのいずれかの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.cleanosgiConfigインストールされたバンドルが実行から実行へと残り、新しいバンドルが解決されません。

したがって、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) でのキャッシングの正確な意味と仕組みについて、適切な説明を誰かが教えてくれれば、私は感謝します。

4

1 に答える 1

1

無視しosgi.cleanます。また、開始レベルは無視してください。あなたが見逃しているステップは、実際にバンドルを開始することです!

を呼び出すたびinstallBundleに、Bundleオブジェクトが提供されます。すべてのバンドルをインストールしたらstart()、返された各バンドル オブジェクトを呼び出す必要があります。

バンドルを開始するために使用してきた他の方法は、完全に運が良かっただけです。つまり、それらのバンドルが一度開始され、その状態でキャッシュされた可能性があるからです。アプリケーションを別のマシンにインストールした場合、同じ状態はおそらく繰り返されません。したがって、実際にバンドルを制御して、自分で開始してください。

通常、INSTALLED と RESOLVED の違いを気にする必要はありません。インストール済みとは単に「まだ解決されていない」ことを意味する場合があります。たとえば、バンドルのエクスポートが必要なかった場合などです。BundleException依存関係の欠落などの解決上の問題がある場合は、メソッドを呼び出すときと同じようにそれらを見つけることができますstart

于 2013-09-18T18:58:01.723 に答える