6

これは大きな問題です。

私は、基本的なモジュラーアーキテクチャを備えた、適切に構造化されたモノリシックコードベースを持っています(すべてのモジュールはインターフェイスを実装しますが、同じクラスパスを共有します)。このアプローチの愚かさと、ライブラリのバージョンが競合している可能性のあるアプリケーションサーバーにデプロイするときに発生する問題を認識しています。

私は現在約30個の瓶に依存しており、それらを束ねていますが途中です。これで、ネットワークコンポーネントなど、一部のモジュールはバージョン管理された依存関係を簡単に宣言できます。これらは、JREおよびその他のBNDdedライブラリ内のクラスを静的に参照しますが、JVM関連のコンポーネントはClass.forName(...)を介してインスタンス化され、任意の数のドライバーの1つを使用できます。

私はすべてをサービスエリアごとにOSGiバンドルに分割しています。

  • 私のコアクラス/インターフェース。
  • 関連するコンポーネントのレポート。
  • データベースアクセス関連コンポーネント(JDBC経由)。
  • 等....

私のコードが、すべての依存関係を持つ単一のjarファイルを介してOSGiなしで、OSGiなしで(JARJARを介して)引き続き使用できるようにし、OSGiメタデータと依存関係情報を含む詳細なバンドルを介してモジュール化できるようにしたいと思います。

  • クラスパス上および/またはOSGiコンテナー環境(Felix / Equinoxなど)内で任意のドライバーを動的に利用できるように、バンドルとコードを構成するにはどうすればよいですか?

  • コンテナー間で互換性のあるOSGiコンテナー(Felix / Equinoxなど)で実行されているかどうかを検出する実行時の方法はありますか?

  • OSGiコンテナーにいる場合、別のクラス・ロード・メカニズムを使用する必要がありますか?

  • データベースモジュールを介してバンドル時に不明なJDBCドライバーをロードできるようにするには、OSGiクラスをプロジェクトにインポートする必要がありますか?

  • ドライバーを取得する2番目の方法もあります(JNDIを介して、アプリサーバーで実行している場合にのみ実際に適用できます)。OSGi対応アプリサーバーのJNDIアクセスコードを変更する必要がありますか?

4

3 に答える 3

8
  • OSGi 環境内でドライバーを利用するには、DynamicImport-Package: * ステートメントを使用する必要があります。これにより、Class.forName(..) を使用してドライバーをロードするときにバンドルがこれらのパッケージを解決できるようになります。
  • おそらく最も簡単な方法は、org.osgi.framework パッケージにあるクラスにアクセスすることです。これらは、少なくとも OSGi 環境では常に存在する必要があります (以下のスニペットを参照)。もっと洗練されたメカニズムがあるので、もっと高度なものが必要な場合はお知らせください。また、OSGi R4.2コア仕様のパラグラフ3.8.9を見てください。これは、クラスのBundleおよびBundleContextを見つけるいくつかの方法を示しているため、フレームワークにいるかどうかを判断するのに間接的に役立ちます。
  • それはあなたが何をしているかによって異なります。ここでは一般的な「はい」または「いいえ」の答えはありません。OSGi はクラスローダーを使用し、標準の Java アプリケーションでは「一般的」ではない方法でそれを行いますが、何をしているかによっては気付かないかもしれません。
  • いいえ。
  • 最近リリースされた OSGi エンタープライズ仕様をご覧ください。OSGi での JNDI 統合に関する章があり、おそらくコードを (ほとんど) 変更せずに残すことができます。

簡単な例のスニペット:

 public static boolean inOSGi() {
  try {
   Class.forName("org.osgi.framework.FrameworkUtil");
   return true;
  }
  catch (ClassNotFoundException e) {
   return false;
  }
 }

このコードをバンドルに入れる場合は、バンドルが org.osgi.framework をインポートする必要があることを確認してください (そうしないと、そのクラスが見つかりません)。

于 2010-04-29T15:21:07.197 に答える
0

pax-jdbc を使用して、宣言的な方法でデータソースを委任できます。つまり、ConfigAdmin サービスで構成エントリを作成でき、JNDI を介してデータソースにアクセスできます。JDBC ドライバーはバンドルとしてデプロイされます。(それらのほとんどは OSGi バージョンを持っています)

例えば:

構成エントリの PID は org.ops4j.datasource-test です。

プロパティ:

osgi.jdbc.driver.name=H2
databaseName=test
user=sa
password=
dataSourceName=testds-h2

サービスは、指定された dataSourceName によって識別されます。したがって、(&(objectClass=javax.sql.DataSource)(dataSourceName=test2)) でフィルタリングできます。

また、JNDI 経由でデータソースにアクセスできます。

osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=test2)
于 2016-07-28T00:03:15.487 に答える
0

私は Eclipse RCP で OSGI 用の JDBC ドライバー・マネージャーを作成しました。OSGI をうまく扱う方法を紹介します。まず、DynamicImport-Package のことは忘れてください。OSGI を使用する唯一の良い方法は、バンドルをインストール/開始/停止し、OSGI メカニズムを設計どおりに使用することです。

  1. JDBC バンドルがあり、DriverClass の初期化、接続ロジックを含む別の「ドライバー バンドル」を作成し、dbcp2 や pool2 などの必要なコモンズ ライブラリを追加します。

  2. ドライバー バンドルを JAR/ZIP としてエクスポートし、リソースとして JDBC バンドルに含めます。

  3. JDBC バンドルの作業領域でドライバ バンドルを解凍します。

    String workdir= Platform.getStateLocation(jdbc_bundle).toPortableString();
    
  4. プログラムでドライバー jar を追加し、それに応じてドライバー バンドルの MANIFEST.MF ファイルを変更します。

  5. 作業領域からドライバ バンドルをプログラムでロードする

    getBundleContext().installBundle("file:/"+workdir);
    
  6. ドライバーのリストをプログラムで変更する場合は、必要に応じて bundle.start()、stop()、uninstall() を使用します。

于 2016-07-22T07:21:22.853 に答える