Export-Packageの一部ではないコンポーネントBを持つバンドルAがあるとします。コンポーネントは、アクティブ化されると定期的に実行するようにスケジュールされます。スケジューラーは別のバンドルによって提供されます。
私の質問は、コンポーネントBがスケジューラのスレッドプール内のスレッドによって実行されているときにバンドルAをアンインストールした場合、どのような影響がありますか?スレッドは引き続き実行されますか?または、スレッドは例外をスローしますか?
バンドルにはライフサイクルがあります。バンドルがアクティブな場合、アンインストールされる前に停止されます。「コンポーネントB」が宣言型サービスコンポーネントである場合、それも停止されます。そうでない場合は、少なくともバンドルアクティベータのstopメソッドがトリガーされます。
停止中、(コンポーネントBのプロバイダーとしての)ユーザーは、スレッドプールから削除されるように、スケジュールからコンポーネントのスケジュールを解除する責任があります。スレッドが現在実行中の場合は、中止できるようにキャンセル機能を実装する必要があります。
適切にクリーンアップしない場合(つまり、スレッドのスケジュールを解除/キャンセルしない場合)、スレッドが再度実行される可能性があります。そのスレッド内からOSGiAPIにアクセスすると、IllegaleStateExceptionが発生します(一部のAPIの使用では、停止後にバンドルのBundleContextが無効になるため)。ただし、そうでない場合、スレッドは永久に実行され続ける可能性があります。オブジェクトとメモリは解放されません。クラスとバンドルクラスローダーはガベージコレクションされません。したがって、「停止」を適切に実装することが重要です。
プロキシ参照を使用してモジュール間をバインドしている場合、モジュールを交換するまで、それらのプロキシは無効になる可能性があります。
直接バインディングがある場合、「アンインストールされた」モジュールは、どこでも使用されなくなるまで実際には削除されません。あなたはそれを置き換えることができ、新しい用途は新しいライブラリを使用します。
OSGiには魔法はありません。オブジェクトへの既存の参照が維持され、ガベージコレクターが対応するクラスローダーを取得するのを防ぎます。
幸い、DSを使用すると、対応するクリーンアップを非常に簡単に実行できます。