Skip to main content

Upgrade

NomaUBL releases ship as a new nomaubl.jar. A single command — nomaubl.sh upgrade <env> on Linux/macOS or nomaubl.cmd upgrade <env> on Windows — takes an installed environment from whatever release it currently runs to the release of the JAR in place. It stops the service, runs the Java-side -upgrade arm (schema migrations, reference-data merge, framework XSL refresh, per-document XSL merge) and restarts the service. A full report lands under ${appHome}/upgrade-reports/ and a rollback backup under ${appHome}/backup/<timestamp>/.

The same command runs on every supported platform — there is no Linux-only or Windows-only upgrade path. Pick the wrapper that matches your host.


Two ways to invoke​

Linux / macOS
# Option A — the JAR is already in place
./nomaubl.sh upgrade prod

# Option B — let the wrapper swap the JAR for you first
./nomaubl.sh upgrade prod /tmp/nomaubl-2026.06.0.jar
Windows
REM Option A — the JAR is already in place
nomaubl.cmd upgrade prod

REM Option B — let the wrapper swap the JAR for you first
nomaubl.cmd upgrade prod C:\downloads\nomaubl-2026.06.0.jar
ArgumentDescription
envEnvironment name — same one used by start, stop, etc. The wrapper resolves the config from <env>/config/config.json.
new_jar (optional)Path to the JAR to upgrade to. The wrapper copies it over the existing nomaubl.jar (Linux) or nomaubl-fat.jar (Windows) before running the upgrade. Omit if you already replaced the JAR by hand.
--from-version <X.Y.Z> (optional)Override the auto-detected baseline. By default the upgrader reads the current installed version from the upgrade-history table and applies every migration strictly newer than that. For environments that were hand-patched ahead of schedule, the auto-detected baseline can be wrong; --from-version forces the start point, so only migrations strictly newer than the supplied version run. Full reference: Command Line → --from-version.

Both forms produce the same end state. Use the second when you want a single command to do everything; use the first when your release pipeline already drops the new JAR in place. Combine with --from-version when you need to override the auto-detected baseline:

Manual baseline override
./nomaubl.sh upgrade prod --from-version 2026.05.20 # only migrations newer than 2026.05.20 run

At a glance — what the upgrade does​

nomaubl.sh / nomaubl.cmd upgrade <env> — the steps in order1 · STOP & BACKUPstop service if runningsnapshot under backup/2 · DATABASEapply schema deltasOracle and PostgreSQL3 · REFERENCE DATAmerge new entrieskeep customer overrides4 · FRAMEWORK XSLrefresh ubl-common + rulesSchematron, XSD5 · PER-DOCUMENT XSL — REWRITE WITH MERGEcustomer TAG_ values kept · OVERRIDES block keptnew TAGs added with defaults · removed TAGs flagged6 · REPORT & RESTART${appHome}/upgrade-reports/upgrade-YYYYMMDD-HHmmss.mdre-start service (only if it was running before)stops here on first error — service stays down, backup still on disk

The per-step reference (what -upgrade does internally, what's preserved, what's refreshed) lives on the Command Line → upgrade page.

Customer-edited ubl-defaults.xsl is preserved​

The framework-XSL refresh (step 4) no longer overwrites ubl-defaults.xsl. This file usually carries customer customisations — seller SIREN / VAT / address per company code, VAT category mappings, payment-code lookups, the date format — that an earlier wholesale replace used to wipe silently. It is now soft-refreshed:

  • a fresh install receives the bundled defaults;
  • an upgrade keeps the customer's file untouched;
  • when the shipped version differs from the customer's, the shipped one is written alongside as ubl-defaults.xsl.upstream for manual review.
  • when the customer's file holds its own version of a framework template (the seller party, for example), the upgrade adds to it the parameters the new framework passes — with their shipped defaults, the body untouched — so the file keeps compiling; the customised body ignores the new values until it is updated from the .upstream copy.

The upgrade report lists every kept file under an Assets preserved section. The same protection covers the ${env}/ubl/ mirror, which the upgrade also refreshes so per-document XSLs never import a stale framework copy.

Reference lists and shipped connectors are completed​

The upgrade adds what the bundled configuration has and the instance lacks, matched by code or by name, and changes nothing else:

  • Reference lists receive their missing codes; codes already there keep their labels. The Invoice Type Codes list also gets the invoice / credit note type of each code.
  • Shipped API and SQL connectors already present receive the endpoints or queries they lack (for example the queries of jde-sql); their connection settings and existing endpoints and queries are kept.

The upgrade report lists the additions under New entries — reference lists, connector endpoints and queries.


Before you upgrade​

CheckWhy
The new JAR is the one you intend — java -jar nomaubl.jar -help prints the version at the top.Catches a wrong build sitting next to the wrapper.
The service user can write to the env directory + the parent.The upgrade rewrites template/, xslt/, .versions/ and creates a backup. A read-only filesystem stops the upgrade at step 1.
The database account has the same DDL rights as on install (create tables, indexes, sequences, views).Step 2 applies schema deltas — DDL rights are required even on a same-version idempotent run.
A real database backup is in place (not just the per-env backup/ snapshot).The backup/ directory keeps a copy of files on disk; it does not snapshot the database. Take your usual DB backup before a major release.
A maintenance window wide enough for a restart — typically 1-5 minutes per environment.The service is unavailable from step 1 until step 6.

