Unsatisfied Requirements: Declarative Services and multiple OSGi dependences

Hi all! I have been developing a binding for the MerossIOT.
It relies on a library that I manufectured which in turn has multiple maven dependencies. The binding installs but it does not start. I get the following message:

Status: Installed
Unsatisfied Requirements:
osgi.wiring.package; filter:="(osgi.wiring.package=com.aayushatharva.brotli4j)"
osgi.wiring.package; filter:="(osgi.wiring.package=com.aayushatharva.brotli4j.decoder)"
osgi.wiring.package; filter:="(osgi.wiring.package=com.aayushatharva.brotli4j.encoder)"
osgi.wiring.package; filter:="(osgi.wiring.package=com.github.luben.zstd)"
osgi.wiring.package; filter:="(osgi.wiring.package=com.google.protobuf)"
osgi.wiring.package; filter:="(osgi.wiring.package=com.google.protobuf.nano)"
osgi.wiring.package; filter:="(osgi.wiring.package=com.jcraft.jzlib)"
osgi.wiring.package; filter:="(osgi.wiring.package=com.ning.compress)"
osgi.wiring.package; filter:="(osgi.wiring.package=com.ning.compress.lzf)"
osgi.wiring.package; filter:="(osgi.wiring.package=com.ning.compress.lzf.util)"
osgi.wiring.package; filter:="(osgi.wiring.package=com.oracle.svm.core.annotate)"
osgi.wiring.package; filter:="(osgi.wiring.package=io.netty.channel.epoll)"
osgi.wiring.package; filter:="(osgi.wiring.package=io.netty.handler.codec.http)"
osgi.wiring.package; filter:="(osgi.wiring.package=io.netty.handler.codec.http.websocketx)"
osgi.wiring.package; filter:="(osgi.wiring.package=io.netty.handler.proxy)"
osgi.wiring.package; filter:="(osgi.wiring.package=io.netty.internal.tcnative)"
osgi.wiring.package; filter:="(osgi.wiring.package=lzma.sdk)"
osgi.wiring.package; filter:="(osgi.wiring.package=lzma.sdk.lzma)"
osgi.wiring.package; filter:="(osgi.wiring.package=net.jpountz.lz4)"
osgi.wiring.package; filter:="(osgi.wiring.package=net.jpountz.xxhash)"
osgi.wiring.package; filter:="(&(osgi.wiring.package=org.apache.logging.log4j.status)(&(version>=2.23.0)(!(version>=3.0.0))))"
osgi.wiring.package; filter:="(osgi.wiring.package=org.bouncycastle.jsse)"
osgi.wiring.package; filter:="(osgi.wiring.package=org.bouncycastle.jsse.provider)"
osgi.wiring.package; filter:="(osgi.wiring.package=org.conscrypt)"
osgi.wiring.package; filter:="(osgi.wiring.package=org.eclipse.jetty.npn)"
osgi.wiring.package; filter:="(osgi.wiring.package=org.jboss.marshalling)"
osgi.wiring.package; filter:="(osgi.wiring.package=reactor.blockhound)"
osgi.wiring.package; filter:="(osgi.wiring.package=reactor.blockhound.integration)"
osgi.wiring.package; filter:="(osgi.wiring.package=sun.security.ssl)"
osgi.wiring.package; filter:="(osgi.wiring.package=sun.security.x509)"
Declarative Services

I realized that the issue is probably related to the binding dependencies and to the OSGi’s package visibility queston.

Here is the library’s bundle manifest:

Manifest-Version: 1.0
Bnd-LastModified: 1727861613123
Build-Jdk-Spec: 17
Bundle-Activator: org.meross4j.bundle.Activator
Bundle-Description: meross4j is a Java library for the Meross cloud
Bundle-License: https://www.eclipse.org/legal/epl-2.0
Bundle-ManifestVersion: 2
Bundle-Name: meross4j Meross Java library
Bundle-SymbolicName: meross4j
Bundle-Version: 0.2.5.20241002-0933
Created-By: Apache Maven Bundle Plugin 5.1.9
Export-Package: org.meross4j;uses:="com.google.gson,com.hivemq,org.apach
 e.commons.codec,org.slf4j,org.jetbrains.annotations,osgi.framework";ver
 sion="0.2.5"
