Skip to main content

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.

👤 Operatorcron · CI · interactive🛠 nomaubl.shenvironment-based wrapperstart · stop · restartstatus · log+ short forms of every JAR mode☕ java -jar nomaubl.jardirect modes — full args-install · -serve-process-fetch-import · -fetch-status-fetch-single · -fetch-all-extractresolves configdirect
LayerWhen 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:

/opt/nomaubl/
📦 nomaubl.jar
🛠 nomaubl.sh
📂 fonts/  · shared
📂 images/  · shared
📂 demo/  · environment
📂 config/ → config.json, xdo.cfg, …
📂 input/, process/, ubl/, single/, …
📂 uat/  · environment
📂 prod/  · environment
SubcommandEffect
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 commandJAR 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
./nomaubl.sh upgrade prod — the steps in order1 · STOP & SNAPSHOTSIGTERM, wait 10 ssnapshot — last 5 kept2 · DATABASEapply schema deltasfrom current version3 · REFERENCE DATAmerge new entrieskeep customer overrides4 · FRAMEWORK XSLrefresh ubl-common + rulesSchematron, XSD5 · PER-DOCUMENT XSL — REWRITE WITH MERGEcustomer TAG_* values kept · NOMAUBL_OVERRIDES block keptnew TAGs added with defaults · removed TAGs kept and flagged6 · REPORT & RESTART${appHome}/upgrade-reports/upgrade-YYYYMMDD-HHmmss.mdre-start service · status visible on Upgrade Historystops here on first error — service stays down, snapshot still on disk

What the wrapper does, step by step

#StepWhat it doesWhat stays untouched
1Stop & snapshotStops 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.
2DatabaseReads 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.
3Reference dataMerges 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.
4Framework XSLRefreshes 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.
5Per-document XSLFor 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_STARTNOMAUBL_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.
6Report & restartWrites ${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
ArgumentDescription
envEnvironment name — same one used by start, stop, etc. The wrapper resolves the config from <env>/config/config.json.
fromDateEarliest invoice issue date to backfill, YYYY-MM-DD. Inclusive.
toDateLatest 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.

ArgumentDescription
targetDirPath 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/

FileSourceBehaviour
config.jsonconfig/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.cfgconfig/xdo.cfg (in JAR)%APP_HOME% and %ENV% substituted with absolute values — Oracle XDO does not resolve placeholders.
config-documents.jsonconfig/config-template-documents.jsonCopied as-is.
config-lists.jsonconfig/config-template-lists.jsonCopied 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.

ArgumentDescription
configFileAbsolute path to config.json.
portTCP port (default 8080).

The scheduler reads the following keys from the global template of config.json to drive periodic jobs:

KeyEffect
fetchImportIntervalMinutes between -fetch-import sweeps. 0 disables the job.
fetchStatusIntervalMinutes between -fetch-status sweeps. 0 disables the job.
fetchAllIntervalMinutes between -fetch-all runs. 0 disables the job.
fetchAllParamsJSON 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]
ArgumentDescription
configFileAbsolute path to config.json.
templateDocument 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.
typeXML templates only — processing type (AUTO | SINGLE | BURST | UBL). Ignored on UBL and Connector templates.

Processing types (XML source only)

ValueEffect
AUTOResolve the type per document from the Document Types configuration. Default for spools mixing several document types.
SINGLEOne PDF per source file — single-document templates.
BURSTSplit the source on burstKey and process every sub-document in parallel (numProc).
UBLUBL-only — produces UBL 2.1, no PDF.

Optional flags — order-independent, may follow the type:

FlagEffectApplies to
--param key=valuePass 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
--verbosePrint per-file processing messages on stdout.all
--replacePurge the five UBL tables for (doc, dct, kco) before re-insert.all
--no-sendSkip submission to the Plateforme Agréée.all
--no-dbSkip the database write step (implies --no-send).XML
--validateXSD + Schematron only — no DB insert, no PA send.UBL
--sendForce submission to the PA, overriding the configured default.UBL
--no-debugSkip 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.

ModeEffect
-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 / flagDescription
configFileAbsolute path to config.json.
--since YYYY-MM-DDEarliest issue date to consider. Defaults to the timestamp of the last successful run persisted in the global template (lastFetchReceivedAt).
--verbosePrint 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:

TaskPurpose
fetch-received-listReturns the list of received invoice references (PA UUID + supplier metadata) since the cursor.
fetch-receivedDownloads 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…]
ArgumentDescription
configFileAbsolute path to config.json.
templateDocument template name. Its source property selects the pipeline (XML or UBL).
sourceExtraction channel — see table below.
sourceArgsSource-specific arguments.
typeProcessing type for XML templates (AUTO | SINGLE | BURST | UBL). Ignored on UBL templates.

Source channels

SourceArgumentsDescription
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

FlagEffect
--verbose --replace --no-sendSame as -process.
--validate --sendUBL templates only.
--input (default) --output --bothBIP 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…]
ArgumentDescription
sourcedirectory — 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]
ArgumentDescription
jobNumberJDE job number (RJJOBNBR).
--input (default)Extract the input XML only.
--outputExtract the generated output files only.
--bothExtract 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).
outputDirOptional 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.

FlagModesEffect
--verbosexml, ubl, fetch-single, fetch-allPrint processing messages on stdout.
--replacexml, ubl, fetch-single, fetch-allOverwrite the existing record (delete-then-insert for ubl; respects replaceDocument semantics for xml).
--validateubl, fetch-single, fetch-allValidate only — no DB insert, no PA send. Implies --no-send.
--sendubl, fetch-single, fetch-allForce PA submission, overriding the configured default.
--no-sendxml, ubl, fetch-single, fetch-allSkip PA submission.
--no-dbxmlSkip the database write step. Implies --no-send.
--input (default)extract, fetch-single (bip), fetch-all (bip)BIP extraction — input XML only.
--outputextract, fetch-single (bip), fetch-all (bip)BIP extraction — output documents only.
--bothextract, fetch-single (bip), fetch-all (bip)BIP extraction — input + output.
--type <t>extractFilter output files by type — XML, PDF, EXCEL, HTML, RTF, PPT, ETEXT.
--lang <l>extractFilter by language code.

Tips & best practices

  • Schedule sweeps via the -serve background scheduler rather than cron. Configuring fetchImportInterval and fetchStatusInterval in 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-all is idempotent on directory source, append-only on bip. A directory rerun re-picks files that are still in dirInput — typically nothing once they have been processed and removed. A bip rerun only fetches jobs newer than lastBipJobNumber, so a successful previous run is never repeated.
  • Use --validate when 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 fetchAllParams in 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 -extract for inspection or recovery. fetch-single and fetch-all already extract internally; the standalone -extract mode is for dropping a BIP job's payload onto disk for off-line review or replay.
  • Run -install on a fresh directory and edit config/config.json afterwards. The installer never overwrites an existing config.json, so a stale config from a previous attempt will silently win — start from an empty targetDir to be sure.