Note
Which Niagara version to stamp a module for
A module that refuses to install with a dependency error is usually not incompatible. It is stamped too high — and the fix is a build flag, not a port.
- Module development
- Mixed estates
- Build tooling
The failure this prevents
You build a module on a development machine, sign it, push it to a controller, and the Software Manager refuses it with a dependency error naming a Niagara version higher than the one the controller runs. Nothing is wrong with the code. The module has simply declared that it needs a newer framework than it actually needs.
This is the single most common reason a perfectly good module will not install on an estate that was not all commissioned in the same year — and most estates were not.
What the declared version actually means
A module declares what it needs in module.xml, as a set of dependencies
each carrying a vendor version. That version is a minimum. It says
"do not load me on anything older than this". It does not say "load me only on
this".
So a module stamped at the version of the SDK that happened to be installed on the build machine will install on that version and everything newer, and be refused everywhere older. Stamp the same module at the oldest version in the estate and it installs across the whole estate, including everything newer.
The rule. Compile against the newest SDK you have. Stamp for the oldest station the module has to run on. These are two separate decisions and the build should let you make them separately.
Why compiling on a newer SDK is usually safe
The instinct is that building on a newer framework must produce something the older one cannot load. Within a single Niagara generation that is rarely true, for two reasons.
The first is the Java level: it is constant across the generation, so the bytecode a newer SDK emits is bytecode an older station's JVM already understands. The second is that most module code touches a small, old, stable part of the API — component and property declarations, ORD resolution, BQL, the driver framework. That surface has barely moved.
The claim is checkable rather than hopeful. Walk the constant pool of the built jar, list every framework class and method it references, and compare that against the API present in the oldest target. If the list contains nothing introduced after the floor version, the module will load. If it does contain something newer, you have found the real incompatibility instead of guessing at one.
Where it does bite
Two places, in practice.
| Area | What to watch |
|---|---|
| Browser CSS | Workbench embeds a browser engine, and an older Workbench embeds an older
one. A ux widget using recent CSS — container queries, modern
selector features — can look correct in a current browser and broken inside
an older Workbench. The station is not the constraint here; the viewing
engine is. |
| New API | If the code genuinely calls something that did not exist at the floor version, no stamp will save it. Either guard the call and degrade, or ship two builds. Knowing which of the two you are in is the point of checking the jar's API surface. |
How to make this routine
Make the target version an argument to the build rather than something inherited from whatever is installed. A build that defaults to the developer's own installation will quietly produce a module that only works on the developer's own installation, and nobody finds out until it is in front of a customer.
Then record the floor version in the delivery note, so that when the estate gains a controller two generations older than anything else on site, the question "will this load" has a written answer.
Related
Where this comes up in the work
Custom modules & drivers
Bespoke Niagara rt, wb and ux modules and drivers written against the Baja API: pure Java, signed, and stamped to install across a mixed estate.
Niagara 5 migration
Niagara 5 readiness audits and migration: which third-party modules survive the new runtime and mandatory signing, and porting your modules so they load.
More notes
Other things worth writing down
What a station checks before loading a module
Niagara's three module verification modes, what each one demands of your certificate, and why the setting cannot be relaxed from the command line.
- Module signing
- Certificates
- Deployment
Pure Java, or it will not run on a JACE
A controller is an ARM host with a fraction of a server's memory. Native libraries, JNI and heavyweight dependencies do not survive the move from a PC.
- JACE
- Controllers
- Module development
Renaming and tagging points in bulk
Point names arrive from the field device and there is no standard. What to use to select, rename and tag in bulk — and what a rename quietly breaks.
- Bulk engineering
- Tagging
- Workbench
Next step
Tell us the version, the hardware, and what it has to do.
You will get a written scope and a fixed price against it. If the honest answer is that you do not need us, you will get that instead.