9

公開された(宣言型)サービスを使用してOSGiバンドルを作成しました。アクティベートが呼び出されたときに、サービスを提供できないなどの問題があることに気付いた場合は、サービスが公開されないようにする必要があります。現時点では、活性化関数は次のようになっています。

public void activate(ComponentContext context, Map<String, Object> properties) {
    pid = (String) properties.get(Constants.SERVICE_PID);
    try {
       ...
    }
    catch(Exception e) {
        context.disableComponent(pid);
    }
}

もう1つの方法は、次のように例外をラップ/伝播する(または、場合によっては新しい例外をスローする)ことです。

public void activate(ComponentContext context, Map<String, Object> properties) {
    try {
       ...
    }
    catch(Exception e) {
        throw new ComponentException("Some reason");
    }
}

OSGi Service Platform Service Compendiumの宣言型サービスのセクションで指定されている正しい動作が見つかりませんが、何かが足りない可能性があります

4

2 に答える 2

9

うーん、私にとっては、エラーが発生した場合に例外をスローするのは理にかなっているようです。基本的に、次に実行しているのは、startメソッドでBundleActivatorの動作を模倣することです。startメソッドが例外なしで戻るとバンドルはACTIVE状態になります(それ以外の場合はRESOLVEDのままです)。DS仕様にやや適切な段落を見つけました(興味深い部分を強調しました):

コンポーネントインスタンスは、非アクティブ化する前にアクティブ化を完了する必要があります。コンポーネント構成が非アクティブ化されるか、例外のためにアクティブ化に失敗すると、SCRはすべてのコンポーネントのバインドされたサービスのバインドを解除し、アクティブ化に関連付けられたコンポーネントインスタンスへのすべての参照を破棄する必要があります。

OSGi4.2cmpn仕様のセクション112.5.6P.320

これは明確ではないことに同意します。そのため、安全を確保したい場合(申し訳ありませんが、安全を確保したい場合)は、組み合わせを行うことをお勧めします(仕様で許可されています)。

public void activate(ComponentContext context, Map<String, Object> properties) {
    try {
       ...
    } catch(Exception e) {
        context.disableComponent((String) properties.get(Constants.SERVICE_PID));
        // not sure if a CE is best here... Maybe just rethrow the original one
        throw new ComponentException("Some reason");
    }
}

乾杯、ミルコ

于 2009-10-15T16:06:23.833 に答える
1

コンポーネント自体を無効にすることは、適切なOSGI設計である可能性はほとんどありません。状況が改善したときにコンポーネントを有効にするにはどうすればよいですか?有効/無効状態は、アクティブ化/非アクティブ化とは異なる論理レベルであることが意図されています。

適切に設計されたOSGIコードは、アクティベーションが失敗したときにComponentException(またはその他の例外)をスローするコードを正しく処理する必要があります。コンポーネントがサービスを登録すると仮定すると、サービス参照は使用可能になりますが、サービスを取得しようとするとnullが返されます。DSはサービスへの参照を正しく処理し、サービス参照からサービスを直接取得しようとするコードは、サービスが実際に利用できない可能性を適切に処理する必要があります。

ただし、これは混乱を招く可能性があります。Felix DSでは、コンポーネントが独自のサービスプロパティを変更できる拡張機能を実装しましたが、これは仕様では受け入れられていません。この拡張機能を使用すると、コンポーネントは、アクティブ化または変更が成功したときにactive = trueなどのサービスプロパティを追加し、変更が失敗したときまたは非アクティブ化したときにそれを削除できます。サービスのクライアントは、このサービスプロパティでフィルタリングできます(例:(active = true))。

于 2017-04-10T17:52:45.643 に答える