Command Line
NomaUBL ships with a complete command-line interface that mirrors every operational action available in the web UI — installing an environment, starting the HTTP server, running an XML or UBL processing batch, polling the Plateforme Agréée, extracting from JD Edwards. The CLI is the natural choice for system installations, cron / scheduler integrations, CI pipelines and any headless environment without web access.
The CLI applies regardless of source system — JD Edwards, SAP, NetSuite or a custom ERP — although a few subcommands (extract, BIP / FTP sources of fetch-single / fetch-all) are JD-Edwards-specific.
Two ways to invoke
NomaUBL exposes two equivalent layers — a service-control wrapper (nomaubl.sh) and the direct JAR modes (java -jar nomaubl.jar -…). The wrapper resolves the configuration file from a short environment name and adds start / stop / restart / status / log operations on top of the JAR.
| Layer | When to use |
|---|---|
nomaubl.sh (wrapper) | Day-to-day operations on a server hosting one or several environments. Manages a PID file per instance, takes the environment name instead of the full config path, exposes start / stop / restart / status / log. |
java -jar nomaubl.jar (direct) | Shipping NomaUBL inside a container, integrating into a CI pipeline, or any context that already manages process lifecycle. Takes the absolute path to config.json. |
The wrapper resolves its config from <script_dir>/<env>/config/config.json — i.e. the JAR sits next to one or more environment directories, each holding a config/config.json.
Service control with nomaubl.sh
Lay out the JAR and one environment per service instance, then drive each one by its short name:
| Subcommand | Effect |
|---|---|
start <env> [port] | Spawn java -jar nomaubl.jar -serve <env>/config/config.json <port> in the background. Default port is 8090. The PID is stored in nomaubl-<env>.pid; stdout / stderr are appended to nomaubl-<env>.log. Refuses to start if the PID file points to a live process. |
stop <env> | Send SIGTERM to the recorded PID; waits up to 10 s, then SIGKILL if still running. Cleans up the PID file. |
restart <env> [port] | Convenience: stop then start. |
status [env] | With an env name, reports running (with PID) or not running. With no argument, lists every nomaubl-*.pid and prints the state of each instance — and prunes stale PID files for processes that are no longer alive. |
log <env> | Tail the log file (tail -f nomaubl-<env>.log). |
upgrade <env> | End-to-end upgrade of an existing environment to the JAR currently in place. See upgrade below. |
backfill-vat <env> <fromDate> <toDate> | Rebuild the VAT detail table (F564234) for every invoice issued in [fromDate, toDate] from the UBL document already kept on each invoice. See backfill-vat below. |
Beyond service control, the wrapper exposes short forms of the JAR's processing and synchronisation modes:
| Wrapper command | JAR equivalent |
|---|---|
nomaubl.sh process <env> <template> <file|dir> [type] [flags] | java -jar nomaubl.jar -process <env>/config/config.json <template> <file|dir> [type] [flags] |
nomaubl.sh fetch-import <env> | java -jar nomaubl.jar -fetch-import <env>/config/config.json |
nomaubl.sh fetch-status <env> | java -jar nomaubl.jar -fetch-status <env>/config/config.json |
nomaubl.sh fetch-single <env> <template> <source> <args…> [type] [flags] | java -jar nomaubl.jar -fetch-single … |
nomaubl.sh fetch-all <env> <template> <source> [type] [flags] | java -jar nomaubl.jar -fetch-all … |
nomaubl.sh extract <env> <jobNumber> [flags] | java -jar nomaubl.jar -extract <env>/config/config.json <jobNumber> [flags] |
nomaubl.sh install <targetDir> | java -jar nomaubl.jar -install <targetDir> |
The remainder of the page describes each direct JAR mode in detail.
upgrade <env> — move an existing environment forward
End-to-end upgrade of an existing environment to the JAR currently in place. Replace nomaubl.jar next to the wrapper, run ./nomaubl.sh upgrade <env>, and the wrapper takes care of every step — service lifecycle, schema, reference data, framework XSL, per-document XSL — and writes a complete report under ${appHome}/upgrade-reports/. Customer mappings and customer config are kept verbatim throughout.
./nomaubl.sh upgrade prod
What the wrapper does, step by step
| # | Step | What it does | What stays untouched |
|---|---|---|---|
| 1 | Stop & snapshot | Stops the service via SIGTERM (10 s grace), copies config/ + template/ + ubl/ + nomaubl.jar into snapshots/<timestamp>/. The last 5 snapshots are kept; older ones are pruned. | — |
| 2 | Database | Reads the current installed version from the upgrade-history table, applies the schema deltas of every release in between (idempotent — running the upgrade twice does nothing the second time). | Operational tables (F564231, lifecycle rows…) — only column / index / table additions and renames run. |
| 3 | Reference data | Merges new entries shipped with the JAR into the system templates (statuses, document-types, currency codes, action codes, etc.). | Every entry already on your side, including the rows you renamed or extended. |
| 4 | Framework XSL | Refreshes ubl-common.xsl, the Schematron rule packs and the XSD set with the version embedded in the JAR. These framework files are not customer-editable. | The framework/ folder is fully replaced — nothing customer-side here. |
| 5 | Per-document XSL | For each template/<name>/<name>.xsl, the wrapper writes a fresh file from the latest reference template, then re-injects every TAG_* value the customer had filled in and the NOMAUBL_OVERRIDES_START…NOMAUBL_OVERRIDES_END block at the bottom. New TAGs introduced by the upgrade come in with their reference default — fill them in afterwards if needed. TAGs removed from the reference are kept on the customer side, flagged with a <!-- removed in <version> --> comment so they don't go unnoticed. | Customer TAG values · customer overrides block · per-document RTF / image / sample-xml resources. |
| 6 | Report & restart | Writes ${appHome}/upgrade-reports/upgrade-<timestamp>.md with every step's outcome (added / kept / flagged TAGs per template, schema changes applied, reference-data deltas) and re-starts the service via the wrapper's start flow. | — |
If any step fails, the upgrade stops there. The snapshot remains on disk so a manual rollback is cp -r snapshots/<timestamp>/* env/ then ./nomaubl.sh start <env>. The next attempt picks up from the failed step — successful steps are not re-applied.
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.
Diagnostics
When something goes wrong, the report header carries the resolved env directory and the JDBC URL so a wrong-host or wrong-path mistake is visible at a glance. Connection failures unwrap the full cause chain — NoRouteToHost, Connection refused, authentication failures, etc., instead of a vague connection attempt failed. At startup, the path of the master key file used to decrypt sensitive config values is logged; if the license page reports restricted because the key file changed, the error message points directly at the master-key resolution.
backfill-vat <env> <fromDate> <toDate> — rebuild VAT details for past periods
Rebuilds the VAT detail table (F564234) for every invoice issued in [fromDate, toDate] from the UBL document already kept on each invoice's header. Two situations call for it:
- Right after turning Store VAT details on under Settings → Connectors → db-nomaubl → Tables. Only invoices inserted from then on get their detail rows in
F564234. The backfill brings the historical periods up to date so the VAT Declaration page can serve them. - Any time a clean rebuild is needed, for instance after a corruption was detected on the detail rows of a period.
./nomaubl.sh backfill-vat prod 2026-04-01 2026-04-30
| Argument | Description |
|---|---|
env | Environment name — same one used by start, stop, etc. The wrapper resolves the config from <env>/config/config.json. |
fromDate | Earliest invoice issue date to backfill, YYYY-MM-DD. Inclusive. |
toDate | Latest invoice issue date to backfill, YYYY-MM-DD. Inclusive. |
What the command does
For every invoice header in the window, the wrapper re-parses the UBL document that lives next to the header and re-inserts the per-rate VAT rows into F564234. The window is read against the invoice issue date so the dates passed match the period filter on the VAT Declaration page.
The command is safe to re-run on the same period without creating duplicates — the existing detail rows of an invoice are removed before the rebuild, so a fresh insert can never collide with stale data. Headers that have no UBL on file are reported in the summary and skipped.
Output
A summary is printed on stdout when the command finishes:
backfill-vat — issue date 2026-04-01 → 2026-04-30
invoices scanned 12 481
rebuilt (UBL present) 12 476
skipped (no UBL) 5
rows inserted into F564234 41 902
elapsed 18.4 s
Store VAT details does not need to be on while backfill-vat runs — the command writes to F564234 unconditionally. The switch only governs what happens on subsequent insertions of new invoices.
-help — usage banner
Emit the built-in help banner and exit. Accepted as -help, --help or -h. Invoking the JAR without any argument has the same effect.
java -jar nomaubl.jar -help
-install <targetDir> — environment setup
Provision a NomaUBL environment under targetDir plus the shared resources (fonts, images) one level up. Skips the configuration files (config.json, xdo.cfg, config-documents.json, config-lists.json) when they already exist, so re-running the install on an existing environment is safe — it only rebuilds the directory layout and refreshes the embedded XSL framework.
| Argument | Description |
|---|---|
targetDir | Path of the environment to create. The directory itself is the environment (e.g. /opt/nomaubl/demo); its parent receives the shared fonts/ and images/ directories. Created if missing. |
Layout produced
parent/ ← shared across environments
fonts/ ← fonts copied from the JAR
images/ ← left empty for project assets
targetDir/ ← one environment
burst/ config/ input/
process/ single/ subtmpl/
template/ ubl/ xslt/ .versions/
Configuration files installed inside targetDir/config/
| File | Source | Behaviour |
|---|---|---|
config.json | config/config-template.json (in JAR) | appHome resolved to the parent absolute path; envName resolved to targetDir's basename. All other paths keep their %APP_HOME% / %ENV% placeholders, resolved at runtime. |
xdo.cfg | config/xdo.cfg (in JAR) | %APP_HOME% and %ENV% substituted with absolute values — Oracle XDO does not resolve placeholders. |
config-documents.json | config/config-template-documents.json | Copied as-is. |
config-lists.json | config/config-template-lists.json | Copied as-is. |
Example
java -jar nomaubl.jar -install /opt/nomaubl/demo
# → creates /opt/nomaubl/demo (env) + /opt/nomaubl/{fonts,images} (shared)
-serve <configFile> [port] — embedded HTTP server
Start the embedded HTTP server (web UI + REST API) and the background scheduler. The process keeps running until killed; HttpServer threads are daemon, so Thread.currentThread().join() is used to keep the JVM alive.
| Argument | Description |
|---|---|
configFile | Absolute path to config.json. |
port | TCP port (default 8080). |
The scheduler reads the following keys from the global template of config.json to drive periodic jobs:
| Key | Effect |
|---|---|
fetchImportInterval | Minutes between -fetch-import sweeps. 0 disables the job. |
fetchStatusInterval | Minutes between -fetch-status sweeps. 0 disables the job. |
fetchAllInterval | Minutes between -fetch-all runs. 0 disables the job. |
fetchAllParams | JSON object holding the batch parameters — same shape as the body of POST /api/fetch-invoices/run-batch. Keys: template (its source property infers XML vs UBL processing), mode (AUTO | SINGLE | BURST | UBL), source (directory | bip), extractMode (input | output | both), replaceMode, validateOnly, sendToPA (Y | N), noSend, language. |
Example
java -jar nomaubl.jar -serve /opt/nomaubl/demo/config/config.json 8090
# → HTTP server on :8090 + scheduler driven by global properties
-process — single document-processing entry point
Process one (or many) source files against one document template — or call a SQL / REST connector when the template's source is Connector. The pipeline is selected by the template's source property (XML for XML spools requiring an XSL transform, UBL for already-formed UBL 2.1 invoices, Connector for live calls to a SQL query or REST endpoint).
-process <configFile> <template> <file|dir|---> [type] [--param key=value …] [--verbose] [--replace] [--no-send] [--no-db] [--validate] [--send] [--no-debug]
| Argument | Description |
|---|---|
configFile | Absolute path to config.json. |
template | Document template name (e.g. invoices, credit_notes). The template's source property drives the pipeline — see Documents. |
file | dir | --- | One source file or a directory of source files. For an XML template, the file is expected at <dirInput>/<file>.xml if no extension is given. For a UBL template, the path may be absolute or relative to <dirInput>/ubl/. When a directory is given, every matching file is processed in alphabetical order. For a Connector template, pass --- (three dashes) in place of the file path — the source is the connector, not a file. |
type | XML templates only — processing type (AUTO | SINGLE | BURST | UBL). Ignored on UBL and Connector templates. |
Processing types (XML source only)
| Value | Effect |
|---|---|
AUTO | Resolve the type per document from the Document Types configuration. Default for spools mixing several document types. |
SINGLE | One PDF per source file — single-document templates. |
BURST | Split the source on burstKey and process every sub-document in parallel (numProc). |
UBL | UBL-only — produces UBL 2.1, no PDF. |
Optional flags — order-independent, may follow the type:
| Flag | Effect | Applies to |
|---|---|---|
--param key=value | Pass a value to the connector's parameters. Repeatable — once per declared parameter. Same names as the form fields shown on Processing → Process Document when the template uses a connector. | Connector |
--verbose | Print per-file processing messages on stdout. | all |
--replace | Purge the five UBL tables for (doc, dct, kco) before re-insert. | all |
--no-send | Skip submission to the Plateforme Agréée. | all |
--no-db | Skip the database write step (implies --no-send). | XML |
--validate | XSD + Schematron only — no DB insert, no PA send. | UBL |
--send | Force submission to the PA, overriding the configured default. | UBL |
--no-debug | Skip the per-step timings (parse, validation, DB insert, send to PA) that are logged by default in every run. Recommended on heavy nightly batches where the per-step overhead is not worth the extra log volume. | all |
Examples
# XML template — JDE spool, AUTO routing
java -jar nomaubl.jar -process /opt/nomaubl/demo/config/config.json \
invoices INV-2026-001 AUTO --verbose --replace
# UBL template — validate every file in a directory, no DB / no PA
java -jar nomaubl.jar -process /opt/nomaubl/demo/config/config.json \
ubl-invoices /opt/nomaubl/demo/ubl/ --validate
# Connector template — pull header + lines from a SQL query, suppress debug timings
java -jar nomaubl.jar -process /opt/nomaubl/demo/config/config.json \
invoices-sql --- \
--param customer=00001234 --param docNumber=2026000125 \
--no-debug
-fetch-import and -fetch-status — synchronisation sweeps
Two read-only sweeps against the Plateforme Agréée — typically scheduled via fetchImportInterval / fetchStatusInterval rather than launched manually.
| Mode | Effect |
|---|---|
-fetch-import <configFile> | Re-poll the PA for invoices stuck in status 9906 — Pending PA import. Each invoice that has now been ingested by the PA gets its lifecycle advanced. |
-fetch-status <configFile> | Retrieve the lifecycle of every active invoice and persist new events (status badges, rejection reasons, expected actions) — same code path as the Sync → Retrieve Statuses page. |
java -jar nomaubl.jar -fetch-import /opt/nomaubl/demo/config/config.json
java -jar nomaubl.jar -fetch-status /opt/nomaubl/demo/config/config.json
-fetch-received — pull supplier invoices from the PA
Receive-side sweep: ask the PA for the list of invoices addressed to the operator since the last successful run, download each UBL the operator has not seen yet, and feed it into the existing UBL processing pipeline. Equivalent of the Sync → Fetch Input → PA inbound (supplier invoices) page.
-fetch-received <configFile> [--since YYYY-MM-DD] [--verbose]
| Argument / flag | Description |
|---|---|
configFile | Absolute path to config.json. |
--since YYYY-MM-DD | Earliest issue date to consider. Defaults to the timestamp of the last successful run persisted in the global template (lastFetchReceivedAt). |
--verbose | Print per-document messages on stdout — useful on a first run when the operator wants to see how many UBLs were downloaded and what dedup decisions were made. |
The handler walks two api-connector tasks on the configured PA template:
| Task | Purpose |
|---|---|
fetch-received-list | Returns the list of received invoice references (PA UUID + supplier metadata) since the cursor. |
fetch-received | Downloads one UBL by PA UUID. |
Deduplication is by PA UUID against the existing F564231 rows, so re-running the sweep is safe — already-imported invoices are skipped silently. The processing pipeline runs against the document template whose direction = R matches the inbound flow (the bundled received-ubl template by default).
To schedule it automatically, set fetchReceivedInterval in the global template (minutes between sweeps, 0 = disabled) — same -serve background scheduler that drives fetchImportInterval / fetchStatusInterval.
# Manual run — pick up everything since the last cursor
java -jar nomaubl.jar -fetch-received /opt/nomaubl/demo/config/config.json --verbose
# Manual run — backfill from a given date
java -jar nomaubl.jar -fetch-received /opt/nomaubl/demo/config/config.json \
--since 2026-04-01
-fetch-single — extract one document, then process it
Equivalent of the Application → Extract and Process page. Extracts a single document from a source channel, drops the resulting file into dirInput (XML template) or <dirInput>/ubl/ (UBL template), then immediately runs the matching pipeline. The XML-vs-UBL choice is inferred from the template's source property — no separate processType argument anymore.
-fetch-single <configFile> <template> <source> <sourceArgs…> [<type>] [flags…]
| Argument | Description |
|---|---|
configFile | Absolute path to config.json. |
template | Document template name. Its source property selects the pipeline (XML or UBL). |
source | Extraction channel — see table below. |
sourceArgs | Source-specific arguments. |
type | Processing type for XML templates (AUTO | SINGLE | BURST | UBL). Ignored on UBL templates. |
Source channels
| Source | Arguments | Description |
|---|---|---|
archive <doc> <dct> <kco> | Document number, document type, company code. | Pull the source from the JDE archive directory. |
ftp <report> <version> <language> <job> | Report code, version, language, JDE job number. | Download via FTP / SFTP. |
bip <jobNumber> | JDE BIP job number. | Read from the BIP Print Queue (F95630 / F95631). |
Optional flags
| Flag | Effect |
|---|---|
--verbose --replace --no-send | Same as -process. |
--validate --send | UBL templates only. |
--input (default) --output --both | BIP extraction mode — input XML, output documents, or both. |
Examples
# XML template — pull from the archive, AUTO routing
java -jar nomaubl.jar -fetch-single /opt/nomaubl/demo/config/config.json \
invoices archive 12345 RI 00070 AUTO --verbose
# UBL template — single BIP job, validate-only
java -jar nomaubl.jar -fetch-single /opt/nomaubl/demo/config/config.json \
ubl-invoices bip 19 --validate
-fetch-all — batch extract + process
Equivalent of the Application → Fetch Input page. Extract every matching document from a source, then process them all. The XML / UBL choice is again inferred from the template — no processType argument. Returns exit code 1 if at least one document failed.
-fetch-all <configFile> <template> <source> [<type>] [flags…]
| Argument | Description |
|---|---|
source | directory — scan dirInput (XML template) or dirInput/ubl (UBL template) for ready-to-process files. bip — pull every new BIP job whose number is greater than lastBipJobNumber (persisted in the global template after each successful run). |
For each bip job the wrapper resolves the per-job template from the BIP report filters when one is defined; otherwise it falls back to the template CLI argument. After a successful run, lastBipJobNumber in config.json is updated to the highest job number processed, so the next sweep only picks up new jobs.
Examples
# Process every XML waiting in the input directory
java -jar nomaubl.jar -fetch-all /opt/nomaubl/demo/config/config.json \
invoices directory AUTO --verbose
# Drain new BIP jobs against a UBL template (validate + send)
java -jar nomaubl.jar -fetch-all /opt/nomaubl/demo/config/config.json \
ubl-invoices bip --send
-extract — JDE BIP raw extraction
Low-level extraction from the JD Edwards BIP Print Queue (F9563110 header, F95630 input XML, F95631 output files). Same engine as fetch-single … bip, but without running the processing pipeline afterwards — useful to drop a job's payload into a directory for off-line inspection.
-extract <configFile> <jobNumber> [--input|--output|--both] [--type <outputType>] [--lang <language>] [outputDir]
| Argument | Description |
|---|---|
jobNumber | JDE job number (RJJOBNBR). |
--input (default) | Extract the input XML only. |
--output | Extract the generated output files only. |
--both | Extract input + output. |
--type <val> | Filter output files by type — XML, PDF, EXCEL, HTML, RTF, PPT, ETEXT. |
--lang <val> | Filter by language code (e.g. FR). |
outputDir | Optional output directory — defaults to global.dirInput. |
Example
java -jar nomaubl.jar -extract /opt/nomaubl/demo/config/config.json 19 \
--both --type PDF --lang FR /tmp/jde-19/
Flags reference
A consolidated view of every CLI flag — which modes accept it, what it does.
| Flag | Modes | Effect |
|---|---|---|
--verbose | xml, ubl, fetch-single, fetch-all | Print processing messages on stdout. |
--replace | xml, ubl, fetch-single, fetch-all | Overwrite the existing record (delete-then-insert for ubl; respects replaceDocument semantics for xml). |
--validate | ubl, fetch-single, fetch-all | Validate only — no DB insert, no PA send. Implies --no-send. |
--send | ubl, fetch-single, fetch-all | Force PA submission, overriding the configured default. |
--no-send | xml, ubl, fetch-single, fetch-all | Skip PA submission. |
--no-db | xml | Skip the database write step. Implies --no-send. |
--input (default) | extract, fetch-single (bip), fetch-all (bip) | BIP extraction — input XML only. |
--output | extract, fetch-single (bip), fetch-all (bip) | BIP extraction — output documents only. |
--both | extract, fetch-single (bip), fetch-all (bip) | BIP extraction — input + output. |
--type <t> | extract | Filter output files by type — XML, PDF, EXCEL, HTML, RTF, PPT, ETEXT. |
--lang <l> | extract | Filter by language code. |
Tips & best practices
- Schedule sweeps via the
-servebackground scheduler rather than cron. ConfiguringfetchImportIntervalandfetchStatusIntervalin the global template gives a single point of truth and survives an environment restart; running the same sweeps via cron risks overlapping with the in-process scheduler. fetch-allis idempotent ondirectorysource, append-only onbip. Adirectoryrerun re-picks files that are still indirInput— typically nothing once they have been processed and removed. Abiprerun only fetches jobs newer thanlastBipJobNumber, so a successful previous run is never repeated.- Use
--validatewhen promoting UBL files between environments. It exercises XSD + Schematron without writing to the DB or contacting the PA — a safe smoke test before flipping the real run. - Place
fetchAllParamsin the global template once, not on every cron entry. The scheduler builds its batch run from this single JSON object, mirroring the Configuration → System → Fetch Invoices page. - Reserve
-extractfor inspection or recovery.fetch-singleandfetch-allalready extract internally; the standalone-extractmode is for dropping a BIP job's payload onto disk for off-line review or replay. - Run
-installon a fresh directory and editconfig/config.jsonafterwards. The installer never overwrites an existingconfig.json, so a stale config from a previous attempt will silently win — start from an emptytargetDirto be sure.