Import-Package: com.google.gson;version="[2.10,3)",com.google.gson.annot
 ations;version="[2.10,3)",com.google.gson.reflect;version="[2.10,3)",co
 m.hivemq.client.mqtt;version="[1.3,2)",com.hivemq.client.mqtt.datatypes
 ;version="[1.3,2)",com.hivemq.client.mqtt.mqtt5;version="[1.3,2)",com.h
 ivemq.client.mqtt.mqtt5.message.auth;version="[1.3,2)",com.hivemq.clien
 t.mqtt.mqtt5.message.connect;version="[1.3,2)",com.hivemq.client.mqtt.m
 qtt5.message.publish;version="[1.3,2)",com.hivemq.client.mqtt.mqtt5.mes
 sage.subscribe;version="[1.3,2)",com.hivemq.client.mqtt.mqtt5.message.s
 ubscribe.suback;version="[1.3,2)",java.io,java.lang,java.lang.invoke,ja
 va.lang.runtime,java.net,java.net.http,java.nio,java.nio.charset,java.n
 io.file,java.time,java.time.temporal,java.util,java.util.concurrent,jav
 a.util.function,java.util.stream,org.apache.commons.codec.digest;versio
 n="[1.17,2)",org.osgi.framework;version="[1.8,2)",org.slf4j;version="[1
 .7,2)"
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=17))"
Tool: Bnd-6.3.1.202206071316

The binding is trying to import the packages which cause the error. I tried with OSGi uses:=
directive to solve the issue but I am new to the framework. How can I satisfy those requirements as I guess they are internal to meross4j lib?
Btw, I have been reading the OSGi in action book by Manning
Thanks

By default bnd (tool used to generate manifest) pulls in a lot of elements. You can reduce these, but you might still need these dependencies to resolve mersos4j library. Even if these are internal dependencies of it, you might need a large set of these to get library working.
Some of packages you miss can be installed through declaration of your binding feature dependencies. These are <feature> elements within first level <feature> elements. For example you can pull hivemq through mqtt transport. Not sure of gson (its part of distribution). Its much harder with others, for this you might need to either embed dependency (to override its manifest) or re-package it.

I followed your suggestions but as you said dealing with external libraries that are not bundled in openhab-core is not an easy task that, as a consequence, makes the binding finalization a difficult goal to achieve given my poor OSGi background. Anyway, I will try a workaround to control Meross plugs! :wink:
Thank you so much for your support!

You can place additional instructions using bnd file like here:

Instruction you need is either Export-Package or Private-Package which are evaluated at build time against compile classpath.
Making Export-Package will expose given package from your bundle to others. The Private-Package will let you wrap selected packages internally without making it available to others.
By proper manipulation of these headers you can embed dependency listed in pom.xml. It takes a bit to find a proper set of these instructions, but by doing so you can avoid creation of transport bundle in openHAB core and also simplify development. As you do not need to publish anything but your addon.
For start try declaring private package with meross4j root package and start adding step by step further packages needed by it.

Hope it makes it a little bit clearer to you and will let you move forward. The -nouses instruction within bnd file removes uses directive attached to imported packages.

That’s very kind of you! I will try the solution and I will update you soon!

Hi! Following your suggestions, I explored two solutions and in both cases the unsatisfied requirements regards hivemq lib only;so I am in a turning point! :grinning:

Solution 1:

meross4j pom (maven-bundle plugin section)

<plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>5.1.9</version>
                <executions>
                    <execution>
                        <id>bundle-manifest</id>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>manifest</goal>
                        </goals>
                    </execution>
                </executions>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Export-Package>org.meross4j.*,com.google.gson.*; version="2.10",com.hivemq.client,
                            org.apache.commons.codec, io.reactivex.*,org.apache.logging.*,org.osgi.*;org.reactivestreams.*,
                            org.jetbrains.*</Export-Package>
                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                        <Bundle-Activator>org.meross4j.bundle.Activator</Bundle-Activator>
                        <Bundle-Version>$(replace;$(project.version);"").$(tstamp;yyyyMMdd-HHmm)</Bundle-Version>
                    </instructions>
                </configuration>
            </plugin>

