How to include Maven dependencies in binding?

Hi folks,
Im totally stuck to include any kind of rest client in my binding.
Currently Im developing a Binding for a Siemens Coffeemaker which we want to use in a research project at University (and maybe publish later if there is a need :slight_smile: ).

I already created a standalone Java CLI Application which uses the retrofit2 rest client lib. I can’t get the code working inside the OpenHAB 3 Binding.

The error is: Unresolved requirement: Import-Package: okhttp3

Okhttp3 is a nested dependency of retrofit

The pom.xml file:

<artifactId>org.openhab.binding.homeconnectcoffee</artifactId>
  <properties>
    <bnd.importpackage>!android.*,!kotlin.*,!kotlinx.*,!com.android.org.*,!dalvik.*,!javax.annotation.meta.*,!org.apache.harmony.*,!org.conscrypt.*,!sun.*</bnd.importpackage>
  </properties>


  <name>openHAB Add-ons :: Bundles :: HomeConnectCoffee Binding</name>
  <dependencies>
    <dependency>
      <groupId>com.squareup.retrofit2</groupId>
      <artifactId>converter-jackson</artifactId>
      <version>2.9.0</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.squareup.retrofit2</groupId>
      <artifactId>retrofit</artifactId>
      <version>2.9.0</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>

feature.xml:

<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.binding.homeconnectcoffee-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
	<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>

	<feature name="openhab-binding-homeconnectcoffee" description="HomeConnectCoffee Binding" version="${project.version}">
		<feature>openhab-runtime-base</feature>
		<feature>wrap</feature>
		<bundle dependency="true">mvn:com.squareup.retrofit2/retrofit/2.9.0</bundle>
		<bundle dependency="true">mvn:com.squareup.okhttp3/okhttp/3.14.9</bundle>
		<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.homeconnectcoffee/${project.version}</bundle>
	</feature>
</features>

I have absolutely no idea what I made wrong.

Maybe there is someone out there who is more familiar with OSGi who can help me?

Thank you very much :slight_smile:

Edit: the wrap entry in the feature.xml was just try and error :smiley:

It sounds like you are hitting issues described in 3rd party Maven dependencies in openhab core - #2 by pravussum

I do not think you need to specify the dependency in feature.xml since you compile in the dependency. You need to make sure bnd does not add the dependency as osgi requirement (once again that would be unnecessary since they are compiled in) – do this via bnd.importpackage

1 Like

Also note that there is a recommendation to use already existing dependencies for some default libraries - HTTP clients being one of them. Refer to Coding Guidelines | openHAB (“Default libraries”)

2 Likes

Thanks for the hint, @ssalonen! Its working now. Wuhuuu :crazy_face:

@pravussum
There are cases in which you don’t want to reinvent a REST-Client. A lot of existing OpenHAB addons are rellying on okhttp including the OpenHAB cloud connector. Retrofit (Generator for REST clients) uses okhttp and my needed SSE-client uses okhttp too.
Is it possible to include those frequently used libraries in the runtime in the future?
I switched from Jackson to Gson because I saw that Gson is the preferred way (mentioned in the guidelines).

Now my pom.xml looks like this. Is this really the way to go to include all transitive dependencies manually and exclude them from BND? Feels a little bit like a workaround…

  <properties>
    <bnd.importpackage>com.squareup.*;resolution:=optional, org.conscrypt.*;resolution:=optional,\
      javax.annotation.*;resolution:=optional, okhttp3;resolution:=optional,okio;resolution:=optional,\
      retrofit2.*;resolution:=optional,\
      android.*;resolution:=optional,com.android.*;resolution:=optional,\
      dalvik.*;resolution:=optional,\
      kotlin.*;resolution:=optional, kotlinx.*;resolution:=optional,\
      sun.*;resolution:=optional
    </bnd.importpackage>
  </properties>


  <name>openHAB Add-ons :: Bundles :: HomeConnectCoffee Binding</name>
  <dependencies>
    <dependency>
      <groupId>javax.annotation</groupId>
      <artifactId>javax.annotation-api</artifactId>
      <version>1.3.2</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.squareup.retrofit2</groupId>
      <artifactId>converter-gson</artifactId>
      <version>2.9.0</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.squareup.retrofit2</groupId>
      <artifactId>retrofit</artifactId>
      <version>2.9.0</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.squareup.okhttp3</groupId>
      <artifactId>okhttp</artifactId>
      <version>3.14.9</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.squareup.okio</groupId>
      <artifactId>okio</artifactId>
      <version>1.17.2</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>

Well…to my understanding transitive dependencies are not automatically compiled in, check out openhab-addons pom.xml: openhab-addons/pom.xml at e9cd6de0336ce1b4f71164535e70fa4fc7c8251a · openhab/openhab-addons · GitHub

I guess you could try this out and see how it influences generated kar (mvn karaf:kar) and jar (mvn install) files?

I’m by no means an OSGI expert, but this is the way I ended up doing it in a PR (felt the same way about the transitive dependencies). Got no feedback yet, but it compiles and works :stuck_out_tongue:
It helps a lot to have a look at the created manifest in the compile output directory and try to understand how OSGI, Karaf and the bnd / Maven plugins play together. Took me a while of reading, but otherwise the trial&error method will probably get you nowhere.