You don't need to put NomaUBL into any special "maintenance mode" beyond stopping the service — the wrapper handles that automatically.


Run it​

Linux / macOS​

cd /opt/nomaubl
./nomaubl.sh upgrade prod

Sample output:

[upgrade] env: prod
[upgrade] stopping service...
NomaUBL [prod] stopped
[upgrade] running -upgrade (this may take a minute)...
... (Java-side step log) ...
[upgrade] starting service...
Starting NomaUBL [prod] (port=8090)...
NomaUBL [prod] started (PID 12347)
URL: http://localhost:8090/
Log: /opt/nomaubl/nomaubl-prod.log

Windows​

cd C:\nomaubl
nomaubl.cmd upgrade prod

Same output, same exit code semantics — 0 on success, non-zero on failure.

Several environments​

The upgrade is per-environment. With three environments on the same host, run the command three times:

Linux / macOS
./nomaubl.sh upgrade demo
./nomaubl.sh upgrade uat
./nomaubl.sh upgrade prod
Windows
nomaubl.cmd upgrade demo
nomaubl.cmd upgrade uat
nomaubl.cmd upgrade prod

Promote in the order your release process dictates (typically demo → uat → prod). Each run uses the same JAR — the JAR is shared across environments on the host.


If something fails​

The wrapper exits non-zero and leaves the service stopped. You'll see:

[upgrade] ⚠ FAILED — service left stopped.
[upgrade] Inspect the report under ${appHome}/upgrade-reports/ and
[upgrade] roll back from ${appHome}/backup/<latest>/ if needed.

The two files to look at:

FileWhereWhat it tells you
The upgrade report${appHome}/upgrade-reports/upgrade-<timestamp>.mdPer-step outcome. The report header carries the resolved env directory and the JDBC URL so a wrong-host / wrong-path mistake is obvious at a glance.
The backup snapshot${appHome}/backup/<timestamp>/A pre-upgrade copy of the env directory + the old JAR. Use this for a rollback.

Rollback​

Linux / macOS
./nomaubl.sh stop prod # safety — usually already stopped
cp -r /opt/nomaubl/backup/<timestamp>/* /opt/nomaubl/prod/
cp /opt/nomaubl/backup/<timestamp>/nomaubl.jar /opt/nomaubl/ # restore the previous JAR
./nomaubl.sh start prod
Windows
nomaubl.cmd stop prod
xcopy /E /I /Y C:\nomaubl\backup\<timestamp>\* C:\nomaubl\prod\
copy /Y C:\nomaubl\backup\<timestamp>\nomaubl-fat.jar C:\nomaubl\nomaubl-fat.jar
nomaubl.cmd start prod

After a rollback, take a fresh database backup before retrying the upgrade — the schema deltas may have partially applied before the failure.

Retry​

The Java-side -upgrade is idempotent: re-running on the same environment skips the steps that already succeeded and resumes from the failed one. Once the underlying issue is fixed (network, missing privilege, etc.), simply re-run:

./nomaubl.sh upgrade prod # or nomaubl.cmd upgrade prod

Settings → Upgrade History​

Every install, upgrade and migration that ran on the environment is listed under Settings → Upgrade History. Click a row to see the full report on the right pane — same content as the file under ${appHome}/upgrade-reports/. The list is read-only; nothing can be re-run from this page.

This is the operator-facing audit trail — useful for confirming "yes, we ran 2026.06.0 on prod last Tuesday" without SSH'ing to the host.


Common upgrade pitfalls​

MistakeSymptomFix
Running upgrade against the wrong env.Wrong environment goes down for a minute.Read the [upgrade] env: <env> line at the start; cancel with Ctrl+C if it's not the intended one.
The new JAR is missing or corrupt.[upgrade] new JAR not found: <path> or Error: Unable to access jarfile.Verify the file exists and has the expected size; re-download if needed.
The service was started by hand outside the wrapper.Wrapper sees no PID file → thinks the service isn't running → upgrade proceeds without stopping the JVM. Two processes briefly contend for the database.Always use the wrapper to start/stop the service.
Schema delta fails because the DB user lost DDL rights.The report logs ORA-01031: insufficient privileges (Oracle) or permission denied for schema (PostgreSQL).Re-grant CREATE TABLE, CREATE INDEX, CREATE SEQUENCE, CREATE VIEW; re-run the upgrade.
The custom XSL has stale TAGs flagged.The report lists per-template entries under "removed TAGs".Open the template's .xsl and remove the <!-- removed in <version> --> lines once you've adapted to the change.
Disk full on the env partition.Backup step fails.Free space; re-run. The backup/ directory grows with retained snapshots — prune old ones to keep disk usage bounded.

What's next​