Buildr-bnd is a project mainly written in Ruby, based on the Apache-2.0 license.
A Buildr extension for packaging OSGi bundles using Bnd. WARNING: Integrated into buildr as of version 1.4.5
= 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 http://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;
== 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|
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'
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'
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.