Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to embed external jars dependency in OSGI bundles?

I am trying to convert my project into an OSGI application. I have few doubts. Suppose ModuleA in my application is dependent on external jars jarA and jarB. Now to make ModeuleA run, I am embedding both the jars using embed-dependency property of maven-bundle-plugin. Now suppose I have another module ModuleB which is also dependent on jarA. So this module also embeds the jarA. My project ends up having jarA being embedded 2 times which will unnecessarily bloat the size of project.

Is there any way to tell OSGI to load jarA only once and provide it to both the modules.

If converting these jars to OSGI bundles is the only solution, I have few more questions:

  1. What is the easiest way to convert jar to a bundle. BND tool looks like a good solution but I am not able to find proper documentation about it.

  2. jarA will also have some dependent jars. So do I need to convert all the dependent jars to bundles also. My project has more than 100 jars. How can I automate this process.

Thanks in advance :)

like image 490
Uday Ogra Avatar asked Nov 07 '22 16:11

Uday Ogra


1 Answers

There are actually to solutions to this, both a little bit different from what you are doing right now:

  1. Build one "third party dependencies" bundle, which will embed all of the non OSGi dependencies your project has.
  2. Convert every non OSGi dependency to a OSGi bundle.

Option 1 is easier to handle so I think most projects do this. I, personally, prefer option 2. We have a Maven "pom.xml" template that we use to convert those dependencies.

The "pom.xml" looks like this:

<?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>

    <properties>
        <library.groupId></library.groupId>
        <library.artifactId></library.artifactId>
        <library.version></library.version>
    </properties>

    <artifactId></artifactId>
    <packaging>bundle</packaging>

    <name></name>
    <description>${library.groupId}:${library.artifactId}:${library.version}</description>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Import-Package>*;resolution:=optional</Import-Package>
                        <Export-Package>*</Export-Package>
                        <Embed-Dependency>*;scope=compile|runtime;inline=true</Embed-Dependency>
                        <Embed-Transitive>true</Embed-Transitive>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>${library.groupId}</groupId>
            <artifactId>${library.artifactId}</artifactId>
            <version>${library.version}</version>
        </dependency>
    </dependencies>

</project>

This does:

  1. Add the non OSGi library as dependency
  2. Tell maven-bundle-plugin to embed this dependency (transitive)
  3. Tell maven-bundle-plugin to export all of the dependencies packages

I left some things blank that you have to set like library.groupId, library.artifactId and library.version. And somethings we need to tweak the configuration of the maven-bundle-plugin. But this is our starting point. Somethings for example, you do not want to export all packages etc.

If you really have 100+ dependencies that you need to convert you might be better of using this template and just adding all of your 100 dependencies as dependency and build one big bundle with all of them inside.

You can find the documentation for the maven-bundle-plugin here:

https://felix.apache.org/documentation/subprojects/apache-felix-maven-bundle-plugin-bnd.html

At this point I also want to mention that there is a new bundle plugin that you might want to consider for this: bnd-maven-plugin.

See: https://github.com/bndtools/bnd/tree/master/maven/bnd-maven-plugin

like image 81
Jens Avatar answered Nov 15 '22 06:11

Jens