OSGiの全般的な情報については、http://www.osgi.orgを参照してください。
この章の内容は次のとおりです。
OSGiとは、OracleがメンバーとなっているOSGi Allianceによって開発および保守されているJavaモジュール方式システムです。
Javaアプリケーションの包括的な運用環境については、次のOSGiの仕様書と関連Javadocにまとめて説明されています。
OSGiサービス・プラットフォーム・コア仕様は、http://www.osgi.org/Release4/Downloadからダウンロードできます。
OSGi Javadocは、http://www.osgi.org/Release4/Javadocから入手できます。
OSGi Alliance Webページ(https://www.osgi.org/about-us/)には、次のように記載されています。「OSGi Allianceは、Javaテクノロジで構築されたソフトウェアのモジュール式アセンブリを可能にするオープンな仕様を作成する実績のある、成熟したプロセスを推進する世界的な技術革新コンソーシアムです。モジュール性はソフトウェアの複雑さを軽減します。OSGiはJavaをモジュール化するのに最適なモデルです。」
OSGi Architecture Webページ(https://www.osgi.org/developer/architecture/)には、OSGiテクノロジについて次にようにさらに詳細に説明されています。「...Java用の動的コンポーネント・システムを定義する一連の仕様です。これらの仕様によって、アプリケーションが多種多様な(再利用可能な)コンポーネントから(動的に)構成される、開発モデルが使用可能になります。OSGiの仕様では、コンポーネントがその実装を他のコンポーネントから見えないようにすることでき、その一方で、複数のコンポーネント間で具体的に共有されるオブジェクトである各種サービスを使用して通信することが可能です。この驚くほど簡単なモデルは、ソフトウェア開発プロセスのほとんどあらゆる側面に広範な影響を及ぼします。」
OSGiを使用する利点(https://www.osgi.org/developer/benefits-of-using-osgi/)で説明されているように、OSGiはユーザーに次の利点をもたらします。
インタフェースの実装者とユーザーのための、パッケージ・ワイヤリングのバージョニング。
「uses」ディレクティブは、クラス・ローダーのインテリジェント・ワイヤリングを可能にし、一貫性のあるクラス・スペースを確保するのに役立ちます。
柔軟かつ動的なセキュリティ。
アクティブ・レジストリを介した動的なサービス・ワイヤリング。
複数のベンダーによって提供される各種の標準的なOSGiの仕様。
WebLogic Serverでは、OSGiフレームワークの1つ以上のインスタンスを構成および管理できます。独自のOSGiバンドルを作成およびデプロイすることもできます。
WebLogic Serverを使用すると、サーバー構成に、(OsgiFrameWorkMBean MBeansによって管理される)OSGiフレームワークのリストを追加することができます。OSGiフレームワークが起動されると、フレームワークに対するバンドル・オブジェクトが、ローカル・サーバーJNDIツリーに配置されます。その結果、アプリケーションはJNDIからこのバンドルを取得し、その後、それをOSGiシステムへのエントリ・ポイントとして使用することができます。
アプリケーションは、独自のOSGiバンドルをデプロイすることもできます。アプリケーション・クラスローダー階層の中では、選択したフレームワーク・インスタンスの特定の1つのOSGiバンドルを使用できます。
WebLogic Serverでは次の操作が可能です。
Weblogic Server管理コンソールおよびWLSTからのOSGiフレームワークの1つ以上のインスタンスの構成および管理。
WebLogic Serverには、OSGiフレームワークのApache Felix実装が含まれます。Felixの詳細は、http://felix.apache.orgを参照してください。
独自のOSGiバンドルの作成およびデプロイ。
WebLogic Serverには、OSGi APIを格納するOSGiバンドルが含まれます。このAPIを使用して、独自のOSGiバンドルを作成することができます。
アプリケーション・クラスローダー階層の中では、選択したフレームワーク・インスタンスの特定の1つのOSGiバンドルを使用できます。
JNDIからのOSGiバンドルへの直接的なアクセス。
OSGiバンドルのデプロイおよびアンデプロイ。
WebLogic Serverロギング・メカニズムによるOSGiステータスの記録。
ユーザーが選択したOSGiサービスの組込み。
OSGiの永続性の有効化。
デプロイされたバンドルに対するOSGiバンドル開始レベルの管理。
これらのトピックについては、この後の項で説明します。
OSGiフレームワークでは、安全で管理可能なJavaフレームワークが提供されます。フレームワークの1つ以上のインスタンスを構成および管理して永続性を確保できます。
OSGiサービス・プラットフォーム・コア仕様では、次のように説明されています。「このフレームワークは、OSGiサービス・プラットフォーム仕様の中核を成しており、バンドルと呼ばれる拡張およびダウンロードが可能なアプリケーションのデプロイメントをサポートする、セキュアで管理された汎用のJavaフレームワークを提供します。」
WebLogic Serverには、OSGiフレームワークのFelix実装が含まれます。Felix OSGiフレームワークの1つ以上のインスタンスを構成および管理できます。
ノート:
WebLogic Serverは、Felixフレームワークのみをサポートしています。その他のOSGiフレームワークはサポートされておらず、テストされていません。
OSGiフレームワークは、デフォルトでWebLogic Serverに含まれていますが、自動的には起動されません。
WebLogic Serverの起動時にOSGiフレームワークを起動するように、WebLogic Serverを構成する必要があります。これは、好みに応じて、次の4つの方法で行うことができます。
WebLogic Server管理コンソールを使用して、OSGiフレームワーク・インスタンスを構成します。
DOMAIN_HOME\config\config.xmlデプロイメント記述子ファイルを編集することで、OSGiサーバーのエントリを追加して、属性値を設定します。WebLogic Serverインスタンスで使用するOSGiフレームワークを指定します。
WLSTを使用して、OSGiフレームワークを作成し、属性値を設定します。この場合、WLSTではDOMAIN_HOME\config\config.xmlデプロイメント記述子ファイルに値を格納します。
Javaプログラムを記述して、OSGiフレームワークを作成し、属性値を設定します。
4つのすべてのケースにおいて、OSGiフレームワーク・インスタンスの構成は、OsgiFrameWorkMBeanによって制御されます。OsgiFrameWorkMBeanに関連付けられたフレームワークごとに、WebLogic Serverが一意の名前を使用してOSGiフレームワークを起動します。
表17-1に示すように、OSGiフレームワーク属性を構成します。
表17-1 OSGiフレームワーク属性
| 属性 | 使用方法 |
|---|---|
Target |
この属性は必須です。このアイテムをデプロイできる現在のドメインにあるサーバーまたはクラスタのリストから、MBeanをデプロイするターゲット(サーバーまたはクラスタ)を選択する必要があります。 |
名前 |
フレームワーク・インスタンスの名前。指定されたフレームワーク・インスタンスの名前は、WebLogic Serverサーバー・インスタンス内で一意である必要があります。 |
Implementation Class |
|
Deploy Installation Bundles |
OSGiバンドルをフレームワークにインストールするかどうかを決定します。この属性は、デフォルトでは「populate」です。詳細は、「フレームワークにバンドルをインストールする際に必要なパラメータ」を参照してください。 |
Dynamically Created |
MBeanを動的に作成するか、 |
Init Properties |
フレームワークを初期化するときに使用する標準のFelixプロパティ。標準のすべてのプロパティおよびフレームワークに固有のすべてのプロパティを設定できます。 Javaプログラムからの初期プロパティの設定の例については、例17-3を参照してください。 Apache Felixフレームワークの構成プロパティについては、 |
Framework Boot delegation |
|
Framework System Packages Extra |
|
Register Global Data Sources |
ブール値。グローバル・データ・ソースをOSGiサービス・レジストリに追加する場合に、trueを返します。 |
Register Global Work Managers |
ブール値。グローバル・ワーク・マネージャをOSGiサービス・レジストリに追加する場合に、trueを返します。 |
Weblogic Server管理コンソールからOSGiフレームワークを構成することができます。次のステップを実行します:
Oracle WebLogic Server管理コンソール・オンライン・ヘルプのOSGiフレームワークの構成に関する項を参照してください。
例17-1は、WebLogic Serverで使用するOSGiフレームワークを追加するようにconfig.xmlを更新する例を示しています。</domain>要素の直前に<osgi-framework>要素を追加します。
複数のOSGiフレームワーク・インスタンスを追加する必要がある場合は、複数の<osgi-framework>要素を追加します。各<name>要素はサーバー内で一意である必要があることを忘れないでください。
この要素を追加した後、WebLogic Serverインスタンスを再起動する必要があります。
例17-1 config.xmlからのOSGiフレームワーク・インスタンスの構成
<osgi-framework>
<name>test-osgi-frame</name>
<target>AdminServer</target>
</osgi-framework>
例17-2は、WLSTを使用してWebLogic Serverインスタンスで使用するOSGiフレームワークを追加する例を示しています。
例17-2 WLSTからのOSGiフレームワーク・インスタンスの構成
java weblogic.WLST
connect('weblogic', 'password')
edit()
startEdit()
wls:/mydomain/edit !> cmo.createOsgiFramework('test-osgi-frame')
[MBeanServerInvocationHandler]com.bea:Name=test-osgi-frame,Type=OsgiFramework
targetServer=cmo.lookupServer('AdminServer')
cd('OsgiFrameworks')
cd('test-osgi-frame')
cmo.addTarget(targetServer)
wls:/mydomain/edit !> save()
wls:/mydomain/edit !> activate()
wls:/mydomain/edit/OsgiFrameworks> ls('a')
drw- test-osgi-frame
wls:/mydomain/edit/OsgiFrameworks> cd('test-osgi-frame')
wls:/mydomain/edit/OsgiFrameworks/test-osgi-frame> ls('a')
-rw- DeployInstallationBundles populate
-rw- DeploymentOrder 1000
-r-- DynamicallyCreated false
-rw- FactoryImplementationClass org.apache.felix.framework.F
rameworkFactory
-r-- Id 0
-rw- InitProperties null
-rw- Name test-osgi-frame
-rw- Notes null
-rw- OrgOsgiFrameworkBootdelegation null
-rw- OrgOsgiFrameworkSystemPackagesExtra null
-rw- RegisterGlobalDataSources true
-rw- RegisterGlobalWorkManagers true
-r-- Type OsgiFramework
例17-3は、Javaプログラムを使用してWebLogic Serverインスタンスで使用するOSGiフレームワークを追加する例を示しています。各操作については、コード内のコメントで説明されています。
例17-3 JavaプログラムからのOSGiフレームワークの構成
/**...imports omitted
*/
/**
* Create an OSGi framework instance with the designated name
*
* @param frameworkName
*/
protected void createOSGiFrameworkInstance(String frameworkName) {
createOSGiFrameworkInstance(frameworkName, null, null, null, null, null);
}
protected void createOSGiFrameworkInstance(String frameworkName,
String isRegisterGlobalWorkManagers,
String isRegisterGlobalDataSources,
String deployInstallationBundles,
String orgOsgiFrameworkBootdelegation,
String orgOsgiFrameworkSystemPackagesExtra) {
createOSGiFrameworkInstance(frameworkName,
null,
isRegisterGlobalWorkManagers,
isRegisterGlobalDataSources,
deployInstallationBundles,
orgOsgiFrameworkBootdelegation,
orgOsgiFrameworkSystemPackagesExtra);
}
/**
* Create a fresh framework
*
* @param isRegisterGlobalWorkManagers
* @param isRegisterGlobalDataSources
* @param deployInstallationBundles
* @param orgOsgiFrameworkBootdelegation
* @param orgOsgiFrameworkSystemPackagesExtra
*/
protected void createOSGiFrameworkInstance(String frameworkName,
Properties initProp,
String isRegisterGlobalWorkManagers,
String isRegisterGlobalDataSources,
String deployInstallationBundles,
String orgOsgiFrameworkBootdelegation,
String orgOsgiFrameworkSystemPackagesExtra) {
frameworkInstances.add(frameworkName);
if (initProp == null) {
initProp = new Properties();
}
initProp.setProperty("wlstest.framework.instance.name", frameworkName);
//initProp.setProperty("felix.cache.locking", "false");
//initProp.setProperty("org.osgi.framework.storage.clean", "onFirstInit");
MBeanServerConnection connection = null;
try {
// Initiate the necessary MBean facilities.
connection = initConnection();
// Switch the edit session on.
ObjectName domainMBean = startEditSession(connection);
// Get the current WebLogic server MBean:
ObjectName serverMBean = null;
ObjectName[] serverMBeans = (ObjectName[]) connection.getAttribute(domainMBean, "Servers");
for (ObjectName objectName : serverMBeans) {
log("found server: " + objectName);
serverMBean = objectName;
}
// Get or create an OsgiFrameworkMBean:
ObjectName osgiFrameworkMBean = null;
ObjectName[] osgiFrameworkMBeans = (ObjectName[]) connection.getAttribute(domainMBean, "OsgiFrameworks");
log("osgiFrameworkMBeans.length=" + osgiFrameworkMBeans.length);
for (ObjectName objectName : osgiFrameworkMBeans) {
String osgiFrameworkName = (String) connection.getAttribute(objectName, "Name");
log("--------------> " + osgiFrameworkName);
if (osgiFrameworkName.equals(frameworkName)) {
osgiFrameworkMBean = objectName;
log("Found OSGi framework instance: " + frameworkName);
break;
}
}
if (osgiFrameworkMBean != null) {
log("Will destroy the framework instance: " + osgiFrameworkMBean);
connection.invoke(osgiFrameworkMBean,
"removeTarget",
new Object[] { serverMBean },
new String[] { "javax.management.ObjectName" });
connection.invoke(domainMBean,
"destroyOsgiFramework",
new Object[] { osgiFrameworkMBean },
new String[] { "javax.management.ObjectName" });
}
log("Will create a new framework instance from scratch");
osgiFrameworkMBean = (ObjectName) connection.invoke(domainMBean,
"createOsgiFramework",
new Object[] { frameworkName },
new String[] { "java.lang.String" });
// Set common properties:
if (initProp != null) {
Attribute initPropAttr = new Attribute("InitProperties", initProp);
connection.setAttribute(osgiFrameworkMBean, initPropAttr);
}
Attribute systemPackagesExtraAttr = new Attribute("OrgOsgiFrameworkSystemPackagesExtra",
"javax.naming,weblogic.work,javax.sql");
connection.setAttribute(osgiFrameworkMBean, systemPackagesExtraAttr);
connection.invoke(osgiFrameworkMBean,
"addTarget",
new Object[] { serverMBean },
new String[] { "javax.management.ObjectName" });
// Set individual property to the OSGi framework instance:
if (isRegisterGlobalWorkManagers != null) {
Attribute attr = new Attribute("RegisterGlobalWorkManagers", Boolean.parseBoolean(isRegisterGlobalWorkManagers));
connection.setAttribute(osgiFrameworkMBean, attr);
}
if (isRegisterGlobalDataSources != null) {
Attribute attr = new Attribute("RegisterGlobalDataSources", Boolean.parseBoolean(isRegisterGlobalDataSources));
connection.setAttribute(osgiFrameworkMBean, attr);
}
if (deployInstallationBundles != null) {
Attribute attr = new Attribute("DeployInstallationBundles", deployInstallationBundles);
connection.setAttribute(osgiFrameworkMBean, attr);
}
if (orgOsgiFrameworkBootdelegation != null) {
Attribute attr = new Attribute("OrgOsgiFrameworkBootdelegation", orgOsgiFrameworkBootdelegation);
connection.setAttribute(osgiFrameworkMBean, attr);
}
if (orgOsgiFrameworkSystemPackagesExtra != null) {
Attribute attr = new Attribute("OrgOsgiFrameworkSystemPackagesExtra", orgOsgiFrameworkSystemPackagesExtra);
connection.setAttribute(osgiFrameworkMBean, attr);
}
MBeanInfo mi = connection.getMBeanInfo(osgiFrameworkMBean);
log("Attributes are as below:");
for (MBeanAttributeInfo mai : mi.getAttributes()) {
Object value = connection.getAttribute(osgiFrameworkMBean, mai.getName());
System.out.printf(" %-40s = %s\n", mai.getName(), value);
}
// Save your changes
ObjectName cfgMgr = (ObjectName) connection.getAttribute(service, "ConfigurationManager");
connection.invoke(cfgMgr, "save", null, null);
OsgiFrameWorkMBean MBeanのDeploy Installation Bundles属性は、osgi-libディレクトリ(この章の後半の「OSGiバンドルのosgi-libディレクトリへのデプロイ」で説明)に存在するバンドルをフレームワークに実際にインストールするかどうかを制御します。
Deploy Installation Bundlesパラメータには、次の値を指定できます。
ignore — このディレクトリ内のいずれのバンドルも、インストールおよび起動されません。
populate — 可能な場合は、バンドルがインストールおよび起動されます。これがデフォルトです。さらに、osgi-libディレクトリ内のバンドルを使用可能にするために、ブート委任クラスパス・パラメータに別のパッケージをいくつか追加します(まだそこに存在しない場合)。
これらのバンドルが適切に解決されておらずそのために起動できない場合には、システムが起動しない原因としてなんらかの障害が発生したとは見なされません。
OSGiには、永続性メカニズムがあります(http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/launch/Framework.htmlで説明)。この永続性メカニズムでは、インストールされているすべてのバンドルが、各バンドルの永続性自動起動設定に従って起動されます。
この永続性メカニズムは、デフォルトでは無効になっています。ただし、表17-1に示されている標準のFelix初期プロパティを使用して、OSGi永続性メカニズムを有効にすることができます。
ノート: WebLogic Serverは、OSGi永続性メカニズムに直接は関与していません。特に、WebLogic Serverは他のサーバーにデータをフェイルオーバーしません。
標準のOSGiサービスをOSGiバンドルで使用できるようにすることができます。このためには、Felixフレームワークに対する正しいパッケージをインポートして、アプリケーション・バンドルが必要な認可を持っていることを確認します。
これらのサービスについては、OSGiサービス・プラットフォーム・コア仕様(https://www.osgi.org/release-4-version-4-3/)に説明されています。サービスの例として、標準のフレームワーク供給サービス(Package Admin Service、Conditional Permission Admin Service、StartLevel Serviceなど)があげられます。
OSGiサービス・イベントをリスニングする簡単なバンドルを作成する例については、「Apache Felix Tutorial Example 1, Service Event Listener Bundle」を参照してください。
必須のバンドルを取得
必須のバンドルを起動
コンソールへの接続
$ORACLE_HOME/wlserver/server/osgi-libの下に配置しますhelpは、すべての使用可能なコマンドのリストを示します
psは、すべてのバンドルとそれらの状態のリストを示します
wlserver/server/lib/org.apache.felix.org.apache.felix.main.jarにあるOSGi APIバンドルを使用して、独自のOSGiバンドルを作成します。
簡単なバンドルを作成する例については、「Apache Felix Tutorial Example 1, Service Event Listener Bundle」を参照してください。この例で説明されているように、マニフェスト・ファイルのImport-Package属性は、外部パッケージに対するバンドルの依存関係を、フレームワークに通知します。アクティベータを含むすべてのバンドルは、org.osgi.frameworkをインポートする必要があります。アクティベータには、コアOSGiクラス定義が含まれているからです。
OSGiを作成した後、OSGiバンドルをターゲット・システム上のosgi-libディレクトリ内にデプロイできます。WebLogic Serverでは、JAR、EARまたはWARファイル内からOSGiバンドルをデプロイできます。
アプリケーションに適切なものとして、JAR、EARまたはWARファイル内からOSGiバンドルをデプロイすることができます。
これを実行する前に、まず、バンドルで使用するOSGiフレームワークを指定して、WebLogic Serverに対するバンドルを特定する必要があります。
ノート:
指定したOSGiフレームワーク・インスタンスがターゲット・サーバー上に存在しない場合、OSGiバンドルのデプロイは失敗します。
これを行う方法は、バンドルがWARファイル内とEARファイル内のどちらにあるかに依存します。
WAR — フレームワーク・インスタンスとバンドル名が、Webアプリケーションのweblogic.xmlデプロイメント記述子ファイルの要素内にある必要があります。
EAR — フレームワーク・インスタンスとバンドル名が、アプリケーションのweblogic-application.xmlデプロイメント記述子ファイルの要素内にある必要があります。
EARファイルにWARファイルが含まれている場合、埋め込まれたWARファイルからweblogic.xmlデプロイメント記述子ファイルを使用して、WARファイル内のバンドルをデプロイします。
次の項では、必要なステップについて詳しく説明します。
WebLogic Serverデプロイメント記述子の詳細は、『Oracle WebLogic Serverへのアプリケーションのデプロイ』を参照してください
OSGiバンドルをデプロイする前に、まず次のことを実行する必要があります。
DOMAIN_HOME\config\config.xmlデプロイメント記述子ファイルまたはWLSTを使用して、OSGiフレームワークのエントリを追加します。weblogic-application.xmlデプロイメント記述子ファイルに、OSGiフレームワークの名前とバンドル自体の名前の両方を追加します。 例17-1は、WebLogic Serverで使用するOSGiフレームワークを追加するようにconfig.xmlを更新する例を示しています。
例17-4は、OSGiフレームワークの名前およびバンドルの名前と場所の両方を追加するようにweblogic-application.xmlを更新する例を示しています。
例17-4 weblogic-application.xmlへのフレームワークとバンドルの追加
<osgi-framework-reference>
<name>test-osgi-frame</name>
<application-bundle-symbolic-name>com.oracle.weblogic.test.client
</application-bundle-symbolic-name>
<bundles-directory>rashi/osgi-lib</bundles-directory>
</osgi-framework-reference>
例17-4のスタンザは、「test-osgi-frame」という名前のOSGiフレームワークにアタッチすること、およびそのOSGiフレームワークからクラスを検索するためにそのサーバーでcom.oracle.weblogic.test.clientというシンボリック名を持つバンドルを検索することを、WebLogic Serverに伝えます。
WARファイルとしてバンドルをインストールする前に、まず次のことを実行する必要があります。
DOMAIN_HOME\config\config.xmlデプロイメント記述子ファイルまたはWLSTを使用して、OSGiフレームワークのエントリを追加します。weblogic.xmlデプロイメント記述子ファイルに、OSGiフレームワークの名前とバンドル自体の名前の両方を追加します。 例17-1は、WebLogic Serverで使用するOSGiフレームワークを追加するようにconfig.xmlを更新する例を示しています。
例17-5は、OSGiフレームワークの名前およびバンドルの名前と場所の両方を追加するようにweblogic.xmlを更新する例を示しています。
例17-5 weblogic.xmlへのフレームワークとバンドルの追加
<osgi-framework-reference>
<name>test-osgi-frame</name>
<application-bundle-symbolic-name>com.oracle.weblogic.test.client
</application-bundle-symbolic-name>
<bundles-directory>rashi/osgi-lib</bundles-directory>
</osgi-framework-reference>
例17-4のスタンザは、「test-osgi-frame」という名前のOSGiフレームワークにアタッチすること、およびそのOSGiフレームワークからクラスを検索するためにそのサーバーでcom.oracle.weblogic.test.clientというシンボリック名を持つバンドルを検索することを、WebLogic Serverに伝えます。
ワーク・マネージャでは、定義したルールに基づいて、さらには実際の実行時パフォーマンスの統計をモニターすることによって、作業の優先順位を決められます。こうした情報は、後にアプリケーションのパフォーマンスを最適化するためにも使用されます。『Oracle WebLogic Serverサーバー環境の管理』のワーク・マネージャを使用したスケジュールされた作業の最適化に関する項を参照してください。
表17-1で説明されているように、Register Global Work Managers MBean属性がtrueに設定されている場合、OSGi実装はグローバル・ワーク・マネージャを利用することができます。
例17-7に示すように、Javaアプリケーションから使用中のグローバル・ワーク・マネージャを決定することができます。
例17-6 グローバル・ワーク・マネージャの決定
// Get the global scoped work manager service:
ServiceReference[] refWmSvcs = bc.getServiceReferences(WorkManager.class.getCanonicalName(),
"(name=GlobalScopedWorkManager)");
if (refWmSvcs != null) {
logger.setAttribute(frameworkInstanceName, bundleIdentifier + "_WorkManager_Count", refWmSvcs.length);
for (int i = 0; i < refWmSvcs.length; i++) {
ServiceReference refWmSvc = refWmSvcs[i];
WorkManager wm = (WorkManager) bc.getService(refWmSvc);
logger.setAttribute(frameworkInstanceName, bundleIdentifier + "_WorkManager" + (i + 1), wm.getName());
bc.ungetService(refWmSvc);
}
}
『Oracle WebLogic Serverの理解』のWebLogic Serverデータ・ソースに関する項で説明されているように、WebLogic Serverでデータベース接続を構成するには、JDBCデータ・ソースとマルチ・データ・ソースを構成し、次にWebLogicドメインのサーバーまたはクラスタに対してJDBCリソースをターゲット化またはデプロイします
表17-1で説明されているように、Register Global Data Sources MBean属性がtrueに設定されている場合、OSGi実装はグローバル・データ・ソースを利用することができます。
例17-7に示すように、Javaアプリケーションから使用中のグローバル・データ・ソースを決定することができます。
例17-7 グローバル・データ・ソースの決定
// Get the global data source services:
ServiceReference[] refDsSvcs = bc.getServiceReferences(DataSource.class.getCanonicalName(), "(name=OsgiDS)");
if (refDsSvcs != null) {
logger.setAttribute(frameworkInstanceName, bundleIdentifier + "_DataSource_Count", refDsSvcs.length);
for (int i = 0; i < refDsSvcs.length; i++) {
String data = null;
ServiceReference refDsSvc = refDsSvcs[i];
DataSource ds = (DataSource) bc.getService(refDsSvc);
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = ds.getConnection();
stmt = conn.createStatement();
rs = stmt.executeQuery("select * from dual");
rs.next();
data = rs.getString(0);
} catch (SQLException e) {
ノート:
「フレームワークにバンドルをインストールする際に必要なパラメータ」で説明されているように、OsgiFrameWorkMBean MBeanのDeploy Installation Bundles属性は、osgi-libディレクトリに存在するバンドルを実際にインストールするかどうかを制御します。この属性はデフォルトでtrueになっており、バンドルがインストールされます。
1の起動レベルでバンドルをデプロイするには、WL_HOME/server/osgi-libディレクトリを作成し(まだ存在しない場合)、次にそのディレクトリにアーカイブ・ファイル(EAR、WAR)ファイルをコピーします。
このディレクトリ内の、.jar、.earまたは.warが最後に付いているファイルはすべて、起動時にフレームワークにインストールされるOSGiバンドルと見なされます。
WL_HOME/server/osgi-libは、サーバーを初めて起動するときにのみ参照され、それ以降に行われる変更については監視されません。新しいOSGiバンドルを、WL_HOME/server/osgi-libディレクトリに追加して、デプロイする場合は、WebLogic Serverを再起動する必要があります。
OSGiサーバーが起動されると、バンドル・オブジェクトが、ローカル・サーバーJNDIツリーに配置されます。その結果、アプリケーションはJNDIからこのバンドルを取得し、その後、それをOSGiシステムへのエントリ・ポイントとして使用することができます。
org.osgi.framework.Bundleは、アプリケーションのjava:app/osgi/Bundle JNDI環境に配置されます。
アプリケーション・クラスローダー階層の中では、選択したフレームワーク・インスタンスの特定の1つのOSGiバンドルを使用できます。
例17-8は、JNDIから作成するバンドルにアクセスする方法を示しています。
例17-8 JNDIからのOSGiバンドルへのアクセス
public static final String BUNDLE_JNDI_NAME = "java:app/osgi/Bundle";
...
String bundleSymbolicName = null;
Bundle bundle = null;
OsgiInfo info = new OsgiInfo();
List<String> errorMessages = new ArrayList<String>();
try {
Context initCtx = new InitialContext();
bundle = (Bundle) initCtx.lookup(Constants.BUNDLE_JNDI_NAME);
} catch (NamingException e) {
errorMessages.add(e.toString());
System.out.println("Failed to lookup bundle from JNDI due to " + e);
}
if (bundle != null) {
bundleSymbolicName = bundle.getSymbolicName() + "_" + bundle.getVersion();
info.setCurrentBundle(bundleSymbolicName);
BundleContext bc = bundle.getBundleContext();
if (bc != null) {
// Get the start level service:
StartLevel startLevelSvc = null;
ServiceReference startLevelSr = bc.getServiceReference("org.osgi.service.startlevel.StartLevel");
if (startLevelSr != null) {
startLevelSvc = (StartLevel) bc.getService(startLevelSr);
}
List<String> allInstalledBundles = new ArrayList<String>();
List<String> allActivatedBundles = new ArrayList<String>();
Map<String, List<String>> services = new HashMap<String, List<String>>();
Map<String, String> startLevels = new HashMap<String, String>();
for (Bundle b : bc.getBundles()) {
// Collect all the installed and activated bundles:
String bundleId = b.getSymbolicName() + "_" + b.getVersion();
allInstalledBundles.add(bundleId);
if (b.getState() == Bundle.ACTIVE) {
allActivatedBundles.add(bundleId);
}
// Collect the registered services:
ServiceReference[] srs = b.getRegisteredServices();
if (srs != null) {
List<String> list = new ArrayList<String>();
for (ServiceReference sr : srs) {
list.add(sr + "-->" + bc.getService(sr));
}
services.put(bundleId, list);
}
// Collect the start levels:
if (startLevelSvc != null) {
startLevels.put(bundleId, startLevelSvc.getBundleStartLevel(b) + "");
}
}
info.setAllInstalledBundles(allInstalledBundles);
info.setAllActivatedBundles(allActivatedBundles);
info.setRegisteredServices(services);
info.setStartLevels(startLevels);
// Query the work manager services:
List<String> workManagers = new ArrayList<String>();
try {
ServiceReference[] wmSrs = bc.getServiceReferences(WorkManager.class.getCanonicalName(), null);
if (wmSrs != null) {
for (ServiceReference sr : wmSrs) {
WorkManager wm = (WorkManager) bc.getService(sr);
workManagers.add(wm.getName());
}
}
} catch (InvalidSyntaxException e) {
e.printStackTrace(System.out);
}
info.setWorkManagers(workManagers);
// Query the data source services:
List<String> dataSources = new ArrayList<String>();
try {
ServiceReference[] dsSrs = bc.getServiceReferences(DataSource.class.getCanonicalName(), null);
if (dsSrs != null) {
for (ServiceReference sr : dsSrs) {
dataSources.add(sr.getProperty("name").toString());
}
}
} catch (InvalidSyntaxException e) {
e.printStackTrace(System.out);
}
info.setDataSources(dataSources);
}
}
String bundleFileName = null;
try {
BundleIntrospect introspection = new BundleIntrospect();
bundleFileName = introspection.whichBundleFile();
info.setCurrentBundleFileName(bundleFileName);
} catch (Throwable e) {
errorMessages.add(e.toString());
//e.printStackTrace(System.out);
}
info.setErrorMessages(errorMessages);
return info;
}
}
OSGiログ・サービスのApache Felix実装は、WebLogic Serverをインストールするとデフォルトでインストールされます。OSGiバンドルはOSGiロギング・サービスに登録され、OSGiロガーからWebLogic Serverロガーにログを送信します。
OSGiログ・サービスのApache Felix実装は、デフォルトでは、インストール・ディレクトリWL_HOME/server/osgi-libにインストールされます。
WL_HOME/server/osgi-libには、OSGiバンドルcom.oracle.weblogic.osgi.logger_relnum.jarもインストールされます。このバンドルはOSGiロギング・サービスに登録され、OSGiロガーからWebLogic Serverロガーにログを送信します。
ロガーのシステム名は、OSGiForAppsです。表17-2に示すように、OSGiとWebLogic Serverの間でメッセージの重大度レベルがマッピングされます。
表17-2 OSGiとWebLogic Serverロギングの重大度マッピング
| OSGiの重大度レベル | WebLogic Serverの重大度レベル |
|---|---|
LogLevel.LOG_ERROR |
Severities.ERROR |
LogLevel.LOG_WARNING |
Severities.WARNING |
LogLevel.LOG_INFO |
Severities.INFO |
LogLevel.LOG_DEBUG |
Severities.DEBUG |
フィルタリング・クラスローダーを使用すると、OSGiバンドルとしてデプロイされる代替ライブラリ・バージョンの使用を指定することができます。
FilteringClassLoaderを構成して、特定のパッケージがアプリケーションからロードされることを指定するには、アプリケーションからロードされるパッケージのリストを記述しているweblogic-application.xmlに、prefer-application-packages記述子要素を追加します。次の例は、org.apache.log4j.*パッケージとantlr.*パッケージがシステム・クラスローダーではなくアプリケーションからロードされることを示します。
<prefer-application-packages> <package-name>org.apache.log4j.*</package-name> <package-name>antlr.*</package-name> </prefer-application-packages>
パッケージがOSGiバンドルである場合、WEB-INF/libまたはWEB-INF/osgi-libにパッケージを配置します。WEB-INF/osgi-libに直接OSGiバンドルの依存関係を追加するか、またはOSGiフレームワーク・インスタンスでorg.osgi.framework.system.packages.extraプロパティ(表17-1を参照)を構成して、アプリケーションが必要とする必須のjavaxパッケージをエクスポートすることができます。
フィルタリング・クラスローダーの詳細は、「フィルタリング・クラスローダーの使用」を参照してください。
WebLogic Serverには、クライアントとサーバーの2つの簡単なOSGiバンドルのサンプルが含まれています。サーバー・バンドル(ServerBundle)は、クライアント・バンドル(ClientBundle)がインポートするパケットをエクスポートします。このサンプルは、デプロイされたOSGiバンドルを表示するHTMLページを生成します。
WebLogic Serverには、OSGiバンドルをWebLogic Serverにデプロイする方法を実証するサンプルが含まれています。WebLogic Serverのサンプルをインストールした場合、OSGiのサンプル・ソース・コードは、ORACLE_HOMEwl_server/examples/src/examples/osgi/osgiAppにあります。ここで、ORACLE_HOMEは、WebLogic Serverのコード・サンプルを構成するディレクトリを示します。WebLogic Serverサンプル・コードの詳細は、『Oracle WebLogic Serverの理解』のサンプル・アプリケーションおよびサンプル・コードに関する項を参照してください。