A Buildr extension for packaging OSGi bundles using Bnd. WARNING: Integrated into buildr as of version 1.4.5
Ruby
Switch branches/tags
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
lib
spec
.gitignore
CHANGELOG
LICENSE
README.rdoc
Rakefile
buildr-bnd.gemspec

README.rdoc

Warning

Buildr-bnd has been integrated into buildr 1.4.5 and will be deprecated once the 1.4.5 version of buildr is released.

buildr-bnd

This is a Buildr extension for packaging OSGi bundles using Bnd (See www.aqute.biz/Code/Bnd). The extension allows the user to define properties/directives to be supplied to the Bnd tool and provides reasonable defaults for those that can be derived from the project model. Please see the bnd tool for documentation on the available properties.

The 'bnd' setting is used to provide directives to the bnd tool that are not inherited by subprojects while the standard 'manifest' setting is used to define properties that inherited by subprojects.

A typical project that uses the extension may look something like;

define 'myProject' do
  ...
  package(:bundle).tap do |bnd|
    bnd['Import-Package'] = "*;resolution:=optional"
    bnd['Export-Package'] = "*;version=#{version}"
  end
  ...
end

Installation

The extension is packaged as a gem named “buildr-iidea”, consult the ruby gems installation steps but typically it is either

sudo gem install buildr-bnd

for MRI ruby or

jgem install buildr-bnd

for jruby.

The user then needs to add the following require into the build file:

require 'buildr_bnd'

If the local maven repository does not contain the required bnd jars they can be downloaded but you will need to register the remote repository by adding the following to the build file:

repositories.remote << Buildr::Bnd.remote_repository

Defaults

The extension sets the following bnd parameters;

  • "Bundle-Version" defaults to the project version.

  • "Bundle-SymbolicName" defaults to the concatenation of the project group and project id, replacing ':' characters with '.'.

  • "Bundle-Name" defaults to the project description if present else the project name

  • "Bundle-Description" defaults to the project description.

  • "-classpath" is set to the compile target directory and any compile time dependencies.

  • "Include-Resource" defaults to the dir project.resources.target if it exists.

Parameters

classpath_element

The user can also specify additional elements that are added to the classpath using the 'classpath_element' method. If the parameter to this element is a task, artifact, artifact namespace etc. then it will be resolved prior to invoking bnd.

define 'foo' do
  ...
  package(:bundle).tap do |bnd|
    # This dependency will be added to classpath
    bnd.classpath_element 'someOtherExistingFile.zip'
    # All of these dependencies will be invoked and added to classpath 
    bnd.classpath_element artifact('com.sun.messaging.mq:imq:jar:4.4')
    bnd.classpath_element project('bar') # Adds all the packages
    bnd.classpath_element 'org.apache.ant:ant:jar:1.8.0'
    bnd.classpath_element file('myLocalFile.jar')
    ...
  end

  project 'bar' do
    ...
  end
end

classpath

The user can specify the complete classpath using the 'classpath' method. The classpath should be an array of elements. If the element is a task, artifact, artifact namespace etc. then it will be resolved prior to invoking bnd.

define 'foo' do
  ...
  package(:bundle).tap do |bnd|
    bnd.classpath [ project.compile.target,
                    'someOtherExistingFile.zip',
                    artifact('com.sun.messaging.mq:imq:jar:4.4'),
                    project('bar'),
                    'org.apache.ant:ant:jar:1.8.0',
                    file('myLocalFile.jar') ]
    ...
  end

  project 'bar' do
    ...
  end
end

Examples

Including non-class resources in a bundle

Bnd can be used to include non-class resources in a bundle. The following example includes all resources in 'src/etc' into the bundle.

require 'buildr_bnd'

desc 'Including resources example'
define 'myproject' do
  ...
  package(:bundle).tap do |bnd|
    bnd['Include-Resource'] = project._('src/etc') + '/'
    ...
  end
end

Using bnd to wrap an existing jar

Bnd can be used to wrap an existing jar as an OSGi bundle. The following example wraps the OpenMQ JMS provider as an OSGi bundle.

require 'buildr_bnd'

# Add repository for OpenMQ
repositories.remote << 'http://download.java.net/maven/2'

desc 'OSGi bundle for OpenMQ JMS provider client library'
define 'com.sun.messaging.mq.imq' do
  project.version = '4.4'
  project.group = 'iris'
  package(:bundle).tap do |bnd|
    bnd['Import-Package'] = "*;resolution:=optional"
    bnd['Export-Package'] = "com.sun.messaging.*;version=#{version}"
    bnd.classpath_element 'com.sun.messaging.mq:imq:jar:4.4'
  end
end

Create an OSGi bundle with an Activator

The following example presents a basic buildfile for building an OSGi bundle with an activator.

require 'buildr_bnd'

# repository for OSGi core bundle
repositories.remote << 'https://repository.apache.org/content/repositories/releases'

desc 'Hello World bundle'
define 'helloworld' do
  project.version = '1.0'
  project.group = 'org.example'
  compile.with 'org.apache.felix:org.osgi.core:jar:1.4.0'
  package(:bundle).tap do |bnd|
    bnd['Export-Package'] = "org.example.helloworld.api.*;version=#{version}"
    bnd['Bundle-Activator'] = "org.example.helloworld.Activator"
  end
end

Inheriting parameters for bnd tool

The following example shows how you can use 'manifest' to define a bnd parameter that is inherited to all child subprojects. The “Bundle-License” defined in the top level project is passed to the bnd tool when generating both the 'fe' and 'fi' subprojects but the 'fo' subproject overrides this parameter withy a local value.

require 'buildr_bnd'

define 'myproject' do
  manifest['Bundle-License'] = "http://www.apache.org/licenses/LICENSE-2.0"
  ...
  define 'fe' do
    ...
    package(:bundle).tap do |bnd|
      ...
    end
  end

  define 'fi' do
    ...
    package(:bundle).tap do |bnd|
      ...
    end
  end

  define 'fo' do
    ...
    package(:bundle).tap do |bnd|
      bnd['Bundle-License'] = "http://www.apache.org/licenses/LICENSE-1.1"
    end
  end
end

Future Work

The following is a list of feature requests for future versions of the extension. Feel free to jump in and supply a patch if you have gone ahead and implemented the feature.

Support Embed-Dependency equivalent

The maven-bundle-plugin supports Embed-Dependency which can include a jar inside the bundle, add manifest directives to include it in the export calculations. One “Embed-Dependency” directive may turn into something like

-classpath=com.ibm.mq.jar
Include-Resource=com.ibm.mq.jar
Bundle-Classpath=.,com.ibm.mq.jar
Private-Package=!*
-exportcontents: com.ibm.mq.*

For further discussion on this see;

Credit

The plugin was heavily inspired by the bnd tasks originally authored by Rhett Sutphin. It began life as a fork but has been rewritten from scratch to use a different approach.