Meross IOT binding bnd file

Bundle-SymbolicName: ${project.artifactId}
DynamicImport-Package: *
Import-Package: org.meross4j.*,com.google.gson.*; version="2.10",com.hivemq.client,
org.apache.commons.codec, io.reactivex.*,org.apache.logging.*,org.osgi.*;org.reactivestreams.*,
org.jetbrains.*

I get this error:

openHAB Add-ons :: Bundles :: MerossIOT Binding (280)
-----------------------------------------------------
Status: Installed
Unsatisfied Requirements:
osgi.wiring.package; filter:="(osgi.wiring.package=com.hivemq.client)"
Declarative Services

Solution 2:

<plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>5.1.9</version>
                <executions>
                    <execution>
                        <id>bundle-manifest</id>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>manifest</goal>
                        </goals>
                    </execution>
                </executions>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Export-Package>org.meross4j.*,com.google.gson.*; version="2.10",com.hivemq.client.*,
                            org.apache.commons.codec, io.reactivex.*,org.apache.logging.*,org.osgi.*;org.reactivestreams.*,
                            org.jetbrains.*</Export-Package>
                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                        <Bundle-Activator>org.meross4j.bundle.Activator</Bundle-Activator>
                        <Bundle-Version>$(replace;$(project.version);"").$(tstamp;yyyyMMdd-HHmm)</Bundle-Version>
                    </instructions>
                </configuration>
            </plugin>

MerssIOT binding bnd file

Bundle-SymbolicName: ${project.artifactId}
DynamicImport-Package: *
Import-Package: org.meross4j.*,com.google.gson.*; version="2.10",com.hivemq.client.*,
org.apache.commons.codec, io.reactivex.*,org.apache.logging.*,org.osgi.*;org.reactivestreams.*,
org.jetbrains.*

This time i get this error:

openHAB Add-ons :: Bundles :: MerossIOT Binding (280)
-----------------------------------------------------
Status: Installed
Unsatisfied Requirements:
osgi.wiring.package; filter:="(&(osgi.wiring.package=com.hivemq.client.mqtt)(&(version>=1.3.0)(!(version>=2.0.0))))"
osgi.wiring.package; filter:="(&(osgi.wiring.package=com.hivemq.client.mqtt.datatypes)(&(version>=1.3.0)(!(version>=2.0.0))))"
osgi.wiring.package; filter:="(&(osgi.wiring.package=com.hivemq.client.mqtt.mqtt5)(&(version>=1.3.0)(!(version>=2.0.0))))"
osgi.wiring.package; filter:="(&(osgi.wiring.package=com.hivemq.client.mqtt.mqtt5.message.auth)(&(version>=1.3.0)(!(version>=2.0.0))))"
osgi.wiring.package; filter:="(&(osgi.wiring.package=com.hivemq.client.mqtt.mqtt5.message.connect)(&(version>=1.3.0)(!(version>=2.0.0))))"
osgi.wiring.package; filter:="(&(osgi.wiring.package=com.hivemq.client.mqtt.mqtt5.message.publish)(&(version>=1.3.0)(!(version>=2.0.0))))"
osgi.wiring.package; filter:="(&(osgi.wiring.package=com.hivemq.client.mqtt.mqtt5.message.subscribe)(&(version>=1.3.0)(!(version>=2.0.0))))"
osgi.wiring.package; filter:="(&(osgi.wiring.package=com.hivemq.client.mqtt.mqtt5.message.subscribe.suback)(&(version>=1.3.0)(!(version>=2.0.0))))"
Declarative Services

So, i guess solution 2 shows more messages given that OSGi looks inside hivemq’s subpackages whereas the first one does not. So this seems to be the right solution. Now, should I export and import these “atomic subpackages” one by one? how else could I terminate such recursive requirements? At what level of package granularity do requirements end?

Moreover, I read some papers regarding DynamicImport-Package directive but I cannot fully grab the idea behind that yet.
Thanks