Skip to content
Skip to breadcrumbs
Skip to header menu
Skip to action menu
Skip to quick search
Quick Search
Browse
Pages
Blog
Labels
Attachments
Mail
Advanced
What’s New
Space Directory
Feed Builder
Keyboard Shortcuts
Confluence Gadgets
Log In
Dashboard
Groovy
Copy Page
You are not logged in. Any changes you make will be marked as
anonymous
. You may want to
Log In
if you already have an account. You can also
Sign Up
for a new account.
This page is being edited by
.
Paragraph
Paragraph
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Preformatted
Quote
Bold
Italic
Underline
More colours
Strikethrough
Subscript
Superscript
Monospace
Clear Formatting
Bullet list
Numbered list
Outdent
Indent
Align left
Align center
Align right
Link
Table
Insert
Insert Content
Image
Link
Attachment
Symbol
Emoticon
Wiki Markup
Horizontal rule
tinymce.confluence.insert_menu.macro_desc
Info
JIRA Issue
Status
Gallery
Tasklist
Table of Contents
Other Macros
Page Layout
No Layout
Two column (simple)
Two column (simple, left sidebar)
Two column (simple, right sidebar)
Three column (simple)
Two column
Two column (left sidebar)
Two column (right sidebar)
Three column
Three column (left and right sidebars)
Undo
Redo
Find/Replace
Keyboard Shortcuts Help
<p>The <a href="http://www.osgi.org/">OSGi</a> framework is a powerful Java tool providing component based service and dependency management. OSGi components can be remotely installed, started, stopped, updated and uninstalled without shutting down your application. Also, OSGi provides far greater dependency management than the basic Java classpath mechanism, allowing you to specify specific versions of dependencies and keep dependencies private so that other components cannot load them. One of the most notable usages of OSGi is the Eclipse Plugin Container. A good starting point for more information is the <a href="http://en.wikipedia.org/wiki/OSGi">Wikipedia page</a> and the Further Reading section of this document.</p> <h1>Loading Groovy as an OSGi service</h1> <p>The Groovy jar files are released with correct OSGi metadata, so they can be loaded into any OSGi compliant container, such as Eclipse Equinox or Apache Felix. The metadata can be viewed by looking at the jar file's MANIFEST.MF file. For instance, your Jar manifest might contain these lines:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> Bundle-Version: 1.7.0 Export-Package: groovy.text;version="1.7.0.beta-1-SNAPSHOT",groovy.xml; version="1.7.0.beta-1-SNAPSHOT",groovy.util;version="1.7.0.beta-1-SNA PSHOT",groovy.lang;version="1.7.0.beta-1-SNAPSHOT",groovyjarjarcom... </pre></td></tr></table> <p>This declares to the OSGi container that the Jar is version 1.7.0 and provides the specified packages for import by other components.</p> <p>The following examples all use the Eclipse Equinox container, which can be downloaded from the Internet or found in an Eclipse installation.</p> <p>Perform the following steps to install and start the Groovy Jar in an OSGi container:</p> <p>Start the OSGi container in console mode:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> java -jar org.eclipse.osgi_3.4.0.v20080605-1900.jar -console </pre></td></tr></table> <p>This should bring up an OSGi console prompt:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> osgi> </pre></td></tr></table> <p>You can see the system status of the container at any time using the "ss" command.</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> osgi> ss Framework is launched. id State Bundle 0 ACTIVE org.eclipse.osgi_3.4.0.v20080605-1900 </pre></td></tr></table> <p>Install the Groovy jar file using "install" and a file URL to your groovy-all jar:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> osgi>install file:///home/user/dev/groovy-core/target/dist/groovy-all-1.7-beta-1-SNAPSHOT.jar Bundle id is 10 </pre></td></tr></table> <p>The container will assign the bundle an identifier. Start the bundle using the "start" command:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> osgi> start 10 </pre></td></tr></table> <p>Verify the bundle is started using "ss":</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> osgi> ss Framework is launched. id State Bundle 0 ACTIVE org.eclipse.osgi_3.4.0.v20080605-1900 10 ACTIVE groovy-all_1.7.0.beta-1-SNAPSHOT </pre></td></tr></table> <p>You can list all the packages the Groovy bundle provides with the "packages" command:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> osgi>packages 10 groovy.xml.streamingmarkupsupport; version="1.7.0.beta-1-SNAPSHOT"<file:///hom e/user/dev/groovy-core/target/dist/groovy-all-1.7-beta-1-SNAPSHOT.jar [10]>gro ovyjarjarantlr.actions.java; version="1.7.0.beta-1-SNAPSHOT"<file:///home/user ... </pre></td></tr></table> <h1>Writing a Groovy OSGi Service</h1> <p>Once the Groovy jar is loaded into the container, writing an OSGi service that uses Groovy is as simple as creating a class that extends the framework's BundleActivator interface.</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> package org.codehaus.groovy.osgi import org.osgi.framework.BundleActivator import org.osgi.framework.BundleContext class Activator implements BundleActivator { void start(BundleContext context) { println "Groovy BundleActivator started" } void stop(BundleContext context) { println "Groovy BundleActivator stopped" } } </pre></td></tr></table> <p>The Activator's start(BundleContext) method will be invoked when the container starts the service, and the stop(BundleContext) method will be invoked when the container stops the service.</p> <p>The first step in deploying the new Groovy service is to create a jar file containing the Activator. The manifest for the Jar needs to specify the name of the new service, the version, the fully qualified path to the Activator, and which packages from the groovy-all jar bundle to import. The complete manifest for this example follows:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> 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" Bundle-ClassPath: . </pre></td></tr></table> <p>The Import-Package statement is important. It states all the dependencies from the Groovy-all jar which are allowed to be referenced. The Groovy-all Jar exports many, many more packages than just this... an Import-Package definition with just enough dependencies to get the println to work correctly is shown here. In a more meaningful Activator you'd want to import many more of the packages.</p> <p>The complete Jar for this example has a layout as follows:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> hello-bundle-imports-groovy.jar --META-INF ----MANIFEST.MF --org ----codehaus ------groovy --------osgi ----------Activator.class </pre></td></tr></table> <p>Test the new Hello-Groovy bundle by running the OSGi console and issuing the following commands, using "ss" to verify that the correct dependencies are loaded beforehand:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> osgi> ss Framework is launched. id State Bundle 0 ACTIVE org.eclipse.osgi_3.4.0.v20080605-1900 10 ACTIVE groovy-all_1.7.0.beta-1-SNAPSHOT osgi> install file:///home/user/dev/groovy-core/src/examples/osgi/build/hello-bundle-imports-groovy.jar Bundle id is 12 osgi> ss Framework is launched. id State Bundle 0 ACTIVE org.eclipse.osgi_3.4.0.v20080605-1900 10 ACTIVE groovy-all_1.7.0.beta-1-SNAPSHOT 12 INSTALLED org.codehaus.groovy.osgi.hello-groovy-bundle_1.0.0 osgi> start 12 Groovy BundleActivator started osgi> stop 12 Groovy BundleActivator stopped </pre></td></tr></table> <p>The start and stop message shows that the Groovy service was correctly started and stopped.</p> <h1>Including the Groovy Jar within a Bundle</h1> <p>The previous example shows how to resolve an Activator's Groovy dependency from the container. The Activator can only be started after the Groovy bundle is started. An alternative is to simply include the groovy-all jar within your bundle. This eliminates the need to declare Import-Packages, but does bloat the size of the jar. Any Jar file included within your bundle has private visibility and cannot be referenced by any other bundles that happen to be running in the container.</p> <p>To include the groovy-all jar within your bundle, rather than loading it from the container, create your Jar with a layout as follows:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> hello-bundle-contains-groovy.jar --groovy-all-1.7-beta-1-SNAPSHOT.jar --META-INF ----MANIFEST.MF --org ----codehaus ------groovy --------osgi ----------Activator.class </pre></td></tr></table> <p>And use this template as the MANIFEST.MF:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> 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: org.w3c.dom,org.osgi.framework;version="1.3.0" Bundle-ClassPath: .,groovy-all-1.7-beta-1-SNAPSHOT.jar </pre></td></tr></table> <p>The Jar can now be loaded and started in the container without first loading the Groovy Jar. Verify this but running the following within the console: <br class="atl-forced-newline" /></p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> osgi> install file:///home/user/dev/groovy-core/src/examples/osgi/build/hello-bundle-contains-groovy.jar Bundle id is 14 osgi> ss Framework is launched. id State Bundle 0 ACTIVE org.eclipse.osgi_3.4.0.v20080605-1900 14 INSTALLED org.codehaus.groovy.osgi.hello-groovy-bundle_1.0.0 osgi> start 14 Groovy BundleActivator started </pre></td></tr></table> <h1>Publishing a Service Written in Groovy</h1> <p>Publishing a service written in Groovy requires one extra step that a Java service does not. This is because of the way Groovy makes extensive use of ClassLoaders and reflection. When registering a service with the BundleContext, you must be sure to temporarily set the current thread's ContextClassLoader to the target object's ClassLoader, and then set it back when you're done. It's actually quite easy, and this example walks you through this one detail.</p> <p>In order to demonstrate registering a service, we need to create a sample service in Groovy. This is just a POGO interface and implementation. Consider the GroovyGreeter which simply prints a message to the console.</p> <p>GroovyGreeter.groovy defines the interface:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> package org.codehaus.groovy.osgi interface GroovyGreeter { void sayHello() } </pre></td></tr></table> <p>And GroovyGreeterImpl.groovy defines the implementation:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> package org.codehaus.groovy.osgi class GroovyGreeterImpl implements GroovyGreeter { void sayHello() { println "Hello from the Groovy Greeter!" } } </pre></td></tr></table> <p>Now the Activator can create an instance of GroovyGreeterImpl and register it with the container as a GroovyGreeter provider. In Java, you'd need one line to call BundleContext.registerService(String, Object, Dictionary), but in Groovy we need to change the ContextClassLoader while we do this. Here is a complete and correct Activator:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> 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() } } </pre></td></tr></table> <p>The Jar file for this bundle is similar to the first example's:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> hello-bundle-imports-groovy.jar --META-INF ----MANIFEST.MF --org ----codehaus ------groovy --------osgi ----------Activator.class ----------GroovyGreeter.class ----------GroovyGreeterImpl.class </pre></td></tr></table> <p>The Jar Manifest is almost the same as the first example. The change is the Export-Package statement. Since we are registering the a service org.codehaus.groovy.osgi,GroovyGreeter, we need to specify that package and version in an Export-Package statement:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> 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: . </pre></td></tr></table> <p>Notice, also, how this bundle is importing the Groovy Jar from the container, it does not contain the Groovy Jar within itself. To verify and test this, use the OSGi console to install and start the groovy-all Jar and then install and start this Jar.</p> <h1>Consuming a Service from Groovy</h1> <p>It is easy to consume an OSGi service from a Groovy Activator. This example shows how to locate and invoke the service from the previous section, but could just as easily work with a different service. It does not matter at all whether the service was written in Groovy, Java, or any other language. The implementation details of a service should be completely hidden from you by the OSGi module system. Also, while this example is written in Groovy, it is not very different from how it would look in Java.</p> <p>To consume the service from the previous section, you will need an Activator that retrieves the service from the BundleContext in the start(BundleContext) method:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> package org.codehaus.groovy.osgi.harness import org.osgi.framework.BundleActivator import org.osgi.framework.BundleContext import org.osgi.framework.ServiceRegistration import org.osgi.framework.ServiceReference import org.codehaus.groovy.osgi.GroovyGreeter class HarnessActivator implements BundleActivator { void start(BundleContext context) { String serviceName = GroovyGreeter.class.name ServiceReference[] references = context.getAllServiceReferences(serviceName, null) println "${ references ? references.size() : 0 } GroovyGreeter services found." references?.each { ServiceReference ref -> Object serviceHandle = context.getService(ref) GroovyGreeter service = serviceHandle service.sayHello() } } void stop(BundleContext context) { } } </pre></td></tr></table> <p>The service was registered by the interface name, so this Activator queries for that interface, printing out all the providers found. Notice the package and name of this Activator changed. Since the previous example exported the org.codehaus.groovy.osgi, this example needed to pick a different package to avoid conflicts. Also, the variables types in the code sample were explicitly declared to make the samplee easier to read.</p> <p>To package and run this example you'll need to make a Jar with the following layout:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> hello-groovy-test-harness.jar --META-INF ----MANIFEST.MF --org ----codehaus ------groovy --------osgi ----------harness ------------HarnessActivator.class ------------HarnessActivator$_start_closure1.class </pre></td></tr></table> <p>And the manifest needs to import the org.codehaus.groovy.osgi in the previous example:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> 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.harness Bundle-ManifestVersion: 2 Bundle-Name: Groovy OSGi Test Harness Bundle-SymbolicName: org.codehaus.groovy.osgi.harness.hello-groovy-tes t-harness Bundle-Version: 1.0.0 Bundle-Activator: org.codehaus.groovy.osgi.harness.HarnessActivator Bundle-Vendor: Groovy Bundle-Localization: plugin Import-Package: org.codehaus.groovy.runtime.typehandling;version="1.0. 0",org.codehaus.groovy.osgi;version="1.0.0",groovy.lang;version="1.7. 0.beta-1-SNAPSHOT",org.codehaus.groovy.reflection;version="1.7.0.beta -1-SNAPSHOT",org.codehaus.groovy.runtime;version="1.7.0.beta-1-SNAPSH OT",org.codehaus.groovy.runtime.callsite;version="1.7.0.beta-1-SNAPSH OT",org.w3c.dom,org.osgi.framework;version="1.3.0" Bundle-ClassPath: . </pre></td></tr></table> <p>Install and test this bundle in the OSGi console. To install this bundle you'll need the groovy-all bundle installed first:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> osgi> install file:///home/user/dev/groovy-core/src/examples/osgi/../../../target/dist/groovy-all-1.7-beta-1-SNAPSHOT.jar Bundle id is 6 osgi> install file:///home/user/dev/groovy-core/src/examples/osgi/build/hello-groovy-test-harness.jar Bundle id is 7 osgi> ss Framework is launched. id State Bundle 0 ACTIVE org.eclipse.osgi_3.4.0.v20080605-1900 6 INSTALLED groovy-all_1.7.0.beta-1-SNAPSHOT 7 INSTALLED org.codehaus.groovy.osgi.harness.hello-groovy-test-harness_1.0.0 </pre></td></tr></table> <p>To start the bundle, you'll need the groovy-all bundle started and the hello-groovy bundle installed:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> osgi> install file:///home/user/dev/groovy-core/src/examples/osgi/build/hello-bundle-imports-groovy.jar Bundle id is 8 osgi> start 6 osgi> start 7 0 GroovyGreeter services found. </pre></td></tr></table> <p>To see the GroovyGreeter service locate and invoke the service, start the hello-groovy bundle and the restart the harness:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> osgi> ss Framework is launched. id State Bundle 0 ACTIVE org.eclipse.osgi_3.4.0.v20080605-1900 6 ACTIVE groovy-all_1.7.0.beta-1-SNAPSHOT 7 ACTIVE org.codehaus.groovy.osgi.harness.hello-groovy-test-harness_1.0.0 8 RESOLVED org.codehaus.groovy.osgi.hello-groovy-bundle_1.0.0 osgi> start 8 Groovy BundleActivator started osgi> stop 7 osgi> start 7 1 GroovyGreeter services found. Hello from the Groovy Greeter! </pre></td></tr></table> <p>Exploring the OSGi console can be a valuable learning experience. Now that all the bundles are loaded, try playing with the "bundle", "headers", "services", and "packages" commands. Help is available by typing "help".</p> <h1>Common Errors </h1> <p>Diagnosing runtime exceptions can be a frustrating experience for the OSGi beginner and expert alike. Here are some common errors and solutions you might experience running these code samples:</p> <p><strong>ClassNotFoundException -</strong> The Java and Groovy compiler use a classpath to resolve dependencies, while the OSGi container does not. This means that code that compiles fine might still receive ClassNotFound exceptions when running in the container. Here are some steps to diagnose the issue:</p> <ul> <li>Find out which class is missing but reading the exception stack trace</li> <li>Find out which Jar contains the missing class</li> <li>Does that Jar's Manifest contain an Export-Package statement for the class' package? If not, then the Jar was built incorrectly and you need to add the package to the Export-Package statement of the Jar.</li> <li>Does your Jar's Manifest contain an Import-Package statement for the imported package? If not, then your Jar was built incorrectly and you need to add the package to the Import-Package statement of your Jar.</li> <li>Does the Export-Package version number match your Import-Package version number? If not, then update your manifest to import the correct version, or update the missing class' jar to export the correct version?</li> <li>Is the missing class' bundle correctly installed and started in the container? The results of an "ss" command must show the Jar as "Active" or else it won't be resolved. Use the "install" and "start" commands to start the jar correctly.</li> </ul> <p><strong>Missing Constraint -</strong> This means that one of your declared Import-Package statements cannot be satisfied by the container. The error message will state exactly which dependency is missing, for instance it might say: Missing Constraint groovy.lang; version="1.7.0.beta-1-SNAPSHOT".</p> <ul> <li> Is the missing constraint's bundle correctly installed and started in the container? The results of an "ss" command must show the Jar as "Active" or else it won't be resolved. Use the "install" and "start" commands to start the jar correctly.</li> </ul> <p><strong>ClassCastException</strong> - This error occurs when retrieving services out of the BundleContext and takes the form of the mysterious error message "Cannot cast foo.bar.Class to foo.bar.Class". This means that the ClassLoader of your bundle has a different version of foo.bar.Class than the one you're retrieving.</p> <ul> <li>Look at how the service's Activator is adding foo.bar.Class to the BundleContext. If the class is implemented in Groovy then you must add the service using the ClassLoader code in the Publishing a Service Written in Groovy of this document.</li> <li>Look at how your Activator is resolving the reference to the class. If your bundle already defines foo.bar.Class and you're trying to retrieve a foo.bar.Class from a different bundle, then the versions of the classes won't match. Declare the type as an interface that is imported the same way between both bundles to resolve this issue.</li> </ul> <h1>Further Reading</h1> <p>The great part about using Groovy for OSGi is that the existing tutorials for Java and OSGi are all easily converted to Groovy.</p> <ul> <li>JavaWorld.com has a good three part introduction to Java and OSGi. <a class="confluence-link unresolved" data-content-title="Part 1" title="http://www.javaworld.com/javaworld/jw-03-2008/jw-03-osgi1.html" data-linked-resource-default-alias="Part 1" href="#">Part 1</a> details the basics os a Hello World service. Part 2 describes the Spring DM product and adding Spring to OSGi. And Part 3 covers several web deployment scenarios and issues. <a href="http://www.javaworld.com/javaworld/jw-04-2008/jw-04-osgi2.html">Part 2</a> describes the Spring DM product and adding Spring to OSGi. And <a href="http://www.javaworld.com/javaworld/jw-06-2008/jw-06-osgi3.html">Part 3</a> covers several web deployment scenarios and issues.</li> <li>TheServerSide.com also has an <a href="http://www.theserverside.com/tt/articles/article.tss?l=OSGiforBeginners">OSGi for Beginners</a> article.</li> <li>Hamlet D'Arcy has a <a href="http://hamletdarcy.blogspot.com/2008/12/beginners-guide-to-osgi-on-desktop.html">Groovy and OSGi on the Desktop</a> tutorial on his <a href="http://hamletdarcy.blogspot.com">blog</a>.</li> <li>Groovy and Sling (using OSGi): <a href="http://incubator.apache.org/sling/site/groovy-support.html">Apache Sling doco</a>, <a href="http://n1ceone.blogspot.com/2008/09/using-groovy-builders-in-sling.html">blog</a></li> </ul>
Please type the word appearing in the picture.
Attachments
Labels
Location
Watch this page
< Edit
Preview >
Loading…
Save
Cancel
Next hint
search
attachments
weblink
advanced