# OSGi Maven Bundle Plugin

The bundle-plugin is used to build and package components for the Vespa Container with Maven. Refer to the multiple-bundles sample app for a practical example.

The minimal Maven pom.xml configuration is:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yahoo.example</groupId>
<artifactId>basic-application</artifactId>
<packaging>container-plugin</packaging> <!-- Use Vespa packaging -->
<version>1.0.1</version>

<properties>
</properties>

<build>
<plugins>
<plugin> <!-- Build the bundles -->
<groupId>com.yahoo.vespa</groupId>
<artifactId>bundle-plugin</artifactId>
<version>${vespa.version}</version> <extensions>true</extensions> </plugin> <plugin> <!-- Zip the application package --> <groupId>com.yahoo.vespa</groupId> <artifactId>vespa-application-maven-plugin</artifactId> <version>${vespa.version}</version>
<executions>
<execution>
<goals>
<goal>packageApplication</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

<dependencies>
<dependency> <!-- Vespa dependencies -->
<groupId>com.yahoo.vespa</groupId>
<artifactId>container</artifactId>
<version>${vespa.version}</version> <scope>provided</scope> </dependency> </dependencies> </project>  To create a deployable application package, run: $ mvn install package


The bundle plugin automates generation of configuration classes by invoking the maven step generate-resources - read more in configuring-components.html

## Including third-party libraries

Include external dependencies into the bundle by specifying them as dependencies:

<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.0.3</version>
<scope>compile</scope>
</dependency>

All packages in the library will then be available for use. If the external dependency is an OSGi bundle, one can deploy it instead of including it into the bundle by setting the scope to provided:

<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5-osgi</artifactId>
<version>5.0-beta2</version>
<scope>provided</scope>
</dependency>


Then deploy the external dependency along with the bundle. Only packages exported by the author of the library will then be available for use (see the section below).

## Exporting, Importing and Including Packages from Bundles

OSGi features information hiding — by default all the classes used inside a bundle are invisible from the outside. Also, the bundle will by default only see (all) the packages in the Java and Container + Vespa APIs. If any other package is needed by the bundle, then it must happen in one of three ways:

• Some additional packages are exported by the container and may be imported explicitly by a bundle
• In addition, any deployed bundle may export packages on its own, which may then be imported by another bundle
• Finally, the bundle may include its own JAR libraries
One can export packages from a bundle by annotating the package. E.g. to export com.mydomain.mypackage, create package-info.java in the package directory with:
@ExportPackage(version = @Version(major=1, minor=0, micro=0))
package com.mydomain.mypackage;

import com.yahoo.osgi.annotation.ExportPackage;
import com.yahoo.osgi.annotation.Version;

The Maven plugin will place such information in the manifest of the plugin JAR built to be picked up by the Container.

Note that this may also be used with bundles that do not contain any searchers but libraries used by other searchers - a bundle may just exist to export some libraries and never have any searchers instantiated.

Bundles may import packages (exported by some other bundle or by the container). The maven plugin will automatically import any package used from bundles it compiles against(i.e. maven dependencies with scope provided).

As mentioned above, each exported package has a version associated with it. Similary, an import of a package has a version range associated with it. The version range determines which exported packages can be used. The range used by the maven plugin is the current version(i.e. the version of the package available at compile time) up to the next major version (not including).

More details in troubleshooting.

## Configuring the Bundle-Plugin

The bundle plugin can be configured to tailor the resulting bundle to specific needs.

<build>
<plugins>
<plugin>
<groupId>com.yahoo.vespa</groupId>
<artifactId>bundle-plugin</artifactId>
<version>${vespa.version}</version> <extensions>true</extensions> <configuration> <attachBundleArtifact>true/false</attachBundleArtifact> <bundleClassifierName>…</bundleClassifierName> <discApplicationClass>…</discApplicationClass> <discPreInstallBundle>…</discPreInstallBundle> <bundleVersion>…</bundleVersion> <bundleSymbolicName>…</bundleSymbolicName> <bundleActivator>…</bundleActivator> <configGenVersion>…</configGenVersion> <configModels>…</configModels> </configuration> </plugin>  attachBundleArtifact Whether to attach the bundle jar artifact to the build. Use this if you want to install and deploy the bundle jar along with the default jar. Default is false If attachBundleArtifact is true, this will be used as classifier for the bundle jar artifact. Default is bundle The fully qualified class name of the Application to be started by JDisc The name of the bundles that jDISC must pre-install The version of this bundle. Defaults to the Maven project version The symbolic name of this bundle. Defaults to the Maven artifact ID The fully qualified class name of the bundle activator The version of com.yahoo.vespa.configlib.config-class-plugin that will be used to generate config classes List of config models ## Troubleshooting A package p is imported if all of the following holds: 1. Using a class in p directly (i.e. not with reflection) in the bundle 2. There's no classes in the bundle that is in p 3. There's a bundle that exports p, and compiling against this bundle To debug, run $ mvn -X package

and look at Defined packages (=packages in the bundle), Exported packages of dependencies, Referenced packages(= packages used). A package is imported if it is in Exported packages and Referenced packages but not in Defined packages.