2017-10-27 9 views
0

私のバンドルにリソースファイル(例えば、いくつかのXML設定ファイル)を含めて、それをコンテナ内の他のすべてのバンドルに見せたいと思っています。 Fragment-Hostマニフェストヘッダーを使用せずに可能ですか?このリソースファイルは、バンドルの横にあるすべてのバンドルのクラスパスに表示されるようにしてください。まだ存在しないものの、今後追加される可能性もあります。OSGiのすべてのバンドルにリソースファイルを見えるようにするには?

EDIT:

明確にする - そのリソースは、すなわち、他のバンドルが自分のクラスパスではなく、私のバンドルのいずれかの特殊なAPIやサービスに参照のうえで、それを見つけることができる必要があり、受動的に利用可能でなければなりません。

背景 - 私の環境はちょっと面倒ですが、私はそれを制御できず、既存のバンドルを変更できません。私が変更できる唯一の方法は、自分のバンドルを追加することです。その環境には、ch.qos.logback.classic bundleのコピーがいくつか含まれています。ログバックが開始されると、クラスパス内の特定のXML設定ファイルが検索されます。それが見つからなければ、デフォルトではすべてをデバッグレベルで標準出力に出力します。この環境は以前はGUIアプリケーションをホストするために使用されていたので、それほど問題にはなりませんでしたが、ヘッドレスモードでその機能の一部を使用できるように変更しようとしています。だから、警告とエラーだけがコンソールに出力されるように設定することが重要になってきた。

答えて

0

一般的に、これはできません。クラス空間の分離はOSGiの中心にありますが、あるバンドルのクラスローダーにリソースを入れ、それを他のすべてのバンドルに見せたいとします。これはOSGiではなく、グローバルなアプリケーションクラスパスです。

特定のバンドルの内部クラスパスに追加することができるのは、そのバンドルに接続するフラグメントを書き込むことだけです。フラグメントは複数のホストバンドルにアタッチすることができますが、のホストは同じシンボル名を持つ場合、つまり同じバンドルの異なるバージョンであるためです。 OSGi R6コア仕様、セクション3.14を参照してください。

あなたが添付するバンドルはすべてch.qos.logback.classicのコピーであると述べましたが、それは、それらがすべてその象徴的な名前を持っていることを意味している場合、おそらくフラグメントはすべて後に機能します。

+0

ありがとうNeil。残念ながら私の断片のホストとして 'ch.qos.logback.classic'を定義することは私の場合は機能しません。これは、他のバンドルが内部的にlibとしてログバックを含み、 'Bundle-ClassPath:lib/logback-classic.jar'マニフェストヘッダを持っているからです。つまり、バンドルごとに1つずつ、いくつかのフラグメントを作成する方法があるようです。とにかくありがとうございました。 – yashu

1

この方法で他のバンドルのクラスパスを変更することはできません。

できることは、バンドルのクラスローダーをbundleContextから取得することです。このクラスローダを別のバンドルに渡して、リソースを取得することができます。

ClassLoader cl = context.getBundle().adapt(BundleWiring.class).getClassLoader(); 

別のオプションには、リソースのURLを指定することもできます。

+0

クリスチャン、他のバンドルとのやりとりを必要としない方法はありますか?私の場合、私は他のバンドルを制御することはできず、それらを変更することはできません。私が知っている一つの方法は、自分のバンドルを他のバンドルの断片にすることですが、その場合、他のどのバンドルが私の断片のホストであるかを明示的に定義しなければなりません。ある種の「一般的な断片」の仕組みが存在していれば、それを一度に解決することができました。 – yashu

0

リソースがクラスパス上にある限り、リソースを含むバンドルのクラスローダを保持できる場合は、どのバンドルもそのリソースにアクセスできます。例えば

ClassLoader classLoaderOfBundleWithResource = ... 
classLoaderOfBundleWithResource.getResourceAsStream("org/example/resource.xml"); 

ビューのメンテナンスやAPIの点から、私はそのようにリソースを暴露することをお勧めしません。 Javaの型は、そのためにはるかに適しています。かわりに、リソースバンドルに、クライアントにリソースの内容へのアクセス権を与えるクラスをエクスポートさせます。例えば

public class XmlDocumentProvider { 
    public InputStream openDocument() { 
    return getClass().getResourceAsStream("resource.xml"); 
    } 
} 

resource.xmlXmlDocumentProvider両方が同じパッケージ内に存在すると仮定すると、openDocumentはちょうど最初の例のようなリソースのコンテンツを返します。

+0

Rüdigerありがとうございました。実際には、他のバンドルとのやりとりを必要としないものを探しています。クラスパスでリソースを利用できるようにするものです。フラグメントと似ていますが、より一般的なものです。私はおそらくそれをより明確にするために質問を編集する必要があります... – yashu