5

私は現在、OSGI に慣れていて、OSGI のユースケースを少し特殊なものにすることにしました。コマンドラインアプリケーションで使用したいと思います。main(..)いくつかのフラグと引数を取り、何かを実行して再びシャットダウンするメソッドが必要です。私が望んでいないのは、Apache Karaf (または同様のもの) を起動して、OSGI コンソール内でコマンドを実行することです (ただし、これはオプション機能になる可能性があります)。

そもそも、なぜコマンドライン アプリケーションに OSGI を使用するのでしょうか? アプリケーションは、同じライブラリの異なるバージョンを使用することになっています ( elasticsearchです)。もちろん、それはもちろん悪いからです。

バンドル内またはバンドル外でサービスを使用する必要がありますか? どうすればそれを行うことができますか?どのような問題が発生する可能性がありますか?

4

2 に答える 2

7

bnd を使用すると、コマンド ライン アプリを非常に簡単に作成する方法があります。bnd には、package コマンドで実行可能な jar を作成する機能があります。

 $ 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() を呼び出してから終了します (必要なだけ実行を続けることができます)。

コマンド ライン引数を取得するには、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 では、Runnable の代わりに Callable<Integer> を使用できます。戻り値は、プロセスの終了コードです。ただし、これは bndtools にはまだ存在しない可能性があります。

于 2013-07-19T12:42:34.090 に答える
1

私自身の質問に答えるには ( Q&A スタイル): 私は現在、

  1. OSGI組み込みを開始(クリーン)
  2. コンテナを起動する
  3. API パッケージのエクスポート ( org.osgi.framework.system.packages.extra)
  4. 必要なバンドルをインストールして開始する
  5. OSGI の外部でサービスを利用する
  6. コンテナをシャットダウンする
  7. アプリを終了する

すべてのバンドルが開始された後は、必要なサービスが利用可能であると想定しても問題ありません。これにより、実際にはサービス呼び出しへの引数のみである構成を OSGI に渡すことも回避されます。

于 2013-07-19T09:44:12.880 に答える