追加したユーザーは T.Yamamoto です。最後に編集したユーザーは T.Yamamotoで、その日時は 2009-12-23 20:06:53 です。

Groovyで書いたサービスを公開する

Groovyで書いたサービスを公開するためには、Javaのサービスでは不要な、余計な一ステップが必要になります。これは、GroovyがClassLoaderやリフレクションを広範に利用していることに由来します。BundleContextを使ってサービスを登録するとき、カレントスレッドのContextClassLoaderに一時的に対象オブジェクトのClassLoaderを設定し、登録終了時に元に戻す必要があります。これは実際にはとても簡単で、以下の例で詳しい流れを見ていきます。

サービス登録のデモのために、まずGroovyサービスの実例を作る必要があります。これは単純なPOGOインタフェースとその実装にします。コンソールにシンプルにメッセージを出力するGroovyGreeterを考えてみてください。

GroovyGreeter.groovyでインタフェースを定義します:

package org.codehaus.groovy.osgi

interface GroovyGreeter { void sayHello() }

そして、GroovyGreeterImpl.groovyでその実装を定義します:

package org.codehaus.groovy.osgi

class GroovyGreeterImpl implements GroovyGreeter { void sayHello() { println "Hello from the Groovy Greeter!" } }

これで、ActivatorはGroovyGreeterImplのインスタンスを生成し、それをGroovyGreererのプロバイダとしてコンテナに登録することができます。JavaではBundleContext.registerService(String, Object, Dictionary)を呼び出す一行だけですみますが、Groovyではこれを行う間、ContextClassLoaderを変更しておく必要があります。 以下が完全かつ正確なActivatorです:

package org.codehaus.groovy.osgi
import org.osgi.framework.BundleActivator
import org.osgi.framework.BundleContext
import org.osgi.framework.ServiceRegistration

class Activator implements BundleActivator { ServiceRegistration registration void start(BundleContext context) { ClassLoader originalClassLoader = Thread.currentThread().contextClassLoader try { Thread.currentThread().contextClassLoader = getClass().classLoader GroovyGreeter myService = new GroovyGreeterImpl() registration = context.registerService(GroovyGreeter.class.getName(), myService, null) } finally { Thread.currentThread().contextClassLoader = originalClassLoader } } void stop(BundleContext context) { registration.unregister() } }

このバンドルのJarファイルは、最初の例のものに似ています:

hello-bundle-imports-groovy.jar
--META-INF
----MANIFEST.MF
--org
----codehaus
------groovy
--------osgi
----------Activator.class
----------GroovyGreeter.class
----------GroovyGreeterImpl.class

JarのManifestも最初の例のものとだいたい同じです。変更点はExport-Package文です。org.codehaus.groovy.osgiのGroovyGreeterサービスを登録しているので、Export-Package文でこのパッケージとバージョンを指定する必要があります:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Created-By: 10.0-b19 (Sun Microsystems Inc.)
Built-By: user
provider: org.codehaus.groovy.osgi
Bundle-ManifestVersion: 2
Bundle-Name: Groovy OSGi Example Bundle
Bundle-SymbolicName: org.codehaus.groovy.osgi.hello-groovy-bundle
Bundle-Version: 1.0.0
Bundle-Activator: org.codehaus.groovy.osgi.Activator
Bundle-Vendor: Groovy
Bundle-Localization: plugin
Import-Package: groovy.lang;version="1.7.0.beta-1-SNAPSHOT",org.codeha
us.groovy.reflection;version="1.7.0.beta-1-SNAPSHOT",org.codehaus.gro
ovy.runtime;version="1.7.0.beta-1-SNAPSHOT",org.codehaus.groovy.runti
me.callsite;version="1.7.0.beta-1-SNAPSHOT",org.w3c.dom,org.osgi.fram
ework;version="1.3.0"
Export-Package: org.codehaus.groovy.osgi;version="1.0.0"
Bundle-ClassPath: .

なお、このバンドルはGroovy Jarをコンテナからインポートしていることに注意してください。これ自体はGroovy Jarを含んでいません。テストして確認するためには、OSGiコンソールを使ってgroovy-all Jarをインストールして起動し、その後でこのJarをインストールして起動します。

子ページ 追加

©2008-2009 grails.jp