Running 4.1 addons under 4.0 (library version issues)

I am trying to build some bindings in the current 4.1 snapshot (main branch) and they run fine under 4.1, but if I try to run them under 4.0.3 I get all sorts of versioning issues.
Things like gson and javax.measure have a minimum higher version under 4.1, for example:

2023-10-10 22:06:20.182 [WARN ] [org.apache.felix.fileinstall        ] - Error while starting bundle: file:/usr/share/openhab/addons/org.openhab.binding.tesla-4.1.0-SNAPSHOT.jar
org.osgi.framework.BundleException: Could not resolve module: org.openhab.binding.tesla [302]
  Unresolved requirement: Import-Package: com.google.gson; version="[2.10.0,3.0.0)"

So I can work around that by changing the pom.xml to specify the version that 4.0.3 has or import the newer version of the library into 4.0.3, but is there an easier way to do it? I naively thought that specifying -Dohc.version=4.0.3 would do something magical put apparently not…

Also does anyone know how to get the “jakarta.annotation” in 4.0.3? For example if you try to compile the Tesla binding in snapshot and run it under 4.0.3 you will get the following:

2023-10-10 23:26:40.833 [INFO ] [org.apache.felix.fileinstall ] - Updating bundle org.openhab.binding.tesla / 4.1.0.202310110322
2023-10-10 23:26:40.916 [WARN ] [org.apache.felix.fileinstall ] - Error while starting bundle: file:/usr/share/openhab/addons/org.openhab.binding.tesla-4.1.0-SNAPSHOT.jar
org.osgi.framework.BundleException: Could not resolve module: org.openhab.binding.tesla [304]
Unresolved requirement: Import-Package: jakarta.annotation

I want to run 4.1 bindings under 4.0.3 is because is very helpful (to me) to be able to easily work in main to fix bugs, but run it on my production system which is kept at the last major release. I have a lot of my things and items in static config (with other dependent rules) and it’s a hassle to keep moving those back to the dev environment. The harder it is to get things to run easily on one version back the less time I spend fixing bugs.

Thanks.

It seems excessive but here’s my pom.xml to get the Tesla binding for 4.1 to run under 4.0.3, in case it helps anyone else who is trying to do something similar.

  <dependencies>
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.9.1</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>javax.measure</groupId>
      <artifactId>unit-api</artifactId>
      <version>2.1.3</version>
    </dependency>
    <dependency>
      <groupId>jakarta.annotation</groupId>
      <artifactId>jakarta.annotation-api</artifactId>
      <version>2.0.0</version>
    </dependency>
    <dependency>
      <groupId>jakarta.inject</groupId>
      <artifactId>jakarta.inject-api</artifactId>
      <version>2.0.0</version>
    </dependency>
    <dependency>
      <groupId>jakarta.inject</groupId>
      <artifactId>jakarta.inject-api</artifactId>
      <version>2.0.0</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>2.0.0</version>
    </dependency>
  </dependencies>

Why use all these workarounds that may work today but not tomorrow if some dependency gets upgraded again? I always find it easier to create a branch based on 4.0.x and then merge my changes to it. That is guaranteed to work.

Is it possible to relax the options for the libraries used to a few prior versions that the older runtime OH versions have? Is there a reason compatibility for things like gson has to be starting with the very latest version? What is the mvn -Dohc.version=4.0.3 supposed to do? Reading the docs it seems like that should produce a bundle/addon that works with 4.0.3, even if I am in main.

The reason I want to work in main is to test the very latest fixes and make sure that I’m not duplicating any extra work. There has been at least one time that I’ve added something only to find somebody else had fixed it already in main. I’m totally cool with running the 4.1 snapshot on my dev system but as a final step I want to make sure it works on my prod system which (I think reasonably) is held at the last stable version. So I really want it to work on both.

The version ranges are generated automatically by Bnd so devs do not have to spend time on micromanaging dependency version ranges. We already have add-ons that won’t work with the older dependency versions part of OH 4.0. Besides dependencies there can also be breaking API changes. After a while the main branch will become very incompatible with 4.0.x. That’s also why we use separate branches for patch releases just like most other software projects.

Well… version ranges are under control, and they can be adjusted to be more permissive or free of version ranges at all. I intentionally disable some of metadata placed by bnd in manifests, because it brings joy for tool, but doesn’t make much sense when you deploy onto predefined runtime (think of Require-Capability and all fancy things you find there).
Looking at code changes in core, most of binding code could remain intact between 3.0-3.1. Then after aligning of UoM library most of code between 3.2-3.4 worked just fine. Many of major dependency updates retain APIs thus compilation errors are very rare. I believe similar will be for 4.0-4.1 with all crazy changes caused by jakarta packets.

I do maintain several addons based on OH 3.0.x and keep rebasing it to upper versions. Recently I rebased all of them to 4.0.x. Key aspect in doing so - I keep moved pom and dependency updates to separate commits. Once I need to build specific version I just do a sequence of git checkout 3.4.x; git rebase master; git push -f github 3.4.x:3.4.x. Obviously it works just for me because I can make a foce push without being at risk of overriding somebody else work. :wink:

See below:


As you can see 3.0.x branch is base for 3.2.x, 3.3.x and 3.4.x.

However, for these who wish to maintain and work on their binding - with a bit of handcrafted commits you can build same pipeline. I made also some experiments to automate that work with dedicated tooling / cicd workflow.

If you rebase to master won’t you get the pom with no dependencies and the 3.4.x will just compile expecting the current versions, requiring the current snapshot OH?

I remember when a user reported a bug we could fix it in main and then say “try out the snapshot” (in your version of OH). I guess if a user reports a bug now we would also ask them to install snapshot OH to verify that the bug is fixed.

For large repository such as openhab-addons rebase from higher version to lower will probably give you a lot conflicts.
I’d suggest you to cherry pick selected commits with necessary changes from main to 4.0.x. By this way you reduce probability of conflicts to minimum. Just identify last commit in your binding which is common for both branches and then start cherry picking from main back to 4.0x. The syntax is git cherry-pick <commit-sha>. You will need to solve conflicts with i.e pom version changes (if its just a version, you can skip commit) and import packages, however you need to do it once per change set if patch do not apply.
If you wish to make it more hacker way - you can create bnd.bnd file and place there overrides.

A basic idea would be:

Import-Package: org.openhab*;version=4.0, com.google*;version=0

For jakarta annotations you can ban their import (annotations are not mandatory to be present at runtime) by adding !jakarta.annotation* to import package list. Same thing applies to not null annotation, they are relevant during compile time.

Could I please have a copy of the Tesla snapshot?
I’m still running on OH 4.0.3

It won’t run on 4.0.3 without recompiling it with the dependencies listed above. I deleted my branch with the 4.0.3 compatible build since the changes were already added to 4.1. You might want to run the 4.1 milestone build and then the 4.1 snapshot will work.

If you need it to run under 4.0.3 you can check out main and change the pom.xml to include the dependencies above, and then it should work on 4.0.3 – at least it does for me.