Develop with Eclipse - Deploy with Maven

In the previous Declarative Services in Apache Karaf entry the creation of a Karaf feature is demonstrated. One can create the feature by simply running `mvn clean install` at the root of the source code (available at GitHub). This will build and install all projects in the local Maven repository. The converter-ds-feature is a special module that actually creates the feature. It has the sole purpose of hosting a features.xml file, which contains links to all the bundles that need to be installed. The created feature can easily be installed in Karaf with the following commands:

features:addUrl mvn:gr.atc.aniketos.demos.converterservice/converter-ds-feature/1.0.0.SNAPSHOT/xml/features
features:install converter-ds-feature

The first command adds the newly created feature in Karaf's features list and the second actually installs the feature. Notice that for the feature's URL the maven protocol is used.

As it is now, the above commands will only work, if Karaf is in the same machine with the local repository, where the bundles were installed. However, one could deploy the bundles in a remote Maven repository and then instruct Karaf to locate bundles also in it.

In order to deploy bundles in a remote maven repository, you need to follow these steps:

  1. Edit Maven's settings.xml file to add the remote server
  2. Modify the parent pom.xml to define the deployment repository
  3. Run the `mvn clean install deploy` command

In Maven's settings.xml file you should add a new <server> under the <servers> section:

<server>
    <id>prometheus-atc</id>
    <username>repository_user</username>
    <password>repository_password</password>
</server>

The id is the name of the remote repository. You can freely select this. The username and password will be given to you by the remote's repository administrator.

In the parent pom.xml you add a <distributionManagement> section:

<distributionManagement>
    <repository>
        <id>prometheus-atc</id> 
        <name>prometheus-atc-releases</name> 
        <url>http://prometheus.atc.gr:8080/nexus/content/repositories/releases/</url> 
    </repository>
    <snapshotRepository>
        <id>prometheus-atc</id> 
        <name>prometheus-atc-snapshots</name> 
        <url>http://prometheus.atc.gr:8080/nexus/content/repositories/snapshots/</url>
    </snapshotRepository>
</distributionManagement>     

The id in both repository and snapshotRepository should match the id you've set in the settings.xml file. The name and url will be given to you by the administrator.

Another issue you should pay attention to is the versioning of your bundles. Maven will install bundles with the word SNAPSHOT as the qualifier in the snapshot repository. If a concrete version is used, the bundle will be deployed in the release repository. You can't install the same version of an artifact to a release Maven repository twice. This means that a release repository isn't suitable during development phase, where a lot of changes take place. A snapshot artifact can be deployed many times in the repository. It will be automatically assigned a version by Maven (using a timestamp). The repository will always serve the latest version. For this reason, you are encouraged to used the SNAPSHOT qualifier during development.

In order to access the remote repository from Karaf, you need to add it in Karaf's repositories list. These are defined in etc/org.ops4j.pax.url.mvn.cfg file. At the bottom of this file you can add the following lines:

repository_password [at] prometheus [dot] atc [dot] gr:8080/nexus/content/repositories/snapshots/@snapshots@noreleases" title="http://repository_user:repository_password [at] prometheus [dot] atc [dot] gr:8080/nexus/content/repositories/snapshots/@snapshots@noreleases">http://repository_user:repository_password [at] prometheus [dot] atc [dot] gr:8080/nexus/..., \
http://repository_user:repository_password [at] prometheus [dot] atc [dot] gr:8080/nexus/content/repositories/releases/

This is a great way of sharing modules between partners. Anyone can install modules at the remote repository and then everyone could install it with only typing two commands in Karaf's console.

However, there is deficiency in the above method. It only works if Maven is used as the build system. It seems that a lot of people, especially newcomers to OSGi are using Eclipse to build their modules. Eclipse does offer some advantages over Maven for the development of OSGi bundles:

  1. It allows you to edit the Manifest and the component.xml (used in DS services) files graphically
  2. Everything is integrated into a single environment
  3. Running and debugging is very easy. One can configure the dependencies that should be included in the runtime target platform with a graphical interface

However Eclipse really lacks compared to Maven on bundle management. When you are only developing a couple of bundles with a couple of dependencies, you can manage the complexity with Eclipse. For systems with many custom modules and hundreds of dependencies, you do need a tool to do the bundle management for you.

A solution to this problem will be to use Eclipse to build binaries, but then use Maven to deploy them in a remote repository and create a Karaf feature. This isn't so difficult, even for users that are new to Maven. You need to follow these steps:

  1. Download and install Maven (either 2.x or 3.x version)
  2. Modify the settings.xml file as described before
  3. Export your binaries from Eclipse
  4. Deploy the jar files in the remote repository with the `mvn deploy:deploy_file` command
  5. Create a Maven project to host the features.xml and then deploy it in the remote repository as well

In step 3, when you are exporting bundles from Eclipse, it is a good practice to use SNAPSHOT as the qualifier:

This is not necessary, as the version of the deployed bundle is set by maven and not by the filename, but it is good to have a consistency.

After you have exported your bundles, you can deploy them in the remote repository by running the following command in a shell (a Windows system is assumed):

mvn deploy:deploy-file -Durl=http://prometheus.atc.gr:8080/nexus/content/repositories/snapshots/ ^
                       -DrepositoryId=prometheus-atc ^
                       -Dfile=mysql-springjdbc-fragment_1.0.0.SNAPSHOT.jar ^
                       -DgroupId=eu.aniketos.marketplace ^
                       -DartifactId=mysql-springjdbc-fragment ^
                       -Dversion=1.0.0.SNAPSHOT ^
                       -Dpackaging=jar

You need to modify the file option to enter the path of your file and the groupId and artifactId options. I recommend that you leave the version as it is. Make suitable selections for the groupId and the artifactId. Select for example eu.aniketos.moduleName for the group id and bundleName for the artifact Id.

In order to create the Maven feature project you can download the converter-ds-feature code. In the pom.xml you only need to modify the groupId and the artifactId. Enter the same groupId you have used for deploying your bundles. For the artifactId you can simple use feature (if your module contains more than one feature, you would need to differentiate them somehow). These are the contents of the features.xml file:

<features>
  <feature name="converter-ds-feature" version="1.0">
    <bundle>mvn:gr.atc.aniketos.demos.converterservice/converter/1.0.0</bundle>
    <bundle>mvn:gr.atc.aniketos.demos.converterservice/converter-impl/1.0.0</bundle>
    <bundle>mvn:gr.atc.aniketos.demos.converterservice/converter-client/1.0.0</bundle>
    <bundle>mvn:org.apache.felix/org.apache.felix.scr/1.6.0</bundle>
  </feature>
</features>

You need to modify the name of the feature. Users will install the feature in Karaf by typing `features:install feature_name`. Then include all your bundles by providing URLs that use the maven protocol. The maven protocol is very simple:

mvn:groupId/artifactId/version

You also need to include all the required dependencies. You can locate your bundles in SpringSource Enterprise Bundle Repository or another global Maven repository. After editing the features.xml file, you deploy it by running `mvn clean install deploy`.

In Karaf you add a feature with the command (see the top of this post for an example):

features:addUrl mvn:groupId/artifactId/version/xml/features

This was a long post, but I believe it can really help in the sharing of binaries between partners.

 

ANIKETOS newsletter

Stay informed on our latest news!

Login

Only for users who has an user and a password sent by the administrator.