<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://wiki.commander4j.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Dgarratt</id>
	<title>Commander4j - User contributions [en-gb]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.commander4j.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Dgarratt"/>
	<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Special:Contributions/Dgarratt"/>
	<updated>2026-04-30T18:14:13Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=File:SFTPTransfer.jpg&amp;diff=1830</id>
		<title>File:SFTPTransfer.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=File:SFTPTransfer.jpg&amp;diff=1830"/>
		<updated>2026-04-24T17:54:03Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=SFTPTransfer&amp;diff=1829</id>
		<title>SFTPTransfer</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=SFTPTransfer&amp;diff=1829"/>
		<updated>2026-04-24T17:53:51Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SFTPTransfer is a background file transfer service that moves files between a local filesystem and a remote SFTP server. It is a standalone Java application that runs either as a headless background service or as a desktop application with a minimal GUI, and supports both uploading (PUT) and downloading (GET) in independent threads.&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer replaces the earlier sftpSend and sftpGet tools with a unified, configurable service.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer automates recurring file transfers between Commander4j and external systems — for example, uploading despatch notifications to a customer portal or downloading order files from a supplier. It runs continuously, polling for new files at a configurable interval, and handles authentication, retry, backup, and archiving without operator involvement.&lt;br /&gt;
&lt;br /&gt;
[[File:SFTPTransfer.jpg|800px]]&lt;br /&gt;
&lt;br /&gt;
== Startup Modes ==&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer supports two startup modes selected at launch time:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Mode !! Behaviour&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Start desktop&#039;&#039;&#039; || Opens a small GUI window. Transfer threads start in a paused state; the operator must click Start in the interface to begin polling. Useful for testing configuration.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Start service&#039;&#039;&#039; || Headless — no GUI window. Transfer threads start immediately on launch. Suitable for production deployment as a background service or scheduled task.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On Windows, the native install package includes &amp;lt;code&amp;gt;sftpTransfer_Service.exe&amp;lt;/code&amp;gt;, which manages the Windows service directly — see [[#Installing as a Windows Service|Installing as a Windows Service]] below. On Linux/macOS, use systemd, launchd, or nohup.&lt;br /&gt;
&lt;br /&gt;
== Configuration Files ==&lt;br /&gt;
&lt;br /&gt;
All configuration is held in XML files under the &amp;lt;code&amp;gt;xml/config/&amp;lt;/code&amp;gt; directory. Changes require a service restart unless hot-reload is triggered (see below).&lt;br /&gt;
&lt;br /&gt;
=== sftp_common.xml ===&lt;br /&gt;
&lt;br /&gt;
Shared settings used by all transfer threads:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Poll interval || How often (in seconds) each thread checks for new files. Default: 10 seconds.&lt;br /&gt;
|-&lt;br /&gt;
| Backup retention || Number of days to keep backed-up files before automatic deletion.&lt;br /&gt;
|-&lt;br /&gt;
| Log level || Logging verbosity passed to Log4j.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sftp_put.xml ===&lt;br /&gt;
&lt;br /&gt;
Configures one or more PUT (upload) profiles. Each profile defines:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Enabled || Whether this profile&#039;s thread is active.&lt;br /&gt;
|-&lt;br /&gt;
| Local path || Local directory to watch for outbound files.&lt;br /&gt;
|-&lt;br /&gt;
| File mask || Wildcard pattern to match files (e.g. &amp;lt;code&amp;gt;*.xml&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;order_*.csv&amp;lt;/code&amp;gt;). Uses Apache Commons IO WildcardFileFilter.&lt;br /&gt;
|-&lt;br /&gt;
| Remote host || SFTP server hostname or IP address.&lt;br /&gt;
|-&lt;br /&gt;
| Remote port || SFTP port (default: 22).&lt;br /&gt;
|-&lt;br /&gt;
| Remote path || Target directory on the remote server.&lt;br /&gt;
|-&lt;br /&gt;
| Username || SFTP login username.&lt;br /&gt;
|-&lt;br /&gt;
| Password || AES-encrypted password (see [[#Password Encryption|Password Encryption]]).&lt;br /&gt;
|-&lt;br /&gt;
| Private key path || Path to SSH private key file (alternative to password authentication).&lt;br /&gt;
|-&lt;br /&gt;
| Backup path || Local directory where successfully uploaded files are moved.&lt;br /&gt;
|-&lt;br /&gt;
| Error path || Local directory where files that failed to upload are moved.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sftp_get.xml ===&lt;br /&gt;
&lt;br /&gt;
Configures one or more GET (download) profiles. Each profile defines:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Enabled || Whether this profile&#039;s thread is active.&lt;br /&gt;
|-&lt;br /&gt;
| Remote host || SFTP server hostname or IP address.&lt;br /&gt;
|-&lt;br /&gt;
| Remote port || SFTP port (default: 22).&lt;br /&gt;
|-&lt;br /&gt;
| Remote path || Directory on the remote server to poll for incoming files.&lt;br /&gt;
|-&lt;br /&gt;
| File mask || Wildcard pattern matched against the remote file listing (server-side ls).&lt;br /&gt;
|-&lt;br /&gt;
| Local path || Local directory where downloaded files are saved.&lt;br /&gt;
|-&lt;br /&gt;
| Username || SFTP login username.&lt;br /&gt;
|-&lt;br /&gt;
| Password || AES-encrypted password.&lt;br /&gt;
|-&lt;br /&gt;
| Private key path || Path to SSH private key file.&lt;br /&gt;
|-&lt;br /&gt;
| Delete after download || Whether to delete the remote file after successful download.&lt;br /&gt;
|-&lt;br /&gt;
| Backup path || Local directory where a copy of each downloaded file is kept.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== jsch_properties.xml ===&lt;br /&gt;
&lt;br /&gt;
Advanced SSH session parameters passed directly to the JSch library. Used to control host key checking, preferred algorithms, and connection timeouts. In most deployments this file can be left at its defaults.&lt;br /&gt;
&lt;br /&gt;
=== email_properties.xml ===&lt;br /&gt;
&lt;br /&gt;
SMTP settings for error notification emails. When a transfer failure occurs and email notification is enabled, SFTPTransfer sends an alert to the configured address. Fields include SMTP host, port, sender address, recipient address, and AES-encrypted SMTP password.&lt;br /&gt;
&lt;br /&gt;
== Installing as a Windows Service ==&lt;br /&gt;
&lt;br /&gt;
The native install package includes &amp;lt;code&amp;gt;sftpTransfer_Service.exe&amp;lt;/code&amp;gt;, a service-mode launcher built with install4j. This executable manages the Windows service directly — no additional wrapper is required.&lt;br /&gt;
&lt;br /&gt;
All service commands must be run from an elevated command prompt (Run as Administrator).&lt;br /&gt;
&lt;br /&gt;
The default Windows service name is &#039;&#039;&#039;sftpTransfer_Service&#039;&#039;&#039; (the launcher name defined in the installer). You can specify a different name as an optional second parameter — useful if you need to run multiple instances on the same machine. If a custom name is used at install time, that same name must be passed to every subsequent command.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Effect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /install&amp;lt;/code&amp;gt; || Register as &#039;&#039;&#039;sftpTransfer_Service&#039;&#039;&#039; with automatic startup on boot&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /install &amp;quot;My SFTP Service&amp;quot;&amp;lt;/code&amp;gt; || Register with a custom service name&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /install-demand&amp;lt;/code&amp;gt; || Register with manual startup only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /start&amp;lt;/code&amp;gt; || Start the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /stop&amp;lt;/code&amp;gt; || Stop the service (waits for graceful shutdown)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /restart&amp;lt;/code&amp;gt; || Restart the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /status&amp;lt;/code&amp;gt; || Query status (exit code: 0 = running, 3 = stopped)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /uninstall&amp;lt;/code&amp;gt; || Remove the service registration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If a custom service name was used at install time, append it to all subsequent commands:&lt;br /&gt;
&lt;br /&gt;
 sftpTransfer_Service.exe /start &amp;quot;My SFTP Service&amp;quot;&lt;br /&gt;
 sftpTransfer_Service.exe /stop &amp;quot;My SFTP Service&amp;quot;&lt;br /&gt;
 sftpTransfer_Service.exe /uninstall &amp;quot;My SFTP Service&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Once installed, the service also appears in the Windows Services management console (&amp;lt;code&amp;gt;services.msc&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Testing Before Installing as a Service ===&lt;br /&gt;
&lt;br /&gt;
The native install package also provides two alternatives for testing:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Launcher !! Mode !! Use case&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Console.exe&amp;lt;/code&amp;gt; || Console (headless) || Runs the service logic in a visible console window — useful for watching log output during initial configuration&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer.exe&amp;lt;/code&amp;gt; || Desktop GUI || Opens the GUI window in Start desktop mode — transfer threads start paused, allowing configuration to be verified before enabling transfers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Authentication ==&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer supports two authentication methods, configured per profile:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Method !! How to configure&lt;br /&gt;
|-&lt;br /&gt;
| Password || Set the &amp;lt;code&amp;gt;Password&amp;lt;/code&amp;gt; field in the profile to an AES-encrypted value. Leave the private key path empty.&lt;br /&gt;
|-&lt;br /&gt;
| SSH private key || Set the &amp;lt;code&amp;gt;Private key path&amp;lt;/code&amp;gt; field to the path of a PEM-format private key file. The password field is ignored.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Both methods use the JSch 2.x SSH library with Bouncy Castle as the cryptographic provider.&lt;br /&gt;
&lt;br /&gt;
=== Password Encryption ===&lt;br /&gt;
&lt;br /&gt;
Passwords stored in configuration files are AES-encrypted. Plain-text passwords are never stored on disk. To encrypt a password, use the password utility included with Commander4j (the same utility used for database passwords in Commander4j&#039;s own configuration).&lt;br /&gt;
&lt;br /&gt;
== File Transfer Behaviour ==&lt;br /&gt;
&lt;br /&gt;
=== PUT (Upload) ===&lt;br /&gt;
&lt;br /&gt;
# SFTPTransfer polls the local input directory every 10 seconds (configurable).&lt;br /&gt;
# Files matching the file mask are selected for upload.&lt;br /&gt;
# Each file is uploaded to the remote path using a temporary name with a &amp;lt;code&amp;gt;.tmp&amp;lt;/code&amp;gt; extension.&lt;br /&gt;
# On successful transfer, the remote file is renamed to its final name (atomic rename — the remote system never sees a partial file).&lt;br /&gt;
# The local source file is moved to the backup directory.&lt;br /&gt;
# If the transfer fails, the file is moved to the error directory and an error is logged.&lt;br /&gt;
&lt;br /&gt;
=== GET (Download) ===&lt;br /&gt;
&lt;br /&gt;
# SFTPTransfer lists the remote directory every 10 seconds (configurable).&lt;br /&gt;
# Files matching the file mask are selected for download.&lt;br /&gt;
# Each file is downloaded to the local path using a &amp;lt;code&amp;gt;.tmp&amp;lt;/code&amp;gt; extension.&lt;br /&gt;
# On successful download, the local file is renamed to its final name.&lt;br /&gt;
# If configured, the remote file is deleted after download.&lt;br /&gt;
# A backup copy is optionally saved to the local backup directory.&lt;br /&gt;
&lt;br /&gt;
== Thread Architecture ==&lt;br /&gt;
&lt;br /&gt;
When running, SFTPTransfer maintains the following threads:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Thread !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| TransferPUT || One thread per enabled PUT profile, each managing its own SFTP connection.&lt;br /&gt;
|-&lt;br /&gt;
| TransferGET || One thread per enabled GET profile, each managing its own SFTP connection.&lt;br /&gt;
|-&lt;br /&gt;
| EmailThread || Sends error notification emails asynchronously.&lt;br /&gt;
|-&lt;br /&gt;
| ArchiveThread || Periodically purges backup files older than the configured retention period.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Hot Configuration Reload ==&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer supports a configuration reload mode (&amp;lt;code&amp;gt;Mode_CONFIG_UPDATE&amp;lt;/code&amp;gt;). When this mode is triggered, running threads re-read their configuration files without requiring a full service restart. This allows profile changes — such as updating a remote path or rotating credentials — to be applied with minimal disruption.&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
All activity is written to the Log4j log file. The log records:&lt;br /&gt;
&lt;br /&gt;
* Service startup and configuration loaded&lt;br /&gt;
* Each thread starting and its profile settings&lt;br /&gt;
* Every file detected, transfer attempted, and outcome&lt;br /&gt;
* Every remote connection attempt and disconnect&lt;br /&gt;
* File move operations (to backup or error directories)&lt;br /&gt;
* Errors and exceptions with full context&lt;br /&gt;
&lt;br /&gt;
Log rotation and retention are configured in the Log4j configuration file included in the distribution.&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Library !! Version !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| JSch || 2.27.9 || SSH/SFTP client&lt;br /&gt;
|-&lt;br /&gt;
| Bouncy Castle || current || Cryptographic provider for JSch&lt;br /&gt;
|-&lt;br /&gt;
| Apache Commons IO || current || WildcardFileFilter for local file matching&lt;br /&gt;
|-&lt;br /&gt;
| Log4j || 2.25.3 || Logging&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
See also: [[LabelServer4j]], [[Middleware4j]], [[Production Lines &amp;amp; Labellers]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=ZPLRenderer&amp;diff=1828</id>
		<title>ZPLRenderer</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=ZPLRenderer&amp;diff=1828"/>
		<updated>2026-04-24T16:34:15Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ZPL Renderer is a desktop application that interprets ZPL (Zebra Programming Language) commands and renders them as a visual preview of what a label will look like when printed on a physical Zebra printer. It is a companion tool to Commander4j, LabelServer4j, and AutoLab4j.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
ZPL is a text-based command language used to define label layouts, text, graphics, and barcodes for Zebra label printers. The commands are sent directly to the printer as a stream of characters and are not human-readable. ZPL Renderer allows you to:&lt;br /&gt;
&lt;br /&gt;
* Load a ZPL file and see what the label will look like before sending it to a printer&lt;br /&gt;
* Listen on a network socket so that any application sending ZPL to that port renders the label on screen in real time&lt;br /&gt;
* Zoom in and out to examine label detail&lt;br /&gt;
* Preview multiple labels from a single ZPL stream&lt;br /&gt;
* Export the rendered label to PDF&lt;br /&gt;
* Print the rendered label directly from the application&lt;br /&gt;
&lt;br /&gt;
[[File:ZPLRenderer.jpg|800px]]&lt;br /&gt;
&lt;br /&gt;
== Running ZPL Renderer ==&lt;br /&gt;
&lt;br /&gt;
Native install packages for Windows, macOS, and Linux are available from the [[Downloads]] page and are the preferred installation method.&lt;br /&gt;
&lt;br /&gt;
Alternatively, ZPL Renderer can be run directly from the distribution archive. It is a Java 21 desktop (Swing) application:&lt;br /&gt;
&lt;br /&gt;
 java -jar zplrenderer.jar&lt;br /&gt;
&lt;br /&gt;
On first launch it reads its configuration from &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Loading a ZPL File ==&lt;br /&gt;
&lt;br /&gt;
Use the &#039;&#039;&#039;Open&#039;&#039;&#039; toolbar button to load a &amp;lt;code&amp;gt;.zpl&amp;lt;/code&amp;gt; text file from disk. The label is rendered immediately. Use &#039;&#039;&#039;Refresh&#039;&#039;&#039; to reload the file after editing it externally.&lt;br /&gt;
&lt;br /&gt;
Several example ZPL files are included in the &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! File !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| example1.zpl || Shipping label with QR code, text, and graphics&lt;br /&gt;
|-&lt;br /&gt;
| example2.zpl || Complex layout with boxes, barcodes, and logo&lt;br /&gt;
|-&lt;br /&gt;
| barcodes.zpl || Showcase of all supported barcode types&lt;br /&gt;
|-&lt;br /&gt;
| pallet_labels.zpl || Pallet label examples typical of Commander4j output&lt;br /&gt;
|-&lt;br /&gt;
| fonts.zpl || Font size and style demonstration&lt;br /&gt;
|-&lt;br /&gt;
| shipping.zpl || Shipping label sample&lt;br /&gt;
|-&lt;br /&gt;
| character.zpl || Character set reference&lt;br /&gt;
|-&lt;br /&gt;
| grid.zpl || Layout grid for alignment reference&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Network Socket Mode ==&lt;br /&gt;
&lt;br /&gt;
ZPL Renderer can listen on a TCP/IP port and render any ZPL label stream sent to it. This allows Commander4j, LabelServer4j, or any other application to use ZPL Renderer as a virtual printer — sending ZPL to the socket and seeing the result on screen instead of printing to paper.&lt;br /&gt;
&lt;br /&gt;
The default port is &#039;&#039;&#039;9100&#039;&#039;&#039; (the standard Zebra raw print port). The IP address and port are configured in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;. Enable listening using the &#039;&#039;&#039;Network&#039;&#039;&#039; button in the toolbar.&lt;br /&gt;
&lt;br /&gt;
ZPL Renderer extracts complete label blocks from the stream, identified by the standard &amp;lt;code&amp;gt;^XA&amp;lt;/code&amp;gt; (start of label) and &amp;lt;code&amp;gt;^XZ&amp;lt;/code&amp;gt; (end of label) delimiters.&lt;br /&gt;
&lt;br /&gt;
== Zoom ==&lt;br /&gt;
&lt;br /&gt;
Use the zoom controls in the toolbar to scale the rendered label between 0.10× and 2.00×. The default zoom is configured in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt; (default: 0.5×). This is useful for examining barcode detail or checking overall label proportions.&lt;br /&gt;
&lt;br /&gt;
== Multiple Labels ==&lt;br /&gt;
&lt;br /&gt;
When a ZPL file or network stream contains multiple labels, ZPL Renderer displays them as pages. Navigation controls allow stepping through each label. The maximum number of pages displayed is configurable (default: 3).&lt;br /&gt;
&lt;br /&gt;
== Export and Print ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PDF Export&#039;&#039;&#039; — saves the rendered label as a vector PDF using Apache PDFBox&lt;br /&gt;
* &#039;&#039;&#039;Print&#039;&#039;&#039; — sends the rendered label to a system printer&lt;br /&gt;
&lt;br /&gt;
== Supported ZPL Commands ==&lt;br /&gt;
&lt;br /&gt;
ZPL Renderer supports over 100 ZPL commands. Key categories:&lt;br /&gt;
&lt;br /&gt;
=== Label Setup ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^XA || Start of label&lt;br /&gt;
|-&lt;br /&gt;
| ^XZ || End of label&lt;br /&gt;
|-&lt;br /&gt;
| ^LL || Label length&lt;br /&gt;
|-&lt;br /&gt;
| ^LH || Label home (origin offset)&lt;br /&gt;
|-&lt;br /&gt;
| ^LT || Label top offset&lt;br /&gt;
|-&lt;br /&gt;
| ^PQ || Print quantity&lt;br /&gt;
|-&lt;br /&gt;
| ^CD || Change delimiter character&lt;br /&gt;
|-&lt;br /&gt;
| ^CC || Change caret character&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Text and Fields ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^FO || Field origin (X,Y position from top-left)&lt;br /&gt;
|-&lt;br /&gt;
| ^FT || Field typeset (X,Y position from bottom-left)&lt;br /&gt;
|-&lt;br /&gt;
| ^FD || Field data (the text content)&lt;br /&gt;
|-&lt;br /&gt;
| ^FS || Field separator&lt;br /&gt;
|-&lt;br /&gt;
| ^FR || Field reverse (inverted colours)&lt;br /&gt;
|-&lt;br /&gt;
| ^FW || Field orientation/rotation&lt;br /&gt;
|-&lt;br /&gt;
| ^FX || Comment (ignored in output)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Fonts ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^A0–^AZ || Select font by ID&lt;br /&gt;
|-&lt;br /&gt;
| ^CF || Change default alphanumeric font&lt;br /&gt;
|-&lt;br /&gt;
| ^CI || Change international character set/encoding&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Graphics ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^GB || Graphic box (rectangle)&lt;br /&gt;
|-&lt;br /&gt;
| ^GC || Graphic circle&lt;br /&gt;
|-&lt;br /&gt;
| ^GD || Graphic diagonal line&lt;br /&gt;
|-&lt;br /&gt;
| ^GE || Graphic ellipse&lt;br /&gt;
|-&lt;br /&gt;
| ^GF || Graphic field (embedded image data)&lt;br /&gt;
|-&lt;br /&gt;
| ^GS || Graphic symbol&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Barcodes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^BC || Code 128 / GS1-128 (EAN-128)&lt;br /&gt;
|-&lt;br /&gt;
| ^BE || EAN-13&lt;br /&gt;
|-&lt;br /&gt;
| ^B8 || EAN-8&lt;br /&gt;
|-&lt;br /&gt;
| ^B3 || Code 39&lt;br /&gt;
|-&lt;br /&gt;
| ^B2 || Interleaved 2 of 5&lt;br /&gt;
|-&lt;br /&gt;
| ^B1 || Code 11&lt;br /&gt;
|-&lt;br /&gt;
| ^BQ || QR Code&lt;br /&gt;
|-&lt;br /&gt;
| ^B7 || PDF417&lt;br /&gt;
|-&lt;br /&gt;
| ^B0 / ^BO || Aztec&lt;br /&gt;
|-&lt;br /&gt;
| ^BY || Bar code field defaults (width, ratio, height)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Barcode rendering uses the OkapiBarcode library. GS1 application identifiers are interpreted from &amp;lt;code&amp;gt;xml/config/gs1_app_defs.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== config.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Input folder || Default directory for ZPL file loading (default: &amp;lt;code&amp;gt;./examples&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| Port || Network socket port to listen on (default: 9100)&lt;br /&gt;
|-&lt;br /&gt;
| Default magnification || Starting zoom level (default: 0.5)&lt;br /&gt;
|-&lt;br /&gt;
| Max pages || Maximum number of label pages to display (default: 3)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fonts.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/config/fonts.xml&amp;lt;/code&amp;gt;, this file maps ZPL font IDs (0, A–Z) to TrueType font files and defines their pixel dimensions. This allows ZPL Renderer to simulate the fonts installed in a physical Zebra printer.&lt;br /&gt;
&lt;br /&gt;
Included fonts: Bitstream Vera, Anonymous Pro, ATTriumvirate.&lt;br /&gt;
&lt;br /&gt;
If your labels use fonts that differ from the defaults, edit &amp;lt;code&amp;gt;fonts.xml&amp;lt;/code&amp;gt; to match the font metrics of your target printer.&lt;br /&gt;
&lt;br /&gt;
== Relationship to Commander4j ==&lt;br /&gt;
&lt;br /&gt;
Commander4j generates ZPL label streams for pallet and case labels. ZPL Renderer allows you to preview these labels before deploying them to production printers, and to verify that label templates produce the correct output after making changes to the template syntax. See [[Label Template Syntax]] and [[Zebra ZPL Label]] for information on ZPL label authoring within Commander4j.&lt;br /&gt;
&lt;br /&gt;
See also: [[Zebra ZPL Label]], [[Label Template Syntax]], [[Printer Queues]], [[Production Lines &amp;amp; Labellers]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=File:ZPLRenderer.jpg&amp;diff=1827</id>
		<title>File:ZPLRenderer.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=File:ZPLRenderer.jpg&amp;diff=1827"/>
		<updated>2026-04-24T15:19:57Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=ZPLRenderer&amp;diff=1826</id>
		<title>ZPLRenderer</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=ZPLRenderer&amp;diff=1826"/>
		<updated>2026-04-24T15:18:39Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ZPL Renderer is a desktop application that interprets ZPL (Zebra Programming Language) commands and renders them as a visual preview of what a label will look like when printed on a physical Zebra printer. It is a companion tool to Commander4j, LabelServer4j, and AutoLab4j.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
ZPL is a text-based command language used to define label layouts, text, graphics, and barcodes for Zebra label printers. The commands are sent directly to the printer as a stream of characters and are not human-readable. ZPL Renderer allows you to:&lt;br /&gt;
&lt;br /&gt;
* Load a ZPL file and see what the label will look like before sending it to a printer&lt;br /&gt;
* Listen on a network socket so that any application sending ZPL to that port renders the label on screen in real time&lt;br /&gt;
* Zoom in and out to examine label detail&lt;br /&gt;
* Preview multiple labels from a single ZPL stream&lt;br /&gt;
* Export the rendered label to PDF&lt;br /&gt;
* Print the rendered label directly from the application&lt;br /&gt;
&lt;br /&gt;
[[File:ZPLRenderer.png|800px]]&lt;br /&gt;
&lt;br /&gt;
== Running ZPL Renderer ==&lt;br /&gt;
&lt;br /&gt;
Native install packages for Windows, macOS, and Linux are available from the [[Downloads]] page and are the preferred installation method.&lt;br /&gt;
&lt;br /&gt;
Alternatively, ZPL Renderer can be run directly from the distribution archive. It is a Java 21 desktop (Swing) application:&lt;br /&gt;
&lt;br /&gt;
 java -jar zplrenderer.jar&lt;br /&gt;
&lt;br /&gt;
On first launch it reads its configuration from &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Loading a ZPL File ==&lt;br /&gt;
&lt;br /&gt;
Use the &#039;&#039;&#039;Open&#039;&#039;&#039; toolbar button to load a &amp;lt;code&amp;gt;.zpl&amp;lt;/code&amp;gt; text file from disk. The label is rendered immediately. Use &#039;&#039;&#039;Refresh&#039;&#039;&#039; to reload the file after editing it externally.&lt;br /&gt;
&lt;br /&gt;
Several example ZPL files are included in the &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! File !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| example1.zpl || Shipping label with QR code, text, and graphics&lt;br /&gt;
|-&lt;br /&gt;
| example2.zpl || Complex layout with boxes, barcodes, and logo&lt;br /&gt;
|-&lt;br /&gt;
| barcodes.zpl || Showcase of all supported barcode types&lt;br /&gt;
|-&lt;br /&gt;
| pallet_labels.zpl || Pallet label examples typical of Commander4j output&lt;br /&gt;
|-&lt;br /&gt;
| fonts.zpl || Font size and style demonstration&lt;br /&gt;
|-&lt;br /&gt;
| shipping.zpl || Shipping label sample&lt;br /&gt;
|-&lt;br /&gt;
| character.zpl || Character set reference&lt;br /&gt;
|-&lt;br /&gt;
| grid.zpl || Layout grid for alignment reference&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Network Socket Mode ==&lt;br /&gt;
&lt;br /&gt;
ZPL Renderer can listen on a TCP/IP port and render any ZPL label stream sent to it. This allows Commander4j, LabelServer4j, or any other application to use ZPL Renderer as a virtual printer — sending ZPL to the socket and seeing the result on screen instead of printing to paper.&lt;br /&gt;
&lt;br /&gt;
The default port is &#039;&#039;&#039;9100&#039;&#039;&#039; (the standard Zebra raw print port). The IP address and port are configured in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;. Enable listening using the &#039;&#039;&#039;Network&#039;&#039;&#039; button in the toolbar.&lt;br /&gt;
&lt;br /&gt;
ZPL Renderer extracts complete label blocks from the stream, identified by the standard &amp;lt;code&amp;gt;^XA&amp;lt;/code&amp;gt; (start of label) and &amp;lt;code&amp;gt;^XZ&amp;lt;/code&amp;gt; (end of label) delimiters.&lt;br /&gt;
&lt;br /&gt;
== Zoom ==&lt;br /&gt;
&lt;br /&gt;
Use the zoom controls in the toolbar to scale the rendered label between 0.10× and 2.00×. The default zoom is configured in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt; (default: 0.5×). This is useful for examining barcode detail or checking overall label proportions.&lt;br /&gt;
&lt;br /&gt;
== Multiple Labels ==&lt;br /&gt;
&lt;br /&gt;
When a ZPL file or network stream contains multiple labels, ZPL Renderer displays them as pages. Navigation controls allow stepping through each label. The maximum number of pages displayed is configurable (default: 3).&lt;br /&gt;
&lt;br /&gt;
== Export and Print ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PDF Export&#039;&#039;&#039; — saves the rendered label as a vector PDF using Apache PDFBox&lt;br /&gt;
* &#039;&#039;&#039;Print&#039;&#039;&#039; — sends the rendered label to a system printer&lt;br /&gt;
&lt;br /&gt;
== Supported ZPL Commands ==&lt;br /&gt;
&lt;br /&gt;
ZPL Renderer supports over 100 ZPL commands. Key categories:&lt;br /&gt;
&lt;br /&gt;
=== Label Setup ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^XA || Start of label&lt;br /&gt;
|-&lt;br /&gt;
| ^XZ || End of label&lt;br /&gt;
|-&lt;br /&gt;
| ^LL || Label length&lt;br /&gt;
|-&lt;br /&gt;
| ^LH || Label home (origin offset)&lt;br /&gt;
|-&lt;br /&gt;
| ^LT || Label top offset&lt;br /&gt;
|-&lt;br /&gt;
| ^PQ || Print quantity&lt;br /&gt;
|-&lt;br /&gt;
| ^CD || Change delimiter character&lt;br /&gt;
|-&lt;br /&gt;
| ^CC || Change caret character&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Text and Fields ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^FO || Field origin (X,Y position from top-left)&lt;br /&gt;
|-&lt;br /&gt;
| ^FT || Field typeset (X,Y position from bottom-left)&lt;br /&gt;
|-&lt;br /&gt;
| ^FD || Field data (the text content)&lt;br /&gt;
|-&lt;br /&gt;
| ^FS || Field separator&lt;br /&gt;
|-&lt;br /&gt;
| ^FR || Field reverse (inverted colours)&lt;br /&gt;
|-&lt;br /&gt;
| ^FW || Field orientation/rotation&lt;br /&gt;
|-&lt;br /&gt;
| ^FX || Comment (ignored in output)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Fonts ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^A0–^AZ || Select font by ID&lt;br /&gt;
|-&lt;br /&gt;
| ^CF || Change default alphanumeric font&lt;br /&gt;
|-&lt;br /&gt;
| ^CI || Change international character set/encoding&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Graphics ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^GB || Graphic box (rectangle)&lt;br /&gt;
|-&lt;br /&gt;
| ^GC || Graphic circle&lt;br /&gt;
|-&lt;br /&gt;
| ^GD || Graphic diagonal line&lt;br /&gt;
|-&lt;br /&gt;
| ^GE || Graphic ellipse&lt;br /&gt;
|-&lt;br /&gt;
| ^GF || Graphic field (embedded image data)&lt;br /&gt;
|-&lt;br /&gt;
| ^GS || Graphic symbol&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Barcodes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^BC || Code 128 / GS1-128 (EAN-128)&lt;br /&gt;
|-&lt;br /&gt;
| ^BE || EAN-13&lt;br /&gt;
|-&lt;br /&gt;
| ^B8 || EAN-8&lt;br /&gt;
|-&lt;br /&gt;
| ^B3 || Code 39&lt;br /&gt;
|-&lt;br /&gt;
| ^B2 || Interleaved 2 of 5&lt;br /&gt;
|-&lt;br /&gt;
| ^B1 || Code 11&lt;br /&gt;
|-&lt;br /&gt;
| ^BQ || QR Code&lt;br /&gt;
|-&lt;br /&gt;
| ^B7 || PDF417&lt;br /&gt;
|-&lt;br /&gt;
| ^B0 / ^BO || Aztec&lt;br /&gt;
|-&lt;br /&gt;
| ^BY || Bar code field defaults (width, ratio, height)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Barcode rendering uses the OkapiBarcode library. GS1 application identifiers are interpreted from &amp;lt;code&amp;gt;xml/config/gs1_app_defs.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== config.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Input folder || Default directory for ZPL file loading (default: &amp;lt;code&amp;gt;./examples&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| Port || Network socket port to listen on (default: 9100)&lt;br /&gt;
|-&lt;br /&gt;
| Default magnification || Starting zoom level (default: 0.5)&lt;br /&gt;
|-&lt;br /&gt;
| Max pages || Maximum number of label pages to display (default: 3)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fonts.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/config/fonts.xml&amp;lt;/code&amp;gt;, this file maps ZPL font IDs (0, A–Z) to TrueType font files and defines their pixel dimensions. This allows ZPL Renderer to simulate the fonts installed in a physical Zebra printer.&lt;br /&gt;
&lt;br /&gt;
Included fonts: Bitstream Vera, Anonymous Pro, ATTriumvirate.&lt;br /&gt;
&lt;br /&gt;
If your labels use fonts that differ from the defaults, edit &amp;lt;code&amp;gt;fonts.xml&amp;lt;/code&amp;gt; to match the font metrics of your target printer.&lt;br /&gt;
&lt;br /&gt;
== Relationship to Commander4j ==&lt;br /&gt;
&lt;br /&gt;
Commander4j generates ZPL label streams for pallet and case labels. ZPL Renderer allows you to preview these labels before deploying them to production printers, and to verify that label templates produce the correct output after making changes to the template syntax. See [[Label Template Syntax]] and [[Zebra ZPL Label]] for information on ZPL label authoring within Commander4j.&lt;br /&gt;
&lt;br /&gt;
See also: [[Zebra ZPL Label]], [[Label Template Syntax]], [[Printer Queues]], [[Production Lines &amp;amp; Labellers]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=File:JLaunchPad.png&amp;diff=1825</id>
		<title>File:JLaunchPad.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=File:JLaunchPad.png&amp;diff=1825"/>
		<updated>2026-04-09T07:58:14Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=LaunchPad&amp;diff=1824</id>
		<title>LaunchPad</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=LaunchPad&amp;diff=1824"/>
		<updated>2026-04-09T07:56:11Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;LaunchPad is a macOS application organiser and launcher. It provides a tabbed grid interface for grouping macOS applications (.app bundles) into named categories and launching them with a double-click. It is a companion tool to the Commander4j suite, used to organise the suite&#039;s tools and supporting applications in a single place.&lt;br /&gt;
&lt;br /&gt;
[[File:JLaunchPad.png|thumb|right|500px|JLaunchPad showing the Desktop tab]]&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
LaunchPad replaces cluttered Dock folders and aliases with a structured, tabbed grid. Each tab is a named category and each cell in the grid holds one application. Applications are added by browsing or dragging from Finder.&lt;br /&gt;
&lt;br /&gt;
== Running LaunchPad ==&lt;br /&gt;
&lt;br /&gt;
The easiest way to run LaunchPad is to double-click the &amp;lt;code&amp;gt;JLaunchPad.app&amp;lt;/code&amp;gt; bundle. This is available from the [[Downloads]] page and launches the application exactly as you would any other macOS application.&lt;br /&gt;
&lt;br /&gt;
Alternatively, LaunchPad can be run from the command line using:&lt;br /&gt;
&lt;br /&gt;
 java -jar JLaunchPad.jar&lt;br /&gt;
&lt;br /&gt;
The window opens at 1300 × 900 pixels. Tabs are listed on the left edge; the grid fills the rest of the window.&lt;br /&gt;
&lt;br /&gt;
== Adding Applications ==&lt;br /&gt;
&lt;br /&gt;
=== Single Application ===&lt;br /&gt;
&lt;br /&gt;
Click the &#039;&#039;&#039;Add App&#039;&#039;&#039; toolbar button. A file chooser opens, defaulting to &amp;lt;code&amp;gt;/Applications&amp;lt;/code&amp;gt; and your home directory. Select any &amp;lt;code&amp;gt;.app&amp;lt;/code&amp;gt; bundle. If you select &amp;lt;code&amp;gt;/Applications&amp;lt;/code&amp;gt;, LaunchPad also scans &amp;lt;code&amp;gt;/System/Applications&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;/System/Applications/Utilities&amp;lt;/code&amp;gt; automatically.&lt;br /&gt;
&lt;br /&gt;
=== Importing a Folder ===&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Import Folder&#039;&#039;&#039; to scan a directory recursively for application bundles. LaunchPad filters out uninstall helpers, login item helpers, and background-only bundles, adding only user-facing applications.&lt;br /&gt;
&lt;br /&gt;
=== Drag and Drop ===&lt;br /&gt;
&lt;br /&gt;
Drag a &amp;lt;code&amp;gt;.app&amp;lt;/code&amp;gt; bundle from Finder directly onto the grid or onto a tab. An application can only appear once across all tabs — dragging a duplicate has no effect.&lt;br /&gt;
&lt;br /&gt;
== Grid Layout ==&lt;br /&gt;
&lt;br /&gt;
Each tab contains a 7-column grid of 150 × 150 pixel cells. Each cell displays the application icon (120 × 120 pixels) and the application&#039;s display name. Click &#039;&#039;&#039;Pack Icons&#039;&#039;&#039; to remove empty cells from the current tab, compacting the grid.&lt;br /&gt;
&lt;br /&gt;
Applications can be reordered within the grid by dragging from one cell to another. The same drag operation works between tabs.&lt;br /&gt;
&lt;br /&gt;
== Tab Management ==&lt;br /&gt;
&lt;br /&gt;
The toolbar provides buttons for:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Add Tab&#039;&#039;&#039; — create a new named category&lt;br /&gt;
* &#039;&#039;&#039;Edit Tab&#039;&#039;&#039; — rename the selected tab&lt;br /&gt;
* &#039;&#039;&#039;Delete Tab&#039;&#039;&#039; — remove the selected tab (with confirmation)&lt;br /&gt;
* &#039;&#039;&#039;Move Up / Move Down&#039;&#039;&#039; — reorder tabs&lt;br /&gt;
&lt;br /&gt;
== Launching Applications ==&lt;br /&gt;
&lt;br /&gt;
Double-click any application icon to launch it. LaunchPad uses the macOS &amp;lt;code&amp;gt;open&amp;lt;/code&amp;gt; command to launch the bundle, so the application opens exactly as if you had double-clicked it in Finder.&lt;br /&gt;
&lt;br /&gt;
== Cell Context Menu ==&lt;br /&gt;
&lt;br /&gt;
Right-click any cell or application to access:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Assign Custom Icon...&#039;&#039;&#039; — replace the icon with any PNG, JPG, GIF, or ICNS image&lt;br /&gt;
* &#039;&#039;&#039;Remove App&#039;&#039;&#039; — clear the cell&lt;br /&gt;
* &#039;&#039;&#039;Reveal in Finder&#039;&#039;&#039; — open the application&#039;s location in Finder&lt;br /&gt;
&lt;br /&gt;
== Icon Resolution ==&lt;br /&gt;
&lt;br /&gt;
When an application is added, LaunchPad attempts to extract its icon automatically. It tries the following in order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;code&amp;gt;.icns&amp;lt;/code&amp;gt; file named in the app&#039;s &amp;lt;code&amp;gt;Info.plist&amp;lt;/code&amp;gt;&lt;br /&gt;
# PNG icons listed in &amp;lt;code&amp;gt;Info.plist&amp;lt;/code&amp;gt; under &amp;lt;code&amp;gt;CFBundleIcons&amp;lt;/code&amp;gt;&lt;br /&gt;
# The app&#039;s &amp;lt;code&amp;gt;Assets.car&amp;lt;/code&amp;gt; (rendered via QuickLook)&lt;br /&gt;
# A generic system icon as a last resort&lt;br /&gt;
&lt;br /&gt;
Extracted icons are scaled to 120 × 120 pixels and cached to &amp;lt;code&amp;gt;images/appIcons/&amp;lt;/code&amp;gt; on disk. On subsequent launches the cached PNG is used unless the app itself has been updated.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
LaunchPad saves its state automatically on exit and restores it on the next launch.&lt;br /&gt;
&lt;br /&gt;
=== launchpad.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/config/launchpad.xml&amp;lt;/code&amp;gt;. This file records all tabs, their names, and the path of each application in the grid. It is written automatically — you do not need to edit it manually.&lt;br /&gt;
&lt;br /&gt;
=== images/appIcons/ ===&lt;br /&gt;
&lt;br /&gt;
The icon cache directory. Each application has a &amp;lt;code&amp;gt;&amp;amp;lt;BundleName&amp;amp;gt;.png&amp;lt;/code&amp;gt; file here. If you use &#039;&#039;&#039;Assign Custom Icon...&#039;&#039;&#039;, the cache file for that application is overwritten with your chosen image.&lt;br /&gt;
&lt;br /&gt;
See also: [[Menu4j]], [[ZPLRenderer]], [[Downloads]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=LabelServer4j_Example_User_Interface&amp;diff=1823</id>
		<title>LabelServer4j Example User Interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=LabelServer4j_Example_User_Interface&amp;diff=1823"/>
		<updated>2026-04-05T16:05:04Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;LabelServer4j is a headless background service — it has no graphical user interface. All interaction with the service is through configuration files, log files, and (on Windows) the Windows Services control panel.&lt;br /&gt;
&lt;br /&gt;
== Starting LabelServer4j ==&lt;br /&gt;
&lt;br /&gt;
=== Windows — Running as a Service ===&lt;br /&gt;
&lt;br /&gt;
The native install package includes &amp;lt;code&amp;gt;LabelServer.exe&amp;lt;/code&amp;gt;, a service-mode launcher that manages the Windows service directly. All commands must be run from an elevated command prompt (Run as Administrator).&lt;br /&gt;
&lt;br /&gt;
The default service name is &#039;&#039;&#039;LabelService&#039;&#039;&#039;. A custom name can be passed as an optional second parameter — if used, the same name must be supplied to all subsequent commands.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Effect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /install&amp;lt;/code&amp;gt; || Register as &#039;&#039;&#039;LabelService&#039;&#039;&#039; with automatic startup on boot&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /install &amp;quot;My Label Service&amp;quot;&amp;lt;/code&amp;gt; || Register with a custom service name&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /install-demand&amp;lt;/code&amp;gt; || Register with manual startup only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /start&amp;lt;/code&amp;gt; || Start the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /stop&amp;lt;/code&amp;gt; || Stop the service (waits for graceful shutdown)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /restart&amp;lt;/code&amp;gt; || Restart the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /status&amp;lt;/code&amp;gt; || Query status (exit code: 0 = running, 3 = stopped)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /uninstall&amp;lt;/code&amp;gt; || Remove the service registration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Once installed, the service also appears in the Windows Services management console (&amp;lt;code&amp;gt;services.msc&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Windows — Testing in a Console Window ===&lt;br /&gt;
&lt;br /&gt;
Before installing as a service, use the debug launcher to run LabelServer4j with all output visible in the console:&lt;br /&gt;
&lt;br /&gt;
 LabelServerDebug.exe&lt;br /&gt;
&lt;br /&gt;
This runs the same application code and is the most convenient way to verify that labellers connect and that the configuration is correct before committing to service deployment.&lt;br /&gt;
&lt;br /&gt;
=== Linux / macOS ===&lt;br /&gt;
&lt;br /&gt;
Start from the terminal using the provided shell script:&lt;br /&gt;
&lt;br /&gt;
 ./start_labeller.sh&lt;br /&gt;
&lt;br /&gt;
Or directly:&lt;br /&gt;
&lt;br /&gt;
 java -cp ./LabelServer.jar:./lib/devonly/i4jruntime.jar com.commander4j.labeller.Service&lt;br /&gt;
&lt;br /&gt;
The process runs in the foreground. Use a process manager (systemd, launchd, or nohup) for production deployment.&lt;br /&gt;
&lt;br /&gt;
== Monitoring ==&lt;br /&gt;
&lt;br /&gt;
Since there is no GUI, the primary monitoring tool is the log file:&lt;br /&gt;
&lt;br /&gt;
 logs/c4jLabelServer.log&lt;br /&gt;
&lt;br /&gt;
The log records every event in detail:&lt;br /&gt;
&lt;br /&gt;
* Service startup and configuration loading&lt;br /&gt;
* Each labeller thread starting&lt;br /&gt;
* Every CSV file detected and processed&lt;br /&gt;
* Every command sent to a printer and every response received&lt;br /&gt;
* File operations (upload, download, backup, delete)&lt;br /&gt;
* Errors and exceptions with full context&lt;br /&gt;
&lt;br /&gt;
Log files rotate at 10 MB and are retained for 14 days.&lt;br /&gt;
&lt;br /&gt;
=== What to Look For ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Situation !! What to check in the log&lt;br /&gt;
|-&lt;br /&gt;
| Label not printing || Look for the CSV filename being detected; if absent, check the input path in labellers.xml&lt;br /&gt;
|-&lt;br /&gt;
| Printer not responding || Look for TCP connection errors or timeout messages for that labeller&#039;s IP and port&lt;br /&gt;
|-&lt;br /&gt;
| Wrong data on label || Check the variable substitution log lines to see what values were sent&lt;br /&gt;
|-&lt;br /&gt;
| Script error || Look for the script line number and command that caused the failure&lt;br /&gt;
|-&lt;br /&gt;
| File stuck in input directory || File renamed to &amp;lt;code&amp;gt;.in&amp;lt;/code&amp;gt; means the script is running or failed — check for a &amp;lt;code&amp;gt;.error&amp;lt;/code&amp;gt; file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Configuration Changes ==&lt;br /&gt;
&lt;br /&gt;
To change a labeller&#039;s IP address, port, command script, or input path, edit the relevant &amp;lt;code&amp;gt;labellers.xml&amp;lt;/code&amp;gt; file and restart the service. Changes to configuration files are not picked up at runtime.&lt;br /&gt;
&lt;br /&gt;
To switch site, edit &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt; and change the &amp;lt;code&amp;gt;site id&amp;lt;/code&amp;gt; attribute, then restart.&lt;br /&gt;
&lt;br /&gt;
== Thread Architecture ==&lt;br /&gt;
&lt;br /&gt;
When running, LabelServer4j maintains the following threads:&lt;br /&gt;
&lt;br /&gt;
* One main service thread (lifecycle management)&lt;br /&gt;
* One server thread (configuration and orchestration)&lt;br /&gt;
* Per enabled labeller: one labeller thread, one TCP receive thread, one TCP transmit thread&lt;br /&gt;
&lt;br /&gt;
The thread count grows with the number of configured printers. A site with six printers typically runs around 20 threads in total.&lt;br /&gt;
&lt;br /&gt;
== Graceful Shutdown ==&lt;br /&gt;
&lt;br /&gt;
Sending a termination signal (Ctrl+C on Linux/macOS, or stopping the Windows service) triggers the shutdown hook. LabelServer4j signals all labeller threads to stop, waits for any in-progress print jobs to complete, then exits cleanly.&lt;br /&gt;
&lt;br /&gt;
See also: [[Overview LabelServer4j]], [[LabelServer4j Configuration]], [[LabelServer4j Operation]], [[Install Interface Services]]&lt;br /&gt;
&lt;br /&gt;
[[Category:LabelServer4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Interface_Service&amp;diff=1822</id>
		<title>Interface Service</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Interface_Service&amp;diff=1822"/>
		<updated>2026-04-05T16:05:03Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Commander4j Interface Service is a background process that handles all automated integration between Commander4j and external systems. It monitors for incoming XML messages from ERPs and other systems, generates outbound XML messages, triggers scheduled reports, and drives automatic labelling. It is designed to run continuously on a server as a Windows service.&lt;br /&gt;
&lt;br /&gt;
The service is a separate optional component — the main Commander4j desktop application does not need to be running for the Interface Service to operate.&lt;br /&gt;
&lt;br /&gt;
== What the Service Does ==&lt;br /&gt;
&lt;br /&gt;
When started, the Interface Service logs into the Commander4j database using the built-in &amp;lt;code&amp;gt;interface&amp;lt;/code&amp;gt; account and starts five background threads:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Thread !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Inbound Message Thread&#039;&#039;&#039; || Monitors the configured inbound directory for XML message files from external systems. Processes each file against the appropriate message handler and writes results to &amp;lt;code&amp;gt;SYS_INTERFACE_LOG&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Outbound Message Thread&#039;&#039;&#039; || Picks up XML messages queued in the database for transmission to external systems and writes them to the configured outbound directories.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Recovery Thread&#039;&#039;&#039; || Monitors the recovery path for messages that failed processing and re-attempts them on a schedule.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Reporting Thread&#039;&#039;&#039; || Fires scheduled reports at their configured times and distributes the output.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Auto Labeller Thread&#039;&#039;&#039; || Drives automatic pallet labelling triggers that are not handled by [[AutoLab4j]] or [[LabelServer4j]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
At a configured daily housekeeping time the service gracefully stops all threads, performs maintenance tasks, and restarts. Email notifications are sent on startup, shutdown, and housekeeping if configured.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
=== Host Configuration ===&lt;br /&gt;
&lt;br /&gt;
The Interface Service identifies which database to connect to by looking for a host entry in &amp;lt;code&amp;gt;hosts.xml&amp;lt;/code&amp;gt; with a &amp;lt;code&amp;gt;uniqueId&amp;lt;/code&amp;gt; of &amp;lt;code&amp;gt;service&amp;lt;/code&amp;gt;. This host entry must be created using [[Setup4j]] before the service will start. Without it, the service logs an error and exits immediately.&lt;br /&gt;
&lt;br /&gt;
=== Interface User Account ===&lt;br /&gt;
&lt;br /&gt;
The service logs into Commander4j using the application account &amp;lt;code&amp;gt;interface&amp;lt;/code&amp;gt; with password &amp;lt;code&amp;gt;interface&amp;lt;/code&amp;gt;. This account must exist and be enabled in the Commander4j user list. It is created automatically when the schema is initialised, but verify it has not been disabled or had its password changed.&lt;br /&gt;
&lt;br /&gt;
== Installing as a Windows Service ==&lt;br /&gt;
&lt;br /&gt;
The native install package includes &amp;lt;code&amp;gt;Service4j.exe&amp;lt;/code&amp;gt;, a service-mode launcher built with install4j. This executable manages the Windows service directly — no additional wrapper is required.&lt;br /&gt;
&lt;br /&gt;
All service commands must be run from an elevated command prompt (Run as Administrator).&lt;br /&gt;
&lt;br /&gt;
The default Windows service name is &#039;&#039;&#039;Service4j&#039;&#039;&#039; (the launcher name defined in the installer). You can specify a different name as an optional second parameter. If a custom name is used at install time, that same name must be passed to every subsequent command.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Effect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Service4j.exe /install&amp;lt;/code&amp;gt; || Register as &#039;&#039;&#039;Service4j&#039;&#039;&#039; with automatic startup on boot&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Service4j.exe /install &amp;quot;Commander4j Interface&amp;quot;&amp;lt;/code&amp;gt; || Register with a custom service name&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Service4j.exe /install-demand&amp;lt;/code&amp;gt; || Register with manual startup only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Service4j.exe /start&amp;lt;/code&amp;gt; || Start the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Service4j.exe /stop&amp;lt;/code&amp;gt; || Stop the service (waits for graceful shutdown)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Service4j.exe /restart&amp;lt;/code&amp;gt; || Restart the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Service4j.exe /status&amp;lt;/code&amp;gt; || Query status (exit code: 0 = running, 3 = stopped)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Service4j.exe /uninstall&amp;lt;/code&amp;gt; || Remove the service registration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If a custom service name was used at install time, append it to all subsequent commands:&lt;br /&gt;
&lt;br /&gt;
 Service4j.exe /start &amp;quot;Commander4j Interface&amp;quot;&lt;br /&gt;
 Service4j.exe /stop &amp;quot;Commander4j Interface&amp;quot;&lt;br /&gt;
 Service4j.exe /uninstall &amp;quot;Commander4j Interface&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Once installed, the service also appears in the Windows Services management console (&amp;lt;code&amp;gt;services.msc&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Testing Before Installing as a Service ===&lt;br /&gt;
&lt;br /&gt;
Before committing to service installation, run the Interface Service in a visible console window using:&lt;br /&gt;
&lt;br /&gt;
 Interface4j.exe&lt;br /&gt;
&lt;br /&gt;
This runs the same application code and all log output is written to the console window. Use this mode to confirm that the correct host is found, the &amp;lt;code&amp;gt;interface&amp;lt;/code&amp;gt; account logs in, and all threads start successfully.&lt;br /&gt;
&lt;br /&gt;
== Email Notifications ==&lt;br /&gt;
&lt;br /&gt;
If configured, the service sends email alerts at key lifecycle events:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !! Trigger&lt;br /&gt;
|-&lt;br /&gt;
| Startup || Service has connected to the database and all threads are running&lt;br /&gt;
|-&lt;br /&gt;
| Shutdown || Service has stopped all threads and disconnected&lt;br /&gt;
|-&lt;br /&gt;
| Housekeeping || Daily maintenance cycle has run&lt;br /&gt;
|-&lt;br /&gt;
| Statistics || Daily statistics summary (if enabled)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Email notification is controlled by the system key &amp;lt;code&amp;gt;INTERFACE EMAIL NOTIFY&amp;lt;/code&amp;gt; (true/false) and the recipient list in &amp;lt;code&amp;gt;INTERFACE ADMIN EMAIL&amp;lt;/code&amp;gt;. Both are configured in the Commander4j system keys administration screen.&lt;br /&gt;
&lt;br /&gt;
== Monitoring ==&lt;br /&gt;
&lt;br /&gt;
All activity is written to the Log4j log file in the &amp;lt;code&amp;gt;logs/&amp;lt;/code&amp;gt; directory. The [[Interface Log]] screen in the Commander4j desktop application provides a searchable view of every message processed — inbound and outbound — including status, error details, and message content.&lt;br /&gt;
&lt;br /&gt;
Failed messages can be resubmitted for reprocessing from the Interface Log screen without re-sending the original file.&lt;br /&gt;
&lt;br /&gt;
See also: [[Interface Log]], [[Interface Message Formats]], [[Setup4j]], [[AutoLab4j]], [[LabelServer4j]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=SFTPTransfer&amp;diff=1821</id>
		<title>SFTPTransfer</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=SFTPTransfer&amp;diff=1821"/>
		<updated>2026-04-05T16:05:02Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SFTPTransfer is a background file transfer service that moves files between a local filesystem and a remote SFTP server. It is a standalone Java application that runs either as a headless background service or as a desktop application with a minimal GUI, and supports both uploading (PUT) and downloading (GET) in independent threads.&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer replaces the earlier sftpSend and sftpGet tools with a unified, configurable service.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer automates recurring file transfers between Commander4j and external systems — for example, uploading despatch notifications to a customer portal or downloading order files from a supplier. It runs continuously, polling for new files at a configurable interval, and handles authentication, retry, backup, and archiving without operator involvement.&lt;br /&gt;
&lt;br /&gt;
== Startup Modes ==&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer supports two startup modes selected at launch time:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Mode !! Behaviour&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Start desktop&#039;&#039;&#039; || Opens a small GUI window. Transfer threads start in a paused state; the operator must click Start in the interface to begin polling. Useful for testing configuration.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Start service&#039;&#039;&#039; || Headless — no GUI window. Transfer threads start immediately on launch. Suitable for production deployment as a background service or scheduled task.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On Windows, the native install package includes &amp;lt;code&amp;gt;sftpTransfer_Service.exe&amp;lt;/code&amp;gt;, which manages the Windows service directly — see [[#Installing as a Windows Service|Installing as a Windows Service]] below. On Linux/macOS, use systemd, launchd, or nohup.&lt;br /&gt;
&lt;br /&gt;
== Configuration Files ==&lt;br /&gt;
&lt;br /&gt;
All configuration is held in XML files under the &amp;lt;code&amp;gt;xml/config/&amp;lt;/code&amp;gt; directory. Changes require a service restart unless hot-reload is triggered (see below).&lt;br /&gt;
&lt;br /&gt;
=== sftp_common.xml ===&lt;br /&gt;
&lt;br /&gt;
Shared settings used by all transfer threads:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Poll interval || How often (in seconds) each thread checks for new files. Default: 10 seconds.&lt;br /&gt;
|-&lt;br /&gt;
| Backup retention || Number of days to keep backed-up files before automatic deletion.&lt;br /&gt;
|-&lt;br /&gt;
| Log level || Logging verbosity passed to Log4j.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sftp_put.xml ===&lt;br /&gt;
&lt;br /&gt;
Configures one or more PUT (upload) profiles. Each profile defines:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Enabled || Whether this profile&#039;s thread is active.&lt;br /&gt;
|-&lt;br /&gt;
| Local path || Local directory to watch for outbound files.&lt;br /&gt;
|-&lt;br /&gt;
| File mask || Wildcard pattern to match files (e.g. &amp;lt;code&amp;gt;*.xml&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;order_*.csv&amp;lt;/code&amp;gt;). Uses Apache Commons IO WildcardFileFilter.&lt;br /&gt;
|-&lt;br /&gt;
| Remote host || SFTP server hostname or IP address.&lt;br /&gt;
|-&lt;br /&gt;
| Remote port || SFTP port (default: 22).&lt;br /&gt;
|-&lt;br /&gt;
| Remote path || Target directory on the remote server.&lt;br /&gt;
|-&lt;br /&gt;
| Username || SFTP login username.&lt;br /&gt;
|-&lt;br /&gt;
| Password || AES-encrypted password (see [[#Password Encryption|Password Encryption]]).&lt;br /&gt;
|-&lt;br /&gt;
| Private key path || Path to SSH private key file (alternative to password authentication).&lt;br /&gt;
|-&lt;br /&gt;
| Backup path || Local directory where successfully uploaded files are moved.&lt;br /&gt;
|-&lt;br /&gt;
| Error path || Local directory where files that failed to upload are moved.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sftp_get.xml ===&lt;br /&gt;
&lt;br /&gt;
Configures one or more GET (download) profiles. Each profile defines:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Enabled || Whether this profile&#039;s thread is active.&lt;br /&gt;
|-&lt;br /&gt;
| Remote host || SFTP server hostname or IP address.&lt;br /&gt;
|-&lt;br /&gt;
| Remote port || SFTP port (default: 22).&lt;br /&gt;
|-&lt;br /&gt;
| Remote path || Directory on the remote server to poll for incoming files.&lt;br /&gt;
|-&lt;br /&gt;
| File mask || Wildcard pattern matched against the remote file listing (server-side ls).&lt;br /&gt;
|-&lt;br /&gt;
| Local path || Local directory where downloaded files are saved.&lt;br /&gt;
|-&lt;br /&gt;
| Username || SFTP login username.&lt;br /&gt;
|-&lt;br /&gt;
| Password || AES-encrypted password.&lt;br /&gt;
|-&lt;br /&gt;
| Private key path || Path to SSH private key file.&lt;br /&gt;
|-&lt;br /&gt;
| Delete after download || Whether to delete the remote file after successful download.&lt;br /&gt;
|-&lt;br /&gt;
| Backup path || Local directory where a copy of each downloaded file is kept.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== jsch_properties.xml ===&lt;br /&gt;
&lt;br /&gt;
Advanced SSH session parameters passed directly to the JSch library. Used to control host key checking, preferred algorithms, and connection timeouts. In most deployments this file can be left at its defaults.&lt;br /&gt;
&lt;br /&gt;
=== email_properties.xml ===&lt;br /&gt;
&lt;br /&gt;
SMTP settings for error notification emails. When a transfer failure occurs and email notification is enabled, SFTPTransfer sends an alert to the configured address. Fields include SMTP host, port, sender address, recipient address, and AES-encrypted SMTP password.&lt;br /&gt;
&lt;br /&gt;
== Installing as a Windows Service ==&lt;br /&gt;
&lt;br /&gt;
The native install package includes &amp;lt;code&amp;gt;sftpTransfer_Service.exe&amp;lt;/code&amp;gt;, a service-mode launcher built with install4j. This executable manages the Windows service directly — no additional wrapper is required.&lt;br /&gt;
&lt;br /&gt;
All service commands must be run from an elevated command prompt (Run as Administrator).&lt;br /&gt;
&lt;br /&gt;
The default Windows service name is &#039;&#039;&#039;sftpTransfer_Service&#039;&#039;&#039; (the launcher name defined in the installer). You can specify a different name as an optional second parameter — useful if you need to run multiple instances on the same machine. If a custom name is used at install time, that same name must be passed to every subsequent command.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Effect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /install&amp;lt;/code&amp;gt; || Register as &#039;&#039;&#039;sftpTransfer_Service&#039;&#039;&#039; with automatic startup on boot&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /install &amp;quot;My SFTP Service&amp;quot;&amp;lt;/code&amp;gt; || Register with a custom service name&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /install-demand&amp;lt;/code&amp;gt; || Register with manual startup only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /start&amp;lt;/code&amp;gt; || Start the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /stop&amp;lt;/code&amp;gt; || Stop the service (waits for graceful shutdown)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /restart&amp;lt;/code&amp;gt; || Restart the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /status&amp;lt;/code&amp;gt; || Query status (exit code: 0 = running, 3 = stopped)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /uninstall&amp;lt;/code&amp;gt; || Remove the service registration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If a custom service name was used at install time, append it to all subsequent commands:&lt;br /&gt;
&lt;br /&gt;
 sftpTransfer_Service.exe /start &amp;quot;My SFTP Service&amp;quot;&lt;br /&gt;
 sftpTransfer_Service.exe /stop &amp;quot;My SFTP Service&amp;quot;&lt;br /&gt;
 sftpTransfer_Service.exe /uninstall &amp;quot;My SFTP Service&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Once installed, the service also appears in the Windows Services management console (&amp;lt;code&amp;gt;services.msc&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Testing Before Installing as a Service ===&lt;br /&gt;
&lt;br /&gt;
The native install package also provides two alternatives for testing:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Launcher !! Mode !! Use case&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Console.exe&amp;lt;/code&amp;gt; || Console (headless) || Runs the service logic in a visible console window — useful for watching log output during initial configuration&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer.exe&amp;lt;/code&amp;gt; || Desktop GUI || Opens the GUI window in Start desktop mode — transfer threads start paused, allowing configuration to be verified before enabling transfers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Authentication ==&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer supports two authentication methods, configured per profile:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Method !! How to configure&lt;br /&gt;
|-&lt;br /&gt;
| Password || Set the &amp;lt;code&amp;gt;Password&amp;lt;/code&amp;gt; field in the profile to an AES-encrypted value. Leave the private key path empty.&lt;br /&gt;
|-&lt;br /&gt;
| SSH private key || Set the &amp;lt;code&amp;gt;Private key path&amp;lt;/code&amp;gt; field to the path of a PEM-format private key file. The password field is ignored.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Both methods use the JSch 2.x SSH library with Bouncy Castle as the cryptographic provider.&lt;br /&gt;
&lt;br /&gt;
=== Password Encryption ===&lt;br /&gt;
&lt;br /&gt;
Passwords stored in configuration files are AES-encrypted. Plain-text passwords are never stored on disk. To encrypt a password, use the password utility included with Commander4j (the same utility used for database passwords in Commander4j&#039;s own configuration).&lt;br /&gt;
&lt;br /&gt;
== File Transfer Behaviour ==&lt;br /&gt;
&lt;br /&gt;
=== PUT (Upload) ===&lt;br /&gt;
&lt;br /&gt;
# SFTPTransfer polls the local input directory every 10 seconds (configurable).&lt;br /&gt;
# Files matching the file mask are selected for upload.&lt;br /&gt;
# Each file is uploaded to the remote path using a temporary name with a &amp;lt;code&amp;gt;.tmp&amp;lt;/code&amp;gt; extension.&lt;br /&gt;
# On successful transfer, the remote file is renamed to its final name (atomic rename — the remote system never sees a partial file).&lt;br /&gt;
# The local source file is moved to the backup directory.&lt;br /&gt;
# If the transfer fails, the file is moved to the error directory and an error is logged.&lt;br /&gt;
&lt;br /&gt;
=== GET (Download) ===&lt;br /&gt;
&lt;br /&gt;
# SFTPTransfer lists the remote directory every 10 seconds (configurable).&lt;br /&gt;
# Files matching the file mask are selected for download.&lt;br /&gt;
# Each file is downloaded to the local path using a &amp;lt;code&amp;gt;.tmp&amp;lt;/code&amp;gt; extension.&lt;br /&gt;
# On successful download, the local file is renamed to its final name.&lt;br /&gt;
# If configured, the remote file is deleted after download.&lt;br /&gt;
# A backup copy is optionally saved to the local backup directory.&lt;br /&gt;
&lt;br /&gt;
== Thread Architecture ==&lt;br /&gt;
&lt;br /&gt;
When running, SFTPTransfer maintains the following threads:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Thread !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| TransferPUT || One thread per enabled PUT profile, each managing its own SFTP connection.&lt;br /&gt;
|-&lt;br /&gt;
| TransferGET || One thread per enabled GET profile, each managing its own SFTP connection.&lt;br /&gt;
|-&lt;br /&gt;
| EmailThread || Sends error notification emails asynchronously.&lt;br /&gt;
|-&lt;br /&gt;
| ArchiveThread || Periodically purges backup files older than the configured retention period.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Hot Configuration Reload ==&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer supports a configuration reload mode (&amp;lt;code&amp;gt;Mode_CONFIG_UPDATE&amp;lt;/code&amp;gt;). When this mode is triggered, running threads re-read their configuration files without requiring a full service restart. This allows profile changes — such as updating a remote path or rotating credentials — to be applied with minimal disruption.&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
All activity is written to the Log4j log file. The log records:&lt;br /&gt;
&lt;br /&gt;
* Service startup and configuration loaded&lt;br /&gt;
* Each thread starting and its profile settings&lt;br /&gt;
* Every file detected, transfer attempted, and outcome&lt;br /&gt;
* Every remote connection attempt and disconnect&lt;br /&gt;
* File move operations (to backup or error directories)&lt;br /&gt;
* Errors and exceptions with full context&lt;br /&gt;
&lt;br /&gt;
Log rotation and retention are configured in the Log4j configuration file included in the distribution.&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Library !! Version !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| JSch || 2.27.9 || SSH/SFTP client&lt;br /&gt;
|-&lt;br /&gt;
| Bouncy Castle || current || Cryptographic provider for JSch&lt;br /&gt;
|-&lt;br /&gt;
| Apache Commons IO || current || WildcardFileFilter for local file matching&lt;br /&gt;
|-&lt;br /&gt;
| Log4j || 2.25.3 || Logging&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
See also: [[LabelServer4j]], [[Middleware4j]], [[Production Lines &amp;amp; Labellers]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Installation_Middleware4j&amp;diff=1820</id>
		<title>Installation Middleware4j</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Installation_Middleware4j&amp;diff=1820"/>
		<updated>2026-04-05T16:05:01Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page covers deploying Middleware4j on a server or integration host.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Network access to any input or output directories defined in the map configuration (local paths, UNC shares, or mounted network drives)&lt;br /&gt;
* If using the EMAIL connector: network access to an SMTP server&lt;br /&gt;
* If using the SOCKET connector: network access to the target TCP/IP device&lt;br /&gt;
* Windows, Linux, or macOS&lt;br /&gt;
* Java 21 — required only when running from the distribution archive; the native install package bundles its own Java runtime&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Native install packages for Windows, macOS, and Linux are available from the [[Downloads]] page and are the preferred installation method. The installer creates the application directory, copies all configuration templates, and handles the Java runtime dependency automatically.&lt;br /&gt;
&lt;br /&gt;
Alternatively, a distribution archive can be extracted to a suitable directory, for example:&lt;br /&gt;
&lt;br /&gt;
 C:\Commander4j\Middleware4j\          (Windows)&lt;br /&gt;
 /opt/commander4j/middleware4j/        (Linux)&lt;br /&gt;
&lt;br /&gt;
The extracted directory contains:&lt;br /&gt;
&lt;br /&gt;
 c4jMiddleware.jar&lt;br /&gt;
 Middleware_Service.exe     (Windows — service launcher)&lt;br /&gt;
 Middleware_GUI.exe         (Windows — desktop GUI launcher)&lt;br /&gt;
 Encrypt_String.exe         (Windows — utility to encrypt passwords)&lt;br /&gt;
 start.cmd                  (Windows — fallback start script)&lt;br /&gt;
 start.sh                   (Linux/macOS — start script)&lt;br /&gt;
 xml/config/&lt;br /&gt;
 xslt/&lt;br /&gt;
 interface/&lt;br /&gt;
 logs/&lt;br /&gt;
 samples/&lt;br /&gt;
&lt;br /&gt;
== Configuration Before First Run ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Maps ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt; to define the transformation maps. Each map specifies one input connector, one or more output connectors, and optionally an XSLT stylesheet. See [[Maps]] for the full configuration reference.&lt;br /&gt;
&lt;br /&gt;
=== 2. XSLT Stylesheets ===&lt;br /&gt;
&lt;br /&gt;
Place any XSLT stylesheets used by your maps in the &amp;lt;code&amp;gt;xslt/&amp;lt;/code&amp;gt; directory. A library of over 60 sample stylesheets is included covering common integration scenarios with SAP, Sage, Tropos, B2MML, and others.&lt;br /&gt;
&lt;br /&gt;
=== 3. Email Notifications (Optional) ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;xml/config/email.xml&amp;lt;/code&amp;gt; with your SMTP server details and recipient addresses for error notifications.&lt;br /&gt;
&lt;br /&gt;
=== 4. Password Encryption ===&lt;br /&gt;
&lt;br /&gt;
Any passwords stored in configuration files (SMTP, database connections) must be AES-encrypted. Use the included &amp;lt;code&amp;gt;Encrypt_String.exe&amp;lt;/code&amp;gt; utility (Windows) to generate encrypted values. On Linux/macOS, use the equivalent utility from the Commander4j installation.&lt;br /&gt;
&lt;br /&gt;
== Installing as a Windows Service ==&lt;br /&gt;
&lt;br /&gt;
The native install package includes &amp;lt;code&amp;gt;Middleware_Service.exe&amp;lt;/code&amp;gt;, a service-mode launcher built with install4j. This executable manages the Windows service directly — no additional wrapper (such as WinSW) is required.&lt;br /&gt;
&lt;br /&gt;
All service commands must be run from an elevated command prompt (Run as Administrator).&lt;br /&gt;
&lt;br /&gt;
The default Windows service name is &#039;&#039;&#039;Middleware Service&#039;&#039;&#039; (the launcher name defined in the installer). You can specify a different name as an optional second parameter — useful if you need to run multiple instances on the same machine. If a custom name is used at install time, that same name must be passed to every subsequent command.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Effect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Middleware_Service.exe /install&amp;lt;/code&amp;gt; || Register as &#039;&#039;&#039;Middleware Service&#039;&#039;&#039; with automatic startup on boot&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Middleware_Service.exe /install &amp;quot;My Middleware&amp;quot;&amp;lt;/code&amp;gt; || Register with a custom service name&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Middleware_Service.exe /install-demand&amp;lt;/code&amp;gt; || Register with manual startup only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Middleware_Service.exe /start&amp;lt;/code&amp;gt; || Start the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Middleware_Service.exe /stop&amp;lt;/code&amp;gt; || Stop the service (waits for graceful shutdown)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Middleware_Service.exe /restart&amp;lt;/code&amp;gt; || Restart the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Middleware_Service.exe /status&amp;lt;/code&amp;gt; || Query status (exit code: 0 = running, 3 = stopped)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Middleware_Service.exe /uninstall&amp;lt;/code&amp;gt; || Remove the service registration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If a custom service name was used at install time, append it to all subsequent commands:&lt;br /&gt;
&lt;br /&gt;
 Middleware_Service.exe /start &amp;quot;My Middleware&amp;quot;&lt;br /&gt;
 Middleware_Service.exe /stop &amp;quot;My Middleware&amp;quot;&lt;br /&gt;
 Middleware_Service.exe /uninstall &amp;quot;My Middleware&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Once installed, the service also appears in the Windows Services management console (&amp;lt;code&amp;gt;services.msc&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Testing Before Installing as a Service ===&lt;br /&gt;
&lt;br /&gt;
Before committing to service installation, run Middleware4j in desktop GUI mode using:&lt;br /&gt;
&lt;br /&gt;
 Middleware_GUI.exe&lt;br /&gt;
&lt;br /&gt;
This launches a desktop window showing all configured maps, their current status, and real-time message counts. Use this mode to confirm that maps are reading from the correct input directories and that XSLT transformations produce the expected output. Once satisfied, switch to service mode for production deployment.&lt;br /&gt;
&lt;br /&gt;
== Starting on Linux / macOS ==&lt;br /&gt;
&lt;br /&gt;
Use the provided shell script:&lt;br /&gt;
&lt;br /&gt;
 ./start.sh&lt;br /&gt;
&lt;br /&gt;
The mode (GUI or Service) is passed as an argument by the script. The process runs in the foreground. For production deployment, use systemd, launchd, or nohup to manage it as a background process.&lt;br /&gt;
&lt;br /&gt;
== Verifying the Installation ==&lt;br /&gt;
&lt;br /&gt;
After starting Middleware4j:&lt;br /&gt;
&lt;br /&gt;
# Check &amp;lt;code&amp;gt;logs/&amp;lt;/code&amp;gt; for startup messages confirming that each map thread has initialised.&lt;br /&gt;
# Place a test input file in the input directory of one of the configured maps.&lt;br /&gt;
# Confirm the file is consumed and the expected output appears in the output directory.&lt;br /&gt;
# Check &amp;lt;code&amp;gt;interface/log/&amp;lt;/code&amp;gt; for the message transaction record.&lt;br /&gt;
&lt;br /&gt;
== Log Files ==&lt;br /&gt;
&lt;br /&gt;
All activity is written to the Log4j log file in the &amp;lt;code&amp;gt;logs/&amp;lt;/code&amp;gt; directory. Log rotation and retention are configured in &amp;lt;code&amp;gt;xml/config/log4j2.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
See also: [[Overview_Middleware4j]], [[Maps]], [[Connectors]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Middleware4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Installation_LabelServer4j&amp;diff=1819</id>
		<title>Installation LabelServer4j</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Installation_LabelServer4j&amp;diff=1819"/>
		<updated>2026-04-05T16:05:00Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page covers deploying LabelServer4j on a server or PC connected to the production network.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Network access to each label printer (TCP/IP — Zebra port 9100, Logopak port 9100 or as configured)&lt;br /&gt;
* Network access to the Commander4j server (to receive CSV request files)&lt;br /&gt;
* Windows, Linux, or macOS&lt;br /&gt;
* Java 21 — required only when running from the distribution archive; the native install package bundles its own Java runtime&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Native install packages for Windows, macOS, and Linux are available from the [[Downloads]] page and are the preferred installation method. The installer creates the application directory, copies all configuration templates, and handles the Java runtime dependency automatically.&lt;br /&gt;
&lt;br /&gt;
Alternatively, a distribution archive can be extracted to a suitable directory, for example:&lt;br /&gt;
&lt;br /&gt;
 C:\Commander4j\LabelServer4j\          (Windows)&lt;br /&gt;
 /opt/commander4j/labelserver4j/        (Linux)&lt;br /&gt;
&lt;br /&gt;
The extracted directory contains:&lt;br /&gt;
&lt;br /&gt;
 LabelServer.jar&lt;br /&gt;
 LabelServer.exe           (Windows — service launcher)&lt;br /&gt;
 LabelServerDebug.exe      (Windows — console launcher for testing)&lt;br /&gt;
 start_labeller.cmd        (Windows — fallback start script)&lt;br /&gt;
 start_labeller.sh         (Linux/macOS — start script)&lt;br /&gt;
 lib/&lt;br /&gt;
 xml/config/&lt;br /&gt;
 labeller_files/&lt;br /&gt;
 labeller_requests/&lt;br /&gt;
 labeller_cmd/&lt;br /&gt;
 labeller_backups/&lt;br /&gt;
 logs/&lt;br /&gt;
&lt;br /&gt;
== Configuration Before First Run ==&lt;br /&gt;
&lt;br /&gt;
Before starting LabelServer4j, complete the following configuration steps.&lt;br /&gt;
&lt;br /&gt;
=== 1. Site and Labeller Definitions ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt; to set the active site identifier. Then create or edit the &amp;lt;code&amp;gt;labellers.xml&amp;lt;/code&amp;gt; file for that site in &amp;lt;code&amp;gt;xml/config/&amp;lt;/code&amp;gt;. Each labeller entry defines:&lt;br /&gt;
&lt;br /&gt;
* The labeller name (must match the name used in Commander4j)&lt;br /&gt;
* The printer IP address and TCP port&lt;br /&gt;
* The path to the command script&lt;br /&gt;
* The input directory where Commander4j writes CSV files&lt;br /&gt;
&lt;br /&gt;
See [[LabelServer4j Configuration]] for the full XML structure.&lt;br /&gt;
&lt;br /&gt;
=== 2. Command Scripts ===&lt;br /&gt;
&lt;br /&gt;
Place the command script files (plain text &amp;lt;code&amp;gt;.txt&amp;lt;/code&amp;gt; files) for each labeller in the &amp;lt;code&amp;gt;labeller_cmd/&amp;lt;/code&amp;gt; directory. The script filename is referenced in &amp;lt;code&amp;gt;labellers.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 3. Label Files (Logopak only) ===&lt;br /&gt;
&lt;br /&gt;
If using Logopak printers with stored label templates, place the binary label files in the appropriate subdirectory of &amp;lt;code&amp;gt;labeller_files/&amp;lt;/code&amp;gt;. LabelServer4j can upload these to the printer using the &amp;lt;code&amp;gt;SEND_FILE_INTELHEX&amp;lt;/code&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
=== 4. Database Connection (Optional) ===&lt;br /&gt;
&lt;br /&gt;
If the command scripts use &amp;lt;code&amp;gt;DB_QUERY&amp;lt;/code&amp;gt; to enrich label data from the Commander4j database, configure the database connection in &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt; with the JDBC URL, username, and AES-encrypted password.&lt;br /&gt;
&lt;br /&gt;
=== 5. Email Notifications (Optional) ===&lt;br /&gt;
&lt;br /&gt;
To receive alerts on print failures or service events, configure &amp;lt;code&amp;gt;xml/config/email.xml&amp;lt;/code&amp;gt; with SMTP server details and recipient addresses.&lt;br /&gt;
&lt;br /&gt;
== Installing as a Windows Service ==&lt;br /&gt;
&lt;br /&gt;
The native install package includes &amp;lt;code&amp;gt;LabelServer.exe&amp;lt;/code&amp;gt;, a service-mode launcher built with install4j. This executable manages the Windows service directly — no additional wrapper (such as WinSW) is required.&lt;br /&gt;
&lt;br /&gt;
All service commands must be run from an elevated command prompt (Run as Administrator).&lt;br /&gt;
&lt;br /&gt;
The default Windows service name is &#039;&#039;&#039;LabelService&#039;&#039;&#039; (the launcher name defined in the installer). You can specify a different name as an optional second parameter — useful if you need to run multiple instances on the same machine. If a custom name is used at install time, that same name must be passed to every subsequent command.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Effect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /install&amp;lt;/code&amp;gt; || Register as &#039;&#039;&#039;LabelService&#039;&#039;&#039; with automatic startup on boot&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /install &amp;quot;My Label Service&amp;quot;&amp;lt;/code&amp;gt; || Register with a custom service name&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /install-demand&amp;lt;/code&amp;gt; || Register with manual startup only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /start&amp;lt;/code&amp;gt; || Start the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /stop&amp;lt;/code&amp;gt; || Stop the service (waits for graceful shutdown)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /restart&amp;lt;/code&amp;gt; || Restart the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /status&amp;lt;/code&amp;gt; || Query status (exit code: 0 = running, 3 = stopped)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /uninstall&amp;lt;/code&amp;gt; || Remove the service registration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If a custom service name was used at install time, append it to all subsequent commands:&lt;br /&gt;
&lt;br /&gt;
 LabelServer.exe /start &amp;quot;My Label Service&amp;quot;&lt;br /&gt;
 LabelServer.exe /stop &amp;quot;My Label Service&amp;quot;&lt;br /&gt;
 LabelServer.exe /uninstall &amp;quot;My Label Service&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Once installed, the service also appears in the Windows Services management console (&amp;lt;code&amp;gt;services.msc&amp;lt;/code&amp;gt;) and can be started and stopped from there.&lt;br /&gt;
&lt;br /&gt;
=== Testing Before Installing as a Service ===&lt;br /&gt;
&lt;br /&gt;
Before committing to service installation, run LabelServer4j in a visible console window using the debug launcher:&lt;br /&gt;
&lt;br /&gt;
 LabelServerDebug.exe&lt;br /&gt;
&lt;br /&gt;
This runs the same application code with all log output written to the console window. Use this mode to confirm that labellers connect to their printers and that the configuration is correct before installing as a service.&lt;br /&gt;
&lt;br /&gt;
== Starting on Linux / macOS ==&lt;br /&gt;
&lt;br /&gt;
Use the provided shell script:&lt;br /&gt;
&lt;br /&gt;
 ./start_labeller.sh&lt;br /&gt;
&lt;br /&gt;
Or directly:&lt;br /&gt;
&lt;br /&gt;
 java -cp ./LabelServer.jar:./lib/devonly/i4jruntime.jar com.commander4j.labeller.Service&lt;br /&gt;
&lt;br /&gt;
The process runs in the foreground. For production deployment, use a process manager (systemd, launchd, or nohup) to run it as a background service.&lt;br /&gt;
&lt;br /&gt;
== Verifying the Installation ==&lt;br /&gt;
&lt;br /&gt;
After starting LabelServer4j:&lt;br /&gt;
&lt;br /&gt;
# Check &amp;lt;code&amp;gt;logs/c4jLabelServer.log&amp;lt;/code&amp;gt; — there should be startup and thread initialisation messages.&lt;br /&gt;
# Verify that each labeller thread reports a successful TCP connection to its printer.&lt;br /&gt;
# Place a test CSV file in a labeller&#039;s input directory to trigger an end-to-end print cycle.&lt;br /&gt;
# Confirm the CSV file is consumed (deleted on success, or moved to the error directory on failure).&lt;br /&gt;
&lt;br /&gt;
== Log Files ==&lt;br /&gt;
&lt;br /&gt;
All activity is written to &amp;lt;code&amp;gt;logs/c4jLabelServer.log&amp;lt;/code&amp;gt;. Log files rotate at 10 MB and are retained for 14 days.&lt;br /&gt;
&lt;br /&gt;
See also: [[Overview LabelServer4j]], [[LabelServer4j Operation]], [[LabelServer4j Configuration]], [[LabelServer4j Example User Interface]]&lt;br /&gt;
&lt;br /&gt;
[[Category:LabelServer4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Interface_Service&amp;diff=1818</id>
		<title>Interface Service</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Interface_Service&amp;diff=1818"/>
		<updated>2026-04-05T16:01:24Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Commander4j Interface Service is a background process that handles all automated integration between Commander4j and external systems. It monitors for incoming XML messages from ERPs and other systems, generates outbound XML messages, triggers scheduled reports, and drives automatic labelling. It is designed to run continuously on a server as a Windows service.&lt;br /&gt;
&lt;br /&gt;
The service is a separate optional component — the main Commander4j desktop application does not need to be running for the Interface Service to operate.&lt;br /&gt;
&lt;br /&gt;
== What the Service Does ==&lt;br /&gt;
&lt;br /&gt;
When started, the Interface Service logs into the Commander4j database using the built-in &amp;lt;code&amp;gt;interface&amp;lt;/code&amp;gt; account and starts five background threads:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Thread !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Inbound Message Thread&#039;&#039;&#039; || Monitors the configured inbound directory for XML message files from external systems. Processes each file against the appropriate message handler and writes results to &amp;lt;code&amp;gt;SYS_INTERFACE_LOG&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Outbound Message Thread&#039;&#039;&#039; || Picks up XML messages queued in the database for transmission to external systems and writes them to the configured outbound directories.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Recovery Thread&#039;&#039;&#039; || Monitors the recovery path for messages that failed processing and re-attempts them on a schedule.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Reporting Thread&#039;&#039;&#039; || Fires scheduled reports at their configured times and distributes the output.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Auto Labeller Thread&#039;&#039;&#039; || Drives automatic pallet labelling triggers that are not handled by [[AutoLab4j]] or [[LabelServer4j]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
At a configured daily housekeeping time the service gracefully stops all threads, performs maintenance tasks, and restarts. Email notifications are sent on startup, shutdown, and housekeeping if configured.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
=== Host Configuration ===&lt;br /&gt;
&lt;br /&gt;
The Interface Service identifies which database to connect to by looking for a host entry in &amp;lt;code&amp;gt;hosts.xml&amp;lt;/code&amp;gt; with a &amp;lt;code&amp;gt;uniqueId&amp;lt;/code&amp;gt; of &amp;lt;code&amp;gt;service&amp;lt;/code&amp;gt;. This host entry must be created using [[Setup4j]] before the service will start. Without it, the service logs an error and exits immediately.&lt;br /&gt;
&lt;br /&gt;
=== Interface User Account ===&lt;br /&gt;
&lt;br /&gt;
The service logs into Commander4j using the application account &amp;lt;code&amp;gt;interface&amp;lt;/code&amp;gt; with password &amp;lt;code&amp;gt;interface&amp;lt;/code&amp;gt;. This account must exist and be enabled in the Commander4j user list. It is created automatically when the schema is initialised, but verify it has not been disabled or had its password changed.&lt;br /&gt;
&lt;br /&gt;
== Installing as a Windows Service ==&lt;br /&gt;
&lt;br /&gt;
The native install package includes &amp;lt;code&amp;gt;Service4j.exe&amp;lt;/code&amp;gt;, a service-mode launcher built with install4j. This executable manages the Windows service directly — no additional wrapper is required.&lt;br /&gt;
&lt;br /&gt;
All service commands must be run from an elevated command prompt (Run as Administrator).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Effect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Service4j.exe /install&amp;lt;/code&amp;gt; || Register the Windows service with automatic startup on boot&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Service4j.exe /install-demand&amp;lt;/code&amp;gt; || Register the service with manual startup only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Service4j.exe /start&amp;lt;/code&amp;gt; || Start the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Service4j.exe /stop&amp;lt;/code&amp;gt; || Stop the service (waits for graceful shutdown)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Service4j.exe /restart&amp;lt;/code&amp;gt; || Restart the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Service4j.exe /status&amp;lt;/code&amp;gt; || Query status (exit code: 0 = running, 3 = stopped)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Service4j.exe /uninstall&amp;lt;/code&amp;gt; || Remove the service registration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Once installed, the service also appears in the Windows Services management console (&amp;lt;code&amp;gt;services.msc&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Testing Before Installing as a Service ===&lt;br /&gt;
&lt;br /&gt;
Before committing to service installation, run the Interface Service in a visible console window using:&lt;br /&gt;
&lt;br /&gt;
 Interface4j.exe&lt;br /&gt;
&lt;br /&gt;
This runs the same application code and all log output is written to the console window. Use this mode to confirm that the correct host is found, the &amp;lt;code&amp;gt;interface&amp;lt;/code&amp;gt; account logs in, and all threads start successfully.&lt;br /&gt;
&lt;br /&gt;
== Email Notifications ==&lt;br /&gt;
&lt;br /&gt;
If configured, the service sends email alerts at key lifecycle events:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !! Trigger&lt;br /&gt;
|-&lt;br /&gt;
| Startup || Service has connected to the database and all threads are running&lt;br /&gt;
|-&lt;br /&gt;
| Shutdown || Service has stopped all threads and disconnected&lt;br /&gt;
|-&lt;br /&gt;
| Housekeeping || Daily maintenance cycle has run&lt;br /&gt;
|-&lt;br /&gt;
| Statistics || Daily statistics summary (if enabled)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Email notification is controlled by the system key &amp;lt;code&amp;gt;INTERFACE EMAIL NOTIFY&amp;lt;/code&amp;gt; (true/false) and the recipient list in &amp;lt;code&amp;gt;INTERFACE ADMIN EMAIL&amp;lt;/code&amp;gt;. Both are configured in the Commander4j system keys administration screen.&lt;br /&gt;
&lt;br /&gt;
== Monitoring ==&lt;br /&gt;
&lt;br /&gt;
All activity is written to the Log4j log file in the &amp;lt;code&amp;gt;logs/&amp;lt;/code&amp;gt; directory. The [[Interface Log]] screen in the Commander4j desktop application provides a searchable view of every message processed — inbound and outbound — including status, error details, and message content.&lt;br /&gt;
&lt;br /&gt;
Failed messages can be resubmitted for reprocessing from the Interface Log screen without re-sending the original file.&lt;br /&gt;
&lt;br /&gt;
See also: [[Interface Log]], [[Interface Message Formats]], [[Setup4j]], [[AutoLab4j]], [[LabelServer4j]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Clone4j&amp;diff=1817</id>
		<title>Clone4j</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Clone4j&amp;diff=1817"/>
		<updated>2026-04-05T16:01:21Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Clone4j&#039;&#039;&#039; is a database copy utility included with Commander4j. It copies the entire contents of one Commander4j database into another, and supports copying between different database types — for example from SQL Server to MySQL or from MySQL to Oracle.&lt;br /&gt;
&lt;br /&gt;
Clone4j is launched from the &amp;lt;code&amp;gt;Clone4j.exe&amp;lt;/code&amp;gt; executable in the Commander4j installation directory. It requires administrator privileges (the launcher requests elevation on Windows).&lt;br /&gt;
&lt;br /&gt;
== When to Use Clone4j ==&lt;br /&gt;
&lt;br /&gt;
Typical uses include:&lt;br /&gt;
&lt;br /&gt;
* Copying a live production database to a test or development environment&lt;br /&gt;
* Migrating data when moving a site from one database platform to another&lt;br /&gt;
* Creating a full backup copy of the database in a different database instance&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Before running Clone4j:&lt;br /&gt;
&lt;br /&gt;
* Both the source and destination databases must be defined as hosts in &amp;lt;code&amp;gt;hosts.xml&amp;lt;/code&amp;gt; (use [[Setup4j]] to configure host connections)&lt;br /&gt;
* Both databases must be on the &#039;&#039;&#039;same schema version&#039;&#039;&#039; — Clone4j will refuse to proceed if the schema versions differ&lt;br /&gt;
* Both databases must have the same number of tables — they must be on identical schema revisions with no partial upgrades applied&lt;br /&gt;
* The destination database will have &#039;&#039;&#039;all its data erased&#039;&#039;&#039; and replaced with the source data&lt;br /&gt;
&lt;br /&gt;
== Using Clone4j ==&lt;br /&gt;
&lt;br /&gt;
# Launch &amp;lt;code&amp;gt;Clone4j.exe&amp;lt;/code&amp;gt;&lt;br /&gt;
# The window shows two lists populated from &amp;lt;code&amp;gt;hosts.xml&amp;lt;/code&amp;gt; — select the &#039;&#039;&#039;source&#039;&#039;&#039; database on the left and the &#039;&#039;&#039;destination&#039;&#039;&#039; database on the right&lt;br /&gt;
# Click &#039;&#039;&#039;Clone Database&#039;&#039;&#039;&lt;br /&gt;
# A confirmation prompt warns that all data in the destination will be erased — confirm to proceed&lt;br /&gt;
# Clone4j copies every table in sequence, updating a progress bar as it works&lt;br /&gt;
# On completion, the status bar reports the outcome&lt;br /&gt;
&lt;br /&gt;
The Clone button is only enabled when both a source and a destination have been selected and they are not the same host.&lt;br /&gt;
&lt;br /&gt;
== Limitations ==&lt;br /&gt;
&lt;br /&gt;
* Clone4j copies data row by row — it is not a structural migration tool. Both databases must already have matching schemas (same schema version, same table count).&lt;br /&gt;
* It is not designed for continuous replication. It is a one-time full copy.&lt;br /&gt;
* Large databases may take several minutes to clone depending on row count and network speed.&lt;br /&gt;
&lt;br /&gt;
See also: [[Setup4j]], [[Installation]], [[Upgrading]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=LabelServer4j&amp;diff=1816</id>
		<title>LabelServer4j</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=LabelServer4j&amp;diff=1816"/>
		<updated>2026-04-05T15:56:01Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;LabelServer4j&#039;&#039;&#039; is a background label printing service that bridges Commander4j and physical label printer devices on a production line. When an operator assigns a [[Process Orders|Process Order]] to a production line, Commander4j exports a data file which LabelServer4j picks up, processes through a configurable script, and uses to drive the printer over TCP/IP.&lt;br /&gt;
&lt;br /&gt;
LabelServer4j supports Zebra ZPL printers, Logopak labellers, and any device that accepts raw TCP/IP text commands. It runs as a headless background service with no graphical interface, and can manage multiple printers simultaneously in independent threads.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [[Overview LabelServer4j]] || What LabelServer4j does and how it differs from AutoLab4j&lt;br /&gt;
|-&lt;br /&gt;
| [[Downloads]] || Download the latest release&lt;br /&gt;
|-&lt;br /&gt;
| [[Installation LabelServer4j]] || Installing LabelServer4j and configuring as a Windows service&lt;br /&gt;
|-&lt;br /&gt;
| [[LabelServer4j Configuration]] || Configuring sites, labellers, and database connections&lt;br /&gt;
|-&lt;br /&gt;
| [[LabelServer4j Folder Structure]] || Directory layout and purpose of each folder&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== User Guide ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [[LabelServer4j Operation]] || End-to-end workflow from order assignment to label printed&lt;br /&gt;
|-&lt;br /&gt;
| [[LabelServer4j Dataset CSV]] || Fields available in the CSV data file from Commander4j&lt;br /&gt;
|-&lt;br /&gt;
| [[LabelServer4j Example User Interface]] || Deployment, startup, monitoring, and log file reference&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Related Pages ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [[Production Lines &amp;amp; Labellers]] || Configuring production lines in Commander4j&lt;br /&gt;
|-&lt;br /&gt;
| [[Process Order Assign to Labeller]] || Assigning orders to labellers from Commander4j&lt;br /&gt;
|-&lt;br /&gt;
| [[Zebra ZPL Label]] || ZPL label template syntax reference&lt;br /&gt;
|-&lt;br /&gt;
| [[Label Template Syntax]] || Commander4j label template language&lt;br /&gt;
|-&lt;br /&gt;
| [[ZPLRenderer]] || Tool for previewing ZPL labels before printing&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:LabelServer4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Installation_AutoLab4j&amp;diff=1815</id>
		<title>Installation AutoLab4j</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Installation_AutoLab4j&amp;diff=1815"/>
		<updated>2026-04-05T15:56:00Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page covers deploying AutoLab4j on a server or PC connected to the production network.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Network access to the Modbus I/O device on each production line (TCP port 502 by default)&lt;br /&gt;
* Network access to each Zebra printer (TCP port 9100)&lt;br /&gt;
* Network access to the Commander4j server (to receive CSV dataset files)&lt;br /&gt;
* Windows, Linux, or macOS&lt;br /&gt;
* Java 21 (JRE or JDK) — required only when running from the distribution archive; the native install package bundles its own Java runtime&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Native install packages for Windows, macOS, and Linux are available from the [[Downloads]] page and are the preferred installation method. The installer creates the application directory, registers it with the operating system, and handles the Java runtime dependency automatically.&lt;br /&gt;
&lt;br /&gt;
Alternatively, a distribution archive can be downloaded from the [[Downloads]] page and extracted to a suitable directory, for example:&lt;br /&gt;
&lt;br /&gt;
 C:\Commander4j\AutoLab4j\          (Windows)&lt;br /&gt;
 /opt/commander4j/autolab4j/        (Linux)&lt;br /&gt;
&lt;br /&gt;
The extracted directory contains:&lt;br /&gt;
&lt;br /&gt;
 AutoLab.jar&lt;br /&gt;
 lib/&lt;br /&gt;
 xml/&lt;br /&gt;
 labels/&lt;br /&gt;
 logs/&lt;br /&gt;
 interface/&lt;br /&gt;
 running/&lt;br /&gt;
&lt;br /&gt;
== Configuration Before First Run ==&lt;br /&gt;
&lt;br /&gt;
Before starting AutoLab4j, complete the following configuration steps.&lt;br /&gt;
&lt;br /&gt;
=== 1. Production Lines ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt; and define each production line. For each line you need:&lt;br /&gt;
&lt;br /&gt;
* The Modbus device IP address and port&lt;br /&gt;
* The coil address that signals a pallet complete event&lt;br /&gt;
* The coil address for semi-pallet detection&lt;br /&gt;
* The printer name (must match the name used in Commander4j)&lt;br /&gt;
&lt;br /&gt;
See [[AutoLab4j Configuration]] for the full XML structure.&lt;br /&gt;
&lt;br /&gt;
=== 2. SSCC Sequence Files ===&lt;br /&gt;
&lt;br /&gt;
Create one SSCC sequence file per printer in &amp;lt;code&amp;gt;xml/sscc/&amp;lt;/code&amp;gt;. The filename must match the printer name configured in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;. For example, for a printer named &amp;lt;code&amp;gt;PRINTER 1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 xml/sscc/PRINTER 1.xml&lt;br /&gt;
&lt;br /&gt;
The file must contain the SSCC prefix, starting sequence number, warning limit, and upper limit. Your GS1 member organisation will provide the prefix. Example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;lt;sscc&amp;gt;&lt;br /&gt;
   &amp;lt;prefix&amp;gt;384133182&amp;lt;/prefix&amp;gt;&lt;br /&gt;
   &amp;lt;sequence&amp;gt;00000001&amp;lt;/sequence&amp;gt;&lt;br /&gt;
   &amp;lt;checkDigit&amp;gt;0&amp;lt;/checkDigit&amp;gt;&lt;br /&gt;
   &amp;lt;upperlimit&amp;gt;00009999&amp;lt;/upperlimit&amp;gt;&lt;br /&gt;
   &amp;lt;warninglimit&amp;gt;00009000&amp;lt;/warninglimit&amp;gt;&lt;br /&gt;
 &amp;lt;/sscc&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Label Templates ===&lt;br /&gt;
&lt;br /&gt;
Copy the ZPL label template files into the &amp;lt;code&amp;gt;labels/&amp;lt;/code&amp;gt; directory. The filename for each template is specified in the CSV dataset file in the &amp;lt;code&amp;gt;REPORT_FILENAME&amp;lt;/code&amp;gt; field. See [[Zebra ZPL Label]] for information on ZPL label authoring.&lt;br /&gt;
&lt;br /&gt;
=== 4. Dataset Directory ===&lt;br /&gt;
&lt;br /&gt;
Ensure the directory configured as &amp;lt;code&amp;gt;dataSet path&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt; is accessible. This is where Commander4j writes the CSV files when an operator assigns a process order to a labeller. The directory can be a local path or a network share.&lt;br /&gt;
&lt;br /&gt;
=== 5. Output Directory ===&lt;br /&gt;
&lt;br /&gt;
Ensure the directory configured as &amp;lt;code&amp;gt;output path&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt; exists and is writable. AutoLab4j writes Production Declaration XML files here after each pallet is printed.&lt;br /&gt;
&lt;br /&gt;
=== 6. Email Notifications (Optional) ===&lt;br /&gt;
&lt;br /&gt;
If you want email alerts for SSCC warnings and service start/stop events, configure &amp;lt;code&amp;gt;xml/config/email.xml&amp;lt;/code&amp;gt; with your SMTP server details and distribution lists.&lt;br /&gt;
&lt;br /&gt;
== Starting AutoLab4j ==&lt;br /&gt;
&lt;br /&gt;
=== Windows — Native Package ===&lt;br /&gt;
&lt;br /&gt;
The native install package creates &amp;lt;code&amp;gt;AutoLab4j_Startup.exe&amp;lt;/code&amp;gt; in the installation directory. Double-click this launcher, or create a shortcut to it, to start AutoLab4j. It enforces single-instance operation — a second launch will signal the running instance to shut down before the new one starts.&lt;br /&gt;
&lt;br /&gt;
AutoLab4j is a GUI application and does not include a built-in Windows service launcher. To run it automatically at boot without an interactive session, use a service wrapper such as WinSW configured to launch &amp;lt;code&amp;gt;AutoLab4j_Startup.exe&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Windows — Distribution Archive ===&lt;br /&gt;
&lt;br /&gt;
If running from the extracted archive rather than the native package:&lt;br /&gt;
&lt;br /&gt;
 java -jar AutoLab.jar&lt;br /&gt;
&lt;br /&gt;
=== Linux / macOS ===&lt;br /&gt;
&lt;br /&gt;
 java -jar AutoLab.jar&lt;br /&gt;
&lt;br /&gt;
Use systemd, launchd, or nohup for production deployment as a background process.&lt;br /&gt;
&lt;br /&gt;
When running, AutoLab4j appears in the system tray with one icon per production line. The System Log window shows startup progress.&lt;br /&gt;
&lt;br /&gt;
== Exclusive Runtime ==&lt;br /&gt;
&lt;br /&gt;
AutoLab4j uses a TCP port (default: 8000) as an exclusive runtime lock. Only one instance can run at a time. If you start a second instance, it sends a shutdown signal to the running instance and waits for it to stop before starting. The watchdog port can be changed in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Verifying the Installation ==&lt;br /&gt;
&lt;br /&gt;
After starting AutoLab4j:&lt;br /&gt;
&lt;br /&gt;
# Check the system tray — there should be one icon per enabled production line.&lt;br /&gt;
# Open the System Log window (right-click the system tray icon).&lt;br /&gt;
# Verify that each production line shows a Modbus connection attempt in its log window.&lt;br /&gt;
# Place a test CSV file in the dataset directory and trigger the Modbus coil to confirm end-to-end operation.&lt;br /&gt;
&lt;br /&gt;
== Log Files ==&lt;br /&gt;
&lt;br /&gt;
All activity is written to &amp;lt;code&amp;gt;logs/AutoLab.log&amp;lt;/code&amp;gt;. Log files rotate at 10 MB and are retained for 14 days. Review this file if any production line fails to connect or if labels are not printing.&lt;br /&gt;
&lt;br /&gt;
See also: [[AutoLab4j Configuration]], [[Overview AutoLab4j]], [[AutoLab4j Operation]]&lt;br /&gt;
&lt;br /&gt;
[[Category:AutoLab4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=SFTPTransfer&amp;diff=1814</id>
		<title>SFTPTransfer</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=SFTPTransfer&amp;diff=1814"/>
		<updated>2026-04-05T15:55:54Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SFTPTransfer is a background file transfer service that moves files between a local filesystem and a remote SFTP server. It is a standalone Java application that runs either as a headless background service or as a desktop application with a minimal GUI, and supports both uploading (PUT) and downloading (GET) in independent threads.&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer replaces the earlier sftpSend and sftpGet tools with a unified, configurable service.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer automates recurring file transfers between Commander4j and external systems — for example, uploading despatch notifications to a customer portal or downloading order files from a supplier. It runs continuously, polling for new files at a configurable interval, and handles authentication, retry, backup, and archiving without operator involvement.&lt;br /&gt;
&lt;br /&gt;
== Startup Modes ==&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer supports two startup modes selected at launch time:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Mode !! Behaviour&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Start desktop&#039;&#039;&#039; || Opens a small GUI window. Transfer threads start in a paused state; the operator must click Start in the interface to begin polling. Useful for testing configuration.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Start service&#039;&#039;&#039; || Headless — no GUI window. Transfer threads start immediately on launch. Suitable for production deployment as a background service or scheduled task.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On Windows, the native install package includes &amp;lt;code&amp;gt;sftpTransfer_Service.exe&amp;lt;/code&amp;gt;, which manages the Windows service directly — see [[#Installing as a Windows Service|Installing as a Windows Service]] below. On Linux/macOS, use systemd, launchd, or nohup.&lt;br /&gt;
&lt;br /&gt;
== Configuration Files ==&lt;br /&gt;
&lt;br /&gt;
All configuration is held in XML files under the &amp;lt;code&amp;gt;xml/config/&amp;lt;/code&amp;gt; directory. Changes require a service restart unless hot-reload is triggered (see below).&lt;br /&gt;
&lt;br /&gt;
=== sftp_common.xml ===&lt;br /&gt;
&lt;br /&gt;
Shared settings used by all transfer threads:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Poll interval || How often (in seconds) each thread checks for new files. Default: 10 seconds.&lt;br /&gt;
|-&lt;br /&gt;
| Backup retention || Number of days to keep backed-up files before automatic deletion.&lt;br /&gt;
|-&lt;br /&gt;
| Log level || Logging verbosity passed to Log4j.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sftp_put.xml ===&lt;br /&gt;
&lt;br /&gt;
Configures one or more PUT (upload) profiles. Each profile defines:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Enabled || Whether this profile&#039;s thread is active.&lt;br /&gt;
|-&lt;br /&gt;
| Local path || Local directory to watch for outbound files.&lt;br /&gt;
|-&lt;br /&gt;
| File mask || Wildcard pattern to match files (e.g. &amp;lt;code&amp;gt;*.xml&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;order_*.csv&amp;lt;/code&amp;gt;). Uses Apache Commons IO WildcardFileFilter.&lt;br /&gt;
|-&lt;br /&gt;
| Remote host || SFTP server hostname or IP address.&lt;br /&gt;
|-&lt;br /&gt;
| Remote port || SFTP port (default: 22).&lt;br /&gt;
|-&lt;br /&gt;
| Remote path || Target directory on the remote server.&lt;br /&gt;
|-&lt;br /&gt;
| Username || SFTP login username.&lt;br /&gt;
|-&lt;br /&gt;
| Password || AES-encrypted password (see [[#Password Encryption|Password Encryption]]).&lt;br /&gt;
|-&lt;br /&gt;
| Private key path || Path to SSH private key file (alternative to password authentication).&lt;br /&gt;
|-&lt;br /&gt;
| Backup path || Local directory where successfully uploaded files are moved.&lt;br /&gt;
|-&lt;br /&gt;
| Error path || Local directory where files that failed to upload are moved.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sftp_get.xml ===&lt;br /&gt;
&lt;br /&gt;
Configures one or more GET (download) profiles. Each profile defines:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Enabled || Whether this profile&#039;s thread is active.&lt;br /&gt;
|-&lt;br /&gt;
| Remote host || SFTP server hostname or IP address.&lt;br /&gt;
|-&lt;br /&gt;
| Remote port || SFTP port (default: 22).&lt;br /&gt;
|-&lt;br /&gt;
| Remote path || Directory on the remote server to poll for incoming files.&lt;br /&gt;
|-&lt;br /&gt;
| File mask || Wildcard pattern matched against the remote file listing (server-side ls).&lt;br /&gt;
|-&lt;br /&gt;
| Local path || Local directory where downloaded files are saved.&lt;br /&gt;
|-&lt;br /&gt;
| Username || SFTP login username.&lt;br /&gt;
|-&lt;br /&gt;
| Password || AES-encrypted password.&lt;br /&gt;
|-&lt;br /&gt;
| Private key path || Path to SSH private key file.&lt;br /&gt;
|-&lt;br /&gt;
| Delete after download || Whether to delete the remote file after successful download.&lt;br /&gt;
|-&lt;br /&gt;
| Backup path || Local directory where a copy of each downloaded file is kept.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== jsch_properties.xml ===&lt;br /&gt;
&lt;br /&gt;
Advanced SSH session parameters passed directly to the JSch library. Used to control host key checking, preferred algorithms, and connection timeouts. In most deployments this file can be left at its defaults.&lt;br /&gt;
&lt;br /&gt;
=== email_properties.xml ===&lt;br /&gt;
&lt;br /&gt;
SMTP settings for error notification emails. When a transfer failure occurs and email notification is enabled, SFTPTransfer sends an alert to the configured address. Fields include SMTP host, port, sender address, recipient address, and AES-encrypted SMTP password.&lt;br /&gt;
&lt;br /&gt;
== Installing as a Windows Service ==&lt;br /&gt;
&lt;br /&gt;
The native install package includes &amp;lt;code&amp;gt;sftpTransfer_Service.exe&amp;lt;/code&amp;gt;, a service-mode launcher built with install4j. This executable manages the Windows service directly — no additional wrapper is required.&lt;br /&gt;
&lt;br /&gt;
All service commands must be run from an elevated command prompt (Run as Administrator).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Effect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /install&amp;lt;/code&amp;gt; || Register the Windows service with automatic startup on boot&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /install-demand&amp;lt;/code&amp;gt; || Register the service with manual startup only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /start&amp;lt;/code&amp;gt; || Start the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /stop&amp;lt;/code&amp;gt; || Stop the service (waits for graceful shutdown)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /restart&amp;lt;/code&amp;gt; || Restart the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /status&amp;lt;/code&amp;gt; || Query status (exit code: 0 = running, 3 = stopped)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Service.exe /uninstall&amp;lt;/code&amp;gt; || Remove the service registration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Once installed, the service also appears in the Windows Services management console (&amp;lt;code&amp;gt;services.msc&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Testing Before Installing as a Service ===&lt;br /&gt;
&lt;br /&gt;
The native install package also provides two alternatives for testing:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Launcher !! Mode !! Use case&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer_Console.exe&amp;lt;/code&amp;gt; || Console (headless) || Runs the service logic in a visible console window — useful for watching log output during initial configuration&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sftpTransfer.exe&amp;lt;/code&amp;gt; || Desktop GUI || Opens the GUI window in Start desktop mode — transfer threads start paused, allowing configuration to be verified before enabling transfers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Authentication ==&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer supports two authentication methods, configured per profile:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Method !! How to configure&lt;br /&gt;
|-&lt;br /&gt;
| Password || Set the &amp;lt;code&amp;gt;Password&amp;lt;/code&amp;gt; field in the profile to an AES-encrypted value. Leave the private key path empty.&lt;br /&gt;
|-&lt;br /&gt;
| SSH private key || Set the &amp;lt;code&amp;gt;Private key path&amp;lt;/code&amp;gt; field to the path of a PEM-format private key file. The password field is ignored.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Both methods use the JSch 2.x SSH library with Bouncy Castle as the cryptographic provider.&lt;br /&gt;
&lt;br /&gt;
=== Password Encryption ===&lt;br /&gt;
&lt;br /&gt;
Passwords stored in configuration files are AES-encrypted. Plain-text passwords are never stored on disk. To encrypt a password, use the password utility included with Commander4j (the same utility used for database passwords in Commander4j&#039;s own configuration).&lt;br /&gt;
&lt;br /&gt;
== File Transfer Behaviour ==&lt;br /&gt;
&lt;br /&gt;
=== PUT (Upload) ===&lt;br /&gt;
&lt;br /&gt;
# SFTPTransfer polls the local input directory every 10 seconds (configurable).&lt;br /&gt;
# Files matching the file mask are selected for upload.&lt;br /&gt;
# Each file is uploaded to the remote path using a temporary name with a &amp;lt;code&amp;gt;.tmp&amp;lt;/code&amp;gt; extension.&lt;br /&gt;
# On successful transfer, the remote file is renamed to its final name (atomic rename — the remote system never sees a partial file).&lt;br /&gt;
# The local source file is moved to the backup directory.&lt;br /&gt;
# If the transfer fails, the file is moved to the error directory and an error is logged.&lt;br /&gt;
&lt;br /&gt;
=== GET (Download) ===&lt;br /&gt;
&lt;br /&gt;
# SFTPTransfer lists the remote directory every 10 seconds (configurable).&lt;br /&gt;
# Files matching the file mask are selected for download.&lt;br /&gt;
# Each file is downloaded to the local path using a &amp;lt;code&amp;gt;.tmp&amp;lt;/code&amp;gt; extension.&lt;br /&gt;
# On successful download, the local file is renamed to its final name.&lt;br /&gt;
# If configured, the remote file is deleted after download.&lt;br /&gt;
# A backup copy is optionally saved to the local backup directory.&lt;br /&gt;
&lt;br /&gt;
== Thread Architecture ==&lt;br /&gt;
&lt;br /&gt;
When running, SFTPTransfer maintains the following threads:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Thread !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| TransferPUT || One thread per enabled PUT profile, each managing its own SFTP connection.&lt;br /&gt;
|-&lt;br /&gt;
| TransferGET || One thread per enabled GET profile, each managing its own SFTP connection.&lt;br /&gt;
|-&lt;br /&gt;
| EmailThread || Sends error notification emails asynchronously.&lt;br /&gt;
|-&lt;br /&gt;
| ArchiveThread || Periodically purges backup files older than the configured retention period.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Hot Configuration Reload ==&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer supports a configuration reload mode (&amp;lt;code&amp;gt;Mode_CONFIG_UPDATE&amp;lt;/code&amp;gt;). When this mode is triggered, running threads re-read their configuration files without requiring a full service restart. This allows profile changes — such as updating a remote path or rotating credentials — to be applied with minimal disruption.&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
All activity is written to the Log4j log file. The log records:&lt;br /&gt;
&lt;br /&gt;
* Service startup and configuration loaded&lt;br /&gt;
* Each thread starting and its profile settings&lt;br /&gt;
* Every file detected, transfer attempted, and outcome&lt;br /&gt;
* Every remote connection attempt and disconnect&lt;br /&gt;
* File move operations (to backup or error directories)&lt;br /&gt;
* Errors and exceptions with full context&lt;br /&gt;
&lt;br /&gt;
Log rotation and retention are configured in the Log4j configuration file included in the distribution.&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Library !! Version !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| JSch || 2.27.9 || SSH/SFTP client&lt;br /&gt;
|-&lt;br /&gt;
| Bouncy Castle || current || Cryptographic provider for JSch&lt;br /&gt;
|-&lt;br /&gt;
| Apache Commons IO || current || WildcardFileFilter for local file matching&lt;br /&gt;
|-&lt;br /&gt;
| Log4j || 2.25.3 || Logging&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
See also: [[LabelServer4j]], [[Middleware4j]], [[Production Lines &amp;amp; Labellers]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=LabelServer4j_Example_User_Interface&amp;diff=1813</id>
		<title>LabelServer4j Example User Interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=LabelServer4j_Example_User_Interface&amp;diff=1813"/>
		<updated>2026-04-05T15:55:53Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;LabelServer4j is a headless background service — it has no graphical user interface. All interaction with the service is through configuration files, log files, and (on Windows) the Windows Services control panel.&lt;br /&gt;
&lt;br /&gt;
== Starting LabelServer4j ==&lt;br /&gt;
&lt;br /&gt;
=== Windows — Running as a Service ===&lt;br /&gt;
&lt;br /&gt;
The native install package includes &amp;lt;code&amp;gt;LabelServer.exe&amp;lt;/code&amp;gt;, a service-mode launcher that manages the Windows service directly. All commands must be run from an elevated command prompt (Run as Administrator).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Effect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /install&amp;lt;/code&amp;gt; || Register the service with automatic startup on boot&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /install-demand&amp;lt;/code&amp;gt; || Register the service with manual startup only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /start&amp;lt;/code&amp;gt; || Start the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /stop&amp;lt;/code&amp;gt; || Stop the service (waits for graceful shutdown)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /restart&amp;lt;/code&amp;gt; || Restart the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /status&amp;lt;/code&amp;gt; || Query status (exit code: 0 = running, 3 = stopped)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /uninstall&amp;lt;/code&amp;gt; || Remove the service registration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Once installed, the service also appears in the Windows Services management console (&amp;lt;code&amp;gt;services.msc&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Windows — Testing in a Console Window ===&lt;br /&gt;
&lt;br /&gt;
Before installing as a service, use the debug launcher to run LabelServer4j with all output visible in the console:&lt;br /&gt;
&lt;br /&gt;
 LabelServerDebug.exe&lt;br /&gt;
&lt;br /&gt;
This runs the same application code and is the most convenient way to verify that labellers connect and that the configuration is correct before committing to service deployment.&lt;br /&gt;
&lt;br /&gt;
=== Linux / macOS ===&lt;br /&gt;
&lt;br /&gt;
Start from the terminal using the provided shell script:&lt;br /&gt;
&lt;br /&gt;
 ./start_labeller.sh&lt;br /&gt;
&lt;br /&gt;
Or directly:&lt;br /&gt;
&lt;br /&gt;
 java -cp ./LabelServer.jar:./lib/devonly/i4jruntime.jar com.commander4j.labeller.Service&lt;br /&gt;
&lt;br /&gt;
The process runs in the foreground. Use a process manager (systemd, launchd, or nohup) for production deployment.&lt;br /&gt;
&lt;br /&gt;
== Monitoring ==&lt;br /&gt;
&lt;br /&gt;
Since there is no GUI, the primary monitoring tool is the log file:&lt;br /&gt;
&lt;br /&gt;
 logs/c4jLabelServer.log&lt;br /&gt;
&lt;br /&gt;
The log records every event in detail:&lt;br /&gt;
&lt;br /&gt;
* Service startup and configuration loading&lt;br /&gt;
* Each labeller thread starting&lt;br /&gt;
* Every CSV file detected and processed&lt;br /&gt;
* Every command sent to a printer and every response received&lt;br /&gt;
* File operations (upload, download, backup, delete)&lt;br /&gt;
* Errors and exceptions with full context&lt;br /&gt;
&lt;br /&gt;
Log files rotate at 10 MB and are retained for 14 days.&lt;br /&gt;
&lt;br /&gt;
=== What to Look For ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Situation !! What to check in the log&lt;br /&gt;
|-&lt;br /&gt;
| Label not printing || Look for the CSV filename being detected; if absent, check the input path in labellers.xml&lt;br /&gt;
|-&lt;br /&gt;
| Printer not responding || Look for TCP connection errors or timeout messages for that labeller&#039;s IP and port&lt;br /&gt;
|-&lt;br /&gt;
| Wrong data on label || Check the variable substitution log lines to see what values were sent&lt;br /&gt;
|-&lt;br /&gt;
| Script error || Look for the script line number and command that caused the failure&lt;br /&gt;
|-&lt;br /&gt;
| File stuck in input directory || File renamed to &amp;lt;code&amp;gt;.in&amp;lt;/code&amp;gt; means the script is running or failed — check for a &amp;lt;code&amp;gt;.error&amp;lt;/code&amp;gt; file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Configuration Changes ==&lt;br /&gt;
&lt;br /&gt;
To change a labeller&#039;s IP address, port, command script, or input path, edit the relevant &amp;lt;code&amp;gt;labellers.xml&amp;lt;/code&amp;gt; file and restart the service. Changes to configuration files are not picked up at runtime.&lt;br /&gt;
&lt;br /&gt;
To switch site, edit &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt; and change the &amp;lt;code&amp;gt;site id&amp;lt;/code&amp;gt; attribute, then restart.&lt;br /&gt;
&lt;br /&gt;
== Thread Architecture ==&lt;br /&gt;
&lt;br /&gt;
When running, LabelServer4j maintains the following threads:&lt;br /&gt;
&lt;br /&gt;
* One main service thread (lifecycle management)&lt;br /&gt;
* One server thread (configuration and orchestration)&lt;br /&gt;
* Per enabled labeller: one labeller thread, one TCP receive thread, one TCP transmit thread&lt;br /&gt;
&lt;br /&gt;
The thread count grows with the number of configured printers. A site with six printers typically runs around 20 threads in total.&lt;br /&gt;
&lt;br /&gt;
== Graceful Shutdown ==&lt;br /&gt;
&lt;br /&gt;
Sending a termination signal (Ctrl+C on Linux/macOS, or stopping the Windows service) triggers the shutdown hook. LabelServer4j signals all labeller threads to stop, waits for any in-progress print jobs to complete, then exits cleanly.&lt;br /&gt;
&lt;br /&gt;
See also: [[Overview LabelServer4j]], [[LabelServer4j Configuration]], [[LabelServer4j Operation]], [[Install Interface Services]]&lt;br /&gt;
&lt;br /&gt;
[[Category:LabelServer4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Installation_Middleware4j&amp;diff=1812</id>
		<title>Installation Middleware4j</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Installation_Middleware4j&amp;diff=1812"/>
		<updated>2026-04-05T15:55:52Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page covers deploying Middleware4j on a server or integration host.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Network access to any input or output directories defined in the map configuration (local paths, UNC shares, or mounted network drives)&lt;br /&gt;
* If using the EMAIL connector: network access to an SMTP server&lt;br /&gt;
* If using the SOCKET connector: network access to the target TCP/IP device&lt;br /&gt;
* Windows, Linux, or macOS&lt;br /&gt;
* Java 21 — required only when running from the distribution archive; the native install package bundles its own Java runtime&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Native install packages for Windows, macOS, and Linux are available from the [[Downloads]] page and are the preferred installation method. The installer creates the application directory, copies all configuration templates, and handles the Java runtime dependency automatically.&lt;br /&gt;
&lt;br /&gt;
Alternatively, a distribution archive can be extracted to a suitable directory, for example:&lt;br /&gt;
&lt;br /&gt;
 C:\Commander4j\Middleware4j\          (Windows)&lt;br /&gt;
 /opt/commander4j/middleware4j/        (Linux)&lt;br /&gt;
&lt;br /&gt;
The extracted directory contains:&lt;br /&gt;
&lt;br /&gt;
 c4jMiddleware.jar&lt;br /&gt;
 Middleware_Service.exe     (Windows — service launcher)&lt;br /&gt;
 Middleware_GUI.exe         (Windows — desktop GUI launcher)&lt;br /&gt;
 Encrypt_String.exe         (Windows — utility to encrypt passwords)&lt;br /&gt;
 start.cmd                  (Windows — fallback start script)&lt;br /&gt;
 start.sh                   (Linux/macOS — start script)&lt;br /&gt;
 xml/config/&lt;br /&gt;
 xslt/&lt;br /&gt;
 interface/&lt;br /&gt;
 logs/&lt;br /&gt;
 samples/&lt;br /&gt;
&lt;br /&gt;
== Configuration Before First Run ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Maps ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt; to define the transformation maps. Each map specifies one input connector, one or more output connectors, and optionally an XSLT stylesheet. See [[Maps]] for the full configuration reference.&lt;br /&gt;
&lt;br /&gt;
=== 2. XSLT Stylesheets ===&lt;br /&gt;
&lt;br /&gt;
Place any XSLT stylesheets used by your maps in the &amp;lt;code&amp;gt;xslt/&amp;lt;/code&amp;gt; directory. A library of over 60 sample stylesheets is included covering common integration scenarios with SAP, Sage, Tropos, B2MML, and others.&lt;br /&gt;
&lt;br /&gt;
=== 3. Email Notifications (Optional) ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;xml/config/email.xml&amp;lt;/code&amp;gt; with your SMTP server details and recipient addresses for error notifications.&lt;br /&gt;
&lt;br /&gt;
=== 4. Password Encryption ===&lt;br /&gt;
&lt;br /&gt;
Any passwords stored in configuration files (SMTP, database connections) must be AES-encrypted. Use the included &amp;lt;code&amp;gt;Encrypt_String.exe&amp;lt;/code&amp;gt; utility (Windows) to generate encrypted values. On Linux/macOS, use the equivalent utility from the Commander4j installation.&lt;br /&gt;
&lt;br /&gt;
== Installing as a Windows Service ==&lt;br /&gt;
&lt;br /&gt;
The native install package includes &amp;lt;code&amp;gt;Middleware_Service.exe&amp;lt;/code&amp;gt;, a service-mode launcher built with install4j. This executable manages the Windows service directly — no additional wrapper (such as WinSW) is required.&lt;br /&gt;
&lt;br /&gt;
All service commands must be run from an elevated command prompt (Run as Administrator).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Effect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Middleware_Service.exe /install&amp;lt;/code&amp;gt; || Register the Windows service with automatic startup on boot&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Middleware_Service.exe /install-demand&amp;lt;/code&amp;gt; || Register the service with manual startup only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Middleware_Service.exe /start&amp;lt;/code&amp;gt; || Start the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Middleware_Service.exe /stop&amp;lt;/code&amp;gt; || Stop the service (waits for graceful shutdown)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Middleware_Service.exe /restart&amp;lt;/code&amp;gt; || Restart the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Middleware_Service.exe /status&amp;lt;/code&amp;gt; || Query status (exit code: 0 = running, 3 = stopped)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Middleware_Service.exe /uninstall&amp;lt;/code&amp;gt; || Remove the service registration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Once installed, the service also appears in the Windows Services management console (&amp;lt;code&amp;gt;services.msc&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Testing Before Installing as a Service ===&lt;br /&gt;
&lt;br /&gt;
Before committing to service installation, run Middleware4j in desktop GUI mode using:&lt;br /&gt;
&lt;br /&gt;
 Middleware_GUI.exe&lt;br /&gt;
&lt;br /&gt;
This launches a desktop window showing all configured maps, their current status, and real-time message counts. Use this mode to confirm that maps are reading from the correct input directories and that XSLT transformations produce the expected output. Once satisfied, switch to service mode for production deployment.&lt;br /&gt;
&lt;br /&gt;
== Starting on Linux / macOS ==&lt;br /&gt;
&lt;br /&gt;
Use the provided shell script:&lt;br /&gt;
&lt;br /&gt;
 ./start.sh&lt;br /&gt;
&lt;br /&gt;
The mode (GUI or Service) is passed as an argument by the script. The process runs in the foreground. For production deployment, use systemd, launchd, or nohup to manage it as a background process.&lt;br /&gt;
&lt;br /&gt;
== Verifying the Installation ==&lt;br /&gt;
&lt;br /&gt;
After starting Middleware4j:&lt;br /&gt;
&lt;br /&gt;
# Check &amp;lt;code&amp;gt;logs/&amp;lt;/code&amp;gt; for startup messages confirming that each map thread has initialised.&lt;br /&gt;
# Place a test input file in the input directory of one of the configured maps.&lt;br /&gt;
# Confirm the file is consumed and the expected output appears in the output directory.&lt;br /&gt;
# Check &amp;lt;code&amp;gt;interface/log/&amp;lt;/code&amp;gt; for the message transaction record.&lt;br /&gt;
&lt;br /&gt;
== Log Files ==&lt;br /&gt;
&lt;br /&gt;
All activity is written to the Log4j log file in the &amp;lt;code&amp;gt;logs/&amp;lt;/code&amp;gt; directory. Log rotation and retention are configured in &amp;lt;code&amp;gt;xml/config/log4j2.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
See also: [[Overview_Middleware4j]], [[Maps]], [[Connectors]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Middleware4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Installation_LabelServer4j&amp;diff=1811</id>
		<title>Installation LabelServer4j</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Installation_LabelServer4j&amp;diff=1811"/>
		<updated>2026-04-05T15:55:35Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page covers deploying LabelServer4j on a server or PC connected to the production network.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Network access to each label printer (TCP/IP — Zebra port 9100, Logopak port 9100 or as configured)&lt;br /&gt;
* Network access to the Commander4j server (to receive CSV request files)&lt;br /&gt;
* Windows, Linux, or macOS&lt;br /&gt;
* Java 21 — required only when running from the distribution archive; the native install package bundles its own Java runtime&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Native install packages for Windows, macOS, and Linux are available from the [[Downloads]] page and are the preferred installation method. The installer creates the application directory, copies all configuration templates, and handles the Java runtime dependency automatically.&lt;br /&gt;
&lt;br /&gt;
Alternatively, a distribution archive can be extracted to a suitable directory, for example:&lt;br /&gt;
&lt;br /&gt;
 C:\Commander4j\LabelServer4j\          (Windows)&lt;br /&gt;
 /opt/commander4j/labelserver4j/        (Linux)&lt;br /&gt;
&lt;br /&gt;
The extracted directory contains:&lt;br /&gt;
&lt;br /&gt;
 LabelServer.jar&lt;br /&gt;
 LabelServer.exe           (Windows — service launcher)&lt;br /&gt;
 LabelServerDebug.exe      (Windows — console launcher for testing)&lt;br /&gt;
 start_labeller.cmd        (Windows — fallback start script)&lt;br /&gt;
 start_labeller.sh         (Linux/macOS — start script)&lt;br /&gt;
 lib/&lt;br /&gt;
 xml/config/&lt;br /&gt;
 labeller_files/&lt;br /&gt;
 labeller_requests/&lt;br /&gt;
 labeller_cmd/&lt;br /&gt;
 labeller_backups/&lt;br /&gt;
 logs/&lt;br /&gt;
&lt;br /&gt;
== Configuration Before First Run ==&lt;br /&gt;
&lt;br /&gt;
Before starting LabelServer4j, complete the following configuration steps.&lt;br /&gt;
&lt;br /&gt;
=== 1. Site and Labeller Definitions ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt; to set the active site identifier. Then create or edit the &amp;lt;code&amp;gt;labellers.xml&amp;lt;/code&amp;gt; file for that site in &amp;lt;code&amp;gt;xml/config/&amp;lt;/code&amp;gt;. Each labeller entry defines:&lt;br /&gt;
&lt;br /&gt;
* The labeller name (must match the name used in Commander4j)&lt;br /&gt;
* The printer IP address and TCP port&lt;br /&gt;
* The path to the command script&lt;br /&gt;
* The input directory where Commander4j writes CSV files&lt;br /&gt;
&lt;br /&gt;
See [[LabelServer4j Configuration]] for the full XML structure.&lt;br /&gt;
&lt;br /&gt;
=== 2. Command Scripts ===&lt;br /&gt;
&lt;br /&gt;
Place the command script files (plain text &amp;lt;code&amp;gt;.txt&amp;lt;/code&amp;gt; files) for each labeller in the &amp;lt;code&amp;gt;labeller_cmd/&amp;lt;/code&amp;gt; directory. The script filename is referenced in &amp;lt;code&amp;gt;labellers.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 3. Label Files (Logopak only) ===&lt;br /&gt;
&lt;br /&gt;
If using Logopak printers with stored label templates, place the binary label files in the appropriate subdirectory of &amp;lt;code&amp;gt;labeller_files/&amp;lt;/code&amp;gt;. LabelServer4j can upload these to the printer using the &amp;lt;code&amp;gt;SEND_FILE_INTELHEX&amp;lt;/code&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
=== 4. Database Connection (Optional) ===&lt;br /&gt;
&lt;br /&gt;
If the command scripts use &amp;lt;code&amp;gt;DB_QUERY&amp;lt;/code&amp;gt; to enrich label data from the Commander4j database, configure the database connection in &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt; with the JDBC URL, username, and AES-encrypted password.&lt;br /&gt;
&lt;br /&gt;
=== 5. Email Notifications (Optional) ===&lt;br /&gt;
&lt;br /&gt;
To receive alerts on print failures or service events, configure &amp;lt;code&amp;gt;xml/config/email.xml&amp;lt;/code&amp;gt; with SMTP server details and recipient addresses.&lt;br /&gt;
&lt;br /&gt;
== Installing as a Windows Service ==&lt;br /&gt;
&lt;br /&gt;
The native install package includes &amp;lt;code&amp;gt;LabelServer.exe&amp;lt;/code&amp;gt;, a service-mode launcher built with install4j. This executable manages the Windows service directly — no additional wrapper (such as WinSW) is required.&lt;br /&gt;
&lt;br /&gt;
All service commands must be run from an elevated command prompt (Run as Administrator).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Effect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /install&amp;lt;/code&amp;gt; || Register the Windows service with automatic startup on boot&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /install-demand&amp;lt;/code&amp;gt; || Register the service with manual startup only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /start&amp;lt;/code&amp;gt; || Start the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /stop&amp;lt;/code&amp;gt; || Stop the service (waits for graceful shutdown)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /restart&amp;lt;/code&amp;gt; || Restart the service&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /status&amp;lt;/code&amp;gt; || Query status (exit code: 0 = running, 3 = stopped)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LabelServer.exe /uninstall&amp;lt;/code&amp;gt; || Remove the service registration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Once installed, the service also appears in the Windows Services management console (&amp;lt;code&amp;gt;services.msc&amp;lt;/code&amp;gt;) and can be started and stopped from there.&lt;br /&gt;
&lt;br /&gt;
=== Testing Before Installing as a Service ===&lt;br /&gt;
&lt;br /&gt;
Before committing to service installation, run LabelServer4j in a visible console window using the debug launcher:&lt;br /&gt;
&lt;br /&gt;
 LabelServerDebug.exe&lt;br /&gt;
&lt;br /&gt;
This runs the same application code with all log output written to the console window. Use this mode to confirm that labellers connect to their printers and that the configuration is correct before installing as a service.&lt;br /&gt;
&lt;br /&gt;
== Starting on Linux / macOS ==&lt;br /&gt;
&lt;br /&gt;
Use the provided shell script:&lt;br /&gt;
&lt;br /&gt;
 ./start_labeller.sh&lt;br /&gt;
&lt;br /&gt;
Or directly:&lt;br /&gt;
&lt;br /&gt;
 java -cp ./LabelServer.jar:./lib/devonly/i4jruntime.jar com.commander4j.labeller.Service&lt;br /&gt;
&lt;br /&gt;
The process runs in the foreground. For production deployment, use a process manager (systemd, launchd, or nohup) to run it as a background service.&lt;br /&gt;
&lt;br /&gt;
== Verifying the Installation ==&lt;br /&gt;
&lt;br /&gt;
After starting LabelServer4j:&lt;br /&gt;
&lt;br /&gt;
# Check &amp;lt;code&amp;gt;logs/c4jLabelServer.log&amp;lt;/code&amp;gt; — there should be startup and thread initialisation messages.&lt;br /&gt;
# Verify that each labeller thread reports a successful TCP connection to its printer.&lt;br /&gt;
# Place a test CSV file in a labeller&#039;s input directory to trigger an end-to-end print cycle.&lt;br /&gt;
# Confirm the CSV file is consumed (deleted on success, or moved to the error directory on failure).&lt;br /&gt;
&lt;br /&gt;
== Log Files ==&lt;br /&gt;
&lt;br /&gt;
All activity is written to &amp;lt;code&amp;gt;logs/c4jLabelServer.log&amp;lt;/code&amp;gt;. Log files rotate at 10 MB and are retained for 14 days.&lt;br /&gt;
&lt;br /&gt;
See also: [[Overview LabelServer4j]], [[LabelServer4j Operation]], [[LabelServer4j Configuration]], [[LabelServer4j Example User Interface]]&lt;br /&gt;
&lt;br /&gt;
[[Category:LabelServer4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=AutoLab4j_Folder_Structure&amp;diff=1810</id>
		<title>AutoLab4j Folder Structure</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=AutoLab4j_Folder_Structure&amp;diff=1810"/>
		<updated>2026-04-01T15:28:46Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the directory layout of an AutoLab4j installation and the purpose of each folder.&lt;br /&gt;
&lt;br /&gt;
== Directory Layout ==&lt;br /&gt;
&lt;br /&gt;
 AutoLab4j/&lt;br /&gt;
 ├── AutoLab.jar&lt;br /&gt;
 ├── lib/&lt;br /&gt;
 ├── xml/&lt;br /&gt;
 │   ├── config/&lt;br /&gt;
 │   │   ├── config.xml&lt;br /&gt;
 │   │   ├── email.xml&lt;br /&gt;
 │   │   └── log4j2.xml&lt;br /&gt;
 │   └── sscc/&lt;br /&gt;
 │       └── PRINTER NAME.xml&lt;br /&gt;
 ├── labels/&lt;br /&gt;
 ├── interface/&lt;br /&gt;
 │   ├── input/&lt;br /&gt;
 │   │   └── dataset/&lt;br /&gt;
 │   └── output/&lt;br /&gt;
 │       └── ProdDec/&lt;br /&gt;
 ├── remote_dataset/&lt;br /&gt;
 ├── remote_labels/&lt;br /&gt;
 ├── labelary/&lt;br /&gt;
 ├── logs/&lt;br /&gt;
 └── running/&lt;br /&gt;
&lt;br /&gt;
== File and Folder Descriptions ==&lt;br /&gt;
&lt;br /&gt;
=== AutoLab.jar ===&lt;br /&gt;
&lt;br /&gt;
The main application JAR. When running from the distribution archive, start AutoLab4j with &amp;lt;code&amp;gt;java -jar AutoLab.jar&amp;lt;/code&amp;gt;. If installed using the native package, use the shortcut or service entry created by the installer.&lt;br /&gt;
&lt;br /&gt;
=== lib/ ===&lt;br /&gt;
&lt;br /&gt;
Third-party library JARs required by AutoLab4j (referenced in the JAR manifest classpath). Do not modify this directory.&lt;br /&gt;
&lt;br /&gt;
=== xml/config/config.xml ===&lt;br /&gt;
&lt;br /&gt;
The main configuration file. Defines production lines, Modbus connection details, pallet quantities, batch format patterns, and file paths. See [[AutoLab4j Configuration]] for the full structure.&lt;br /&gt;
&lt;br /&gt;
=== xml/config/email.xml ===&lt;br /&gt;
&lt;br /&gt;
SMTP and distribution list settings for email notifications. Used for SSCC warning alerts and service start/stop notifications.&lt;br /&gt;
&lt;br /&gt;
=== xml/config/log4j2.xml ===&lt;br /&gt;
&lt;br /&gt;
Log4j2 logging configuration. Controls log file location, rotation size, and retention period.&lt;br /&gt;
&lt;br /&gt;
=== xml/sscc/ ===&lt;br /&gt;
&lt;br /&gt;
Contains one XML sequence file per printer, named after the printer (for example &amp;lt;code&amp;gt;PRINTER 1.xml&amp;lt;/code&amp;gt;). Each file stores the current SSCC prefix, sequence number, check digit, warning limit, and upper limit. AutoLab4j reads and updates these files atomically each time a new SSCC is generated. Back up this directory regularly — it records how far through the SSCC sequence each printer has progressed.&lt;br /&gt;
&lt;br /&gt;
=== labels/ ===&lt;br /&gt;
&lt;br /&gt;
ZPL label template files. The filename of the template to use for each order is specified in the &amp;lt;code&amp;gt;REPORT_FILENAME&amp;lt;/code&amp;gt; field of the CSV dataset file. Templates contain ZPL commands with field placeholders such as &amp;lt;code&amp;gt;&amp;amp;lt;*MATERIAL*&amp;amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;amp;lt;*SSCC*&amp;amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== interface/input/dataset/ ===&lt;br /&gt;
&lt;br /&gt;
The directory AutoLab4j monitors for incoming CSV dataset files from Commander4j. When Commander4j assigns a process order to a production line, it writes a CSV file here named &amp;lt;code&amp;gt;LINE_NAME_PRINTER_NAME.CSV&amp;lt;/code&amp;gt;. This directory is configured as &amp;lt;code&amp;gt;dataSet path&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== interface/output/ProdDec/ ===&lt;br /&gt;
&lt;br /&gt;
Production Declaration XML files are written here after each pallet is printed — one file per SSCC. These files record the SSCC, product, batch, shelf life, and other details for downstream integration. This directory is configured as &amp;lt;code&amp;gt;output path&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== remote_dataset/ ===&lt;br /&gt;
&lt;br /&gt;
An optional secondary location for CSV dataset files, used when the dataset files are delivered from a remote source and need to be synchronised locally before processing. Configured as &amp;lt;code&amp;gt;dataSet path&amp;lt;/code&amp;gt; if remote synchronisation is in use.&lt;br /&gt;
&lt;br /&gt;
=== remote_labels/ ===&lt;br /&gt;
&lt;br /&gt;
An optional source directory for label template files. The LabelSync thread copies label files from this directory into &amp;lt;code&amp;gt;labels/&amp;lt;/code&amp;gt; at a configurable interval. Used when label templates are maintained centrally and need to be distributed to multiple AutoLab4j instances. Configured as &amp;lt;code&amp;gt;labelSync path&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== labelary/ ===&lt;br /&gt;
&lt;br /&gt;
Cache directory for label preview images fetched from the Labelary API. Each ZPL label that is previewed produces a PNG file here. The cache is used to avoid re-fetching the same label image on repeat prints.&lt;br /&gt;
&lt;br /&gt;
=== logs/ ===&lt;br /&gt;
&lt;br /&gt;
Application log files. The main log file is &amp;lt;code&amp;gt;AutoLab.log&amp;lt;/code&amp;gt;. Log files rotate at 10 MB and are retained for 14 days. Review this directory when diagnosing Modbus connection issues, print failures, or SSCC sequence problems.&lt;br /&gt;
&lt;br /&gt;
=== running/ ===&lt;br /&gt;
&lt;br /&gt;
Temporary runtime flag files created by AutoLab4j while it is running. These files are created on startup and removed on clean shutdown. If they remain after an unexpected exit, AutoLab4j will clear them on the next start. Do not modify or delete these files while the service is running.&lt;br /&gt;
&lt;br /&gt;
See also: [[AutoLab4j Configuration]], [[Installation AutoLab4j]], [[Overview AutoLab4j]]&lt;br /&gt;
&lt;br /&gt;
[[Category:AutoLab4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Installation_AutoLab4j&amp;diff=1809</id>
		<title>Installation AutoLab4j</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Installation_AutoLab4j&amp;diff=1809"/>
		<updated>2026-04-01T15:28:45Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page covers deploying AutoLab4j on a server or PC connected to the production network.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Network access to the Modbus I/O device on each production line (TCP port 502 by default)&lt;br /&gt;
* Network access to each Zebra printer (TCP port 9100)&lt;br /&gt;
* Network access to the Commander4j server (to receive CSV dataset files)&lt;br /&gt;
* Windows, Linux, or macOS&lt;br /&gt;
* Java 21 (JRE or JDK) — required only when running from the distribution archive; the native install package bundles its own Java runtime&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Native install packages for Windows, macOS, and Linux are available from the [[Downloads]] page and are the preferred installation method. The installer creates the application directory, registers it with the operating system, and handles the Java runtime dependency automatically.&lt;br /&gt;
&lt;br /&gt;
Alternatively, a distribution archive can be downloaded from the [[Downloads]] page and extracted to a suitable directory, for example:&lt;br /&gt;
&lt;br /&gt;
 C:\Commander4j\AutoLab4j\          (Windows)&lt;br /&gt;
 /opt/commander4j/autolab4j/        (Linux)&lt;br /&gt;
&lt;br /&gt;
The extracted directory contains:&lt;br /&gt;
&lt;br /&gt;
 AutoLab.jar&lt;br /&gt;
 lib/&lt;br /&gt;
 xml/&lt;br /&gt;
 labels/&lt;br /&gt;
 logs/&lt;br /&gt;
 interface/&lt;br /&gt;
 running/&lt;br /&gt;
&lt;br /&gt;
== Configuration Before First Run ==&lt;br /&gt;
&lt;br /&gt;
Before starting AutoLab4j, complete the following configuration steps.&lt;br /&gt;
&lt;br /&gt;
=== 1. Production Lines ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt; and define each production line. For each line you need:&lt;br /&gt;
&lt;br /&gt;
* The Modbus device IP address and port&lt;br /&gt;
* The coil address that signals a pallet complete event&lt;br /&gt;
* The coil address for semi-pallet detection&lt;br /&gt;
* The printer name (must match the name used in Commander4j)&lt;br /&gt;
&lt;br /&gt;
See [[AutoLab4j Configuration]] for the full XML structure.&lt;br /&gt;
&lt;br /&gt;
=== 2. SSCC Sequence Files ===&lt;br /&gt;
&lt;br /&gt;
Create one SSCC sequence file per printer in &amp;lt;code&amp;gt;xml/sscc/&amp;lt;/code&amp;gt;. The filename must match the printer name configured in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;. For example, for a printer named &amp;lt;code&amp;gt;PRINTER 1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 xml/sscc/PRINTER 1.xml&lt;br /&gt;
&lt;br /&gt;
The file must contain the SSCC prefix, starting sequence number, warning limit, and upper limit. Your GS1 member organisation will provide the prefix. Example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;lt;sscc&amp;gt;&lt;br /&gt;
   &amp;lt;prefix&amp;gt;384133182&amp;lt;/prefix&amp;gt;&lt;br /&gt;
   &amp;lt;sequence&amp;gt;00000001&amp;lt;/sequence&amp;gt;&lt;br /&gt;
   &amp;lt;checkDigit&amp;gt;0&amp;lt;/checkDigit&amp;gt;&lt;br /&gt;
   &amp;lt;upperlimit&amp;gt;00009999&amp;lt;/upperlimit&amp;gt;&lt;br /&gt;
   &amp;lt;warninglimit&amp;gt;00009000&amp;lt;/warninglimit&amp;gt;&lt;br /&gt;
 &amp;lt;/sscc&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Label Templates ===&lt;br /&gt;
&lt;br /&gt;
Copy the ZPL label template files into the &amp;lt;code&amp;gt;labels/&amp;lt;/code&amp;gt; directory. The filename for each template is specified in the CSV dataset file in the &amp;lt;code&amp;gt;REPORT_FILENAME&amp;lt;/code&amp;gt; field. See [[Zebra ZPL Label]] for information on ZPL label authoring.&lt;br /&gt;
&lt;br /&gt;
=== 4. Dataset Directory ===&lt;br /&gt;
&lt;br /&gt;
Ensure the directory configured as &amp;lt;code&amp;gt;dataSet path&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt; is accessible. This is where Commander4j writes the CSV files when an operator assigns a process order to a labeller. The directory can be a local path or a network share.&lt;br /&gt;
&lt;br /&gt;
=== 5. Output Directory ===&lt;br /&gt;
&lt;br /&gt;
Ensure the directory configured as &amp;lt;code&amp;gt;output path&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt; exists and is writable. AutoLab4j writes Production Declaration XML files here after each pallet is printed.&lt;br /&gt;
&lt;br /&gt;
=== 6. Email Notifications (Optional) ===&lt;br /&gt;
&lt;br /&gt;
If you want email alerts for SSCC warnings and service start/stop events, configure &amp;lt;code&amp;gt;xml/config/email.xml&amp;lt;/code&amp;gt; with your SMTP server details and distribution lists.&lt;br /&gt;
&lt;br /&gt;
== Starting AutoLab4j ==&lt;br /&gt;
&lt;br /&gt;
If you installed using the native package, start AutoLab4j using the shortcut or service entry created by the installer.&lt;br /&gt;
&lt;br /&gt;
If running from the distribution archive:&lt;br /&gt;
&lt;br /&gt;
=== Windows ===&lt;br /&gt;
&lt;br /&gt;
 java -jar AutoLab.jar&lt;br /&gt;
&lt;br /&gt;
AutoLab4j can be installed as a Windows service using a wrapper such as WinSW so that it starts automatically on boot.&lt;br /&gt;
&lt;br /&gt;
=== Linux / macOS ===&lt;br /&gt;
&lt;br /&gt;
 java -jar AutoLab.jar&lt;br /&gt;
&lt;br /&gt;
Use systemd, launchd, or nohup for production deployment.&lt;br /&gt;
&lt;br /&gt;
When running, AutoLab4j appears in the system tray with one icon per production line. The System Log window shows startup progress.&lt;br /&gt;
&lt;br /&gt;
== Exclusive Runtime ==&lt;br /&gt;
&lt;br /&gt;
AutoLab4j uses a TCP port (default: 8000) as an exclusive runtime lock. Only one instance can run at a time. If you start a second instance, it sends a shutdown signal to the running instance and waits for it to stop before starting. The watchdog port can be changed in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Verifying the Installation ==&lt;br /&gt;
&lt;br /&gt;
After starting AutoLab4j:&lt;br /&gt;
&lt;br /&gt;
# Check the system tray — there should be one icon per enabled production line.&lt;br /&gt;
# Open the System Log window (right-click the system tray icon).&lt;br /&gt;
# Verify that each production line shows a Modbus connection attempt in its log window.&lt;br /&gt;
# Place a test CSV file in the dataset directory and trigger the Modbus coil to confirm end-to-end operation.&lt;br /&gt;
&lt;br /&gt;
== Log Files ==&lt;br /&gt;
&lt;br /&gt;
All activity is written to &amp;lt;code&amp;gt;logs/AutoLab.log&amp;lt;/code&amp;gt;. Log files rotate at 10 MB and are retained for 14 days. Review this file if any production line fails to connect or if labels are not printing.&lt;br /&gt;
&lt;br /&gt;
See also: [[AutoLab4j Configuration]], [[Overview AutoLab4j]], [[AutoLab4j Operation]]&lt;br /&gt;
&lt;br /&gt;
[[Category:AutoLab4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=XML_Viewer&amp;diff=1808</id>
		<title>XML Viewer</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=XML_Viewer&amp;diff=1808"/>
		<updated>2026-04-01T15:28:44Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;XML Viewer is a desktop application for exploring XML documents as an interactive, expandable tree. It supports configurable display modes, multi-language element name translation, and adjustable tree expansion depth. It is designed for viewing structured XML files such as SAP IDoc messages, Commander4j configuration files, and production schedule exports.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
XML Viewer makes it practical to inspect complex XML files that are difficult to read as raw text. Element names can be translated into plain-language descriptions (for example, the SAP field code &amp;lt;code&amp;gt;ABWKZ&amp;lt;/code&amp;gt; becomes &amp;quot;Deviation indicator&amp;quot; in the English translation), and the tree can be expanded to a specific depth to give a high-level overview without showing every leaf value.&lt;br /&gt;
&lt;br /&gt;
== Running XML Viewer ==&lt;br /&gt;
&lt;br /&gt;
Native install packages for Windows, macOS, and Linux are available from the [[Downloads]] page and are the preferred installation method.&lt;br /&gt;
&lt;br /&gt;
Alternatively, XML Viewer can be run directly from the distribution archive. It is a Java 21 desktop (Swing) application:&lt;br /&gt;
&lt;br /&gt;
 java -jar xmlviewer.jar [optional path to XML file]&lt;br /&gt;
&lt;br /&gt;
If a file path is provided on the command line, that file is opened immediately on launch. Otherwise, the last-opened file from the configuration is loaded.&lt;br /&gt;
&lt;br /&gt;
== Loading a Document ==&lt;br /&gt;
&lt;br /&gt;
Click the &#039;&#039;&#039;Open XML Document&#039;&#039;&#039; button in the right sidebar, or pass a file path on the command line. Only well-formed XML files are supported. Click &#039;&#039;&#039;Reload XML Document&#039;&#039;&#039; to re-read the current file after it has been changed externally.&lt;br /&gt;
&lt;br /&gt;
== Display Modes ==&lt;br /&gt;
&lt;br /&gt;
=== Standard Mode ===&lt;br /&gt;
&lt;br /&gt;
The XML hierarchy is displayed exactly as it appears in the file — elements nest within their parent elements, forming a tree that mirrors the XML structure.&lt;br /&gt;
&lt;br /&gt;
=== Flat Mode ===&lt;br /&gt;
&lt;br /&gt;
Leaf elements (those containing only text, no child elements) are collapsed into their parent&#039;s row rather than appearing as separate tree nodes. Only elements that contain child elements appear as tree nodes. This produces a more compact view of documents with many small leaf values.&lt;br /&gt;
&lt;br /&gt;
Toggle between modes using the &#039;&#039;&#039;View Mode&#039;&#039;&#039; button in the right sidebar.&lt;br /&gt;
&lt;br /&gt;
== Tree Expansion Control ==&lt;br /&gt;
&lt;br /&gt;
The top toolbar provides four buttons:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Expand All&#039;&#039;&#039; — expand every node in the tree&lt;br /&gt;
* &#039;&#039;&#039;Expand Selected&#039;&#039;&#039; — expand only the selected subtree&lt;br /&gt;
* &#039;&#039;&#039;Collapse Selected&#039;&#039;&#039; — collapse the selected subtree&lt;br /&gt;
* &#039;&#039;&#039;Collapse All&#039;&#039;&#039; — collapse everything to root level&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;−&#039;&#039;&#039; and &#039;&#039;&#039;+&#039;&#039;&#039; buttons in the toolbar adjust the current expansion level (shown as a number between the buttons). Clicking &#039;&#039;&#039;Refresh&#039;&#039;&#039; after changing the level re-expands the tree to that depth.&lt;br /&gt;
&lt;br /&gt;
The expansion level is saved in the configuration and restored on next launch.&lt;br /&gt;
&lt;br /&gt;
== Translation ==&lt;br /&gt;
&lt;br /&gt;
XML Viewer can replace technical XML element names and values with plain-language descriptions from a translation file.&lt;br /&gt;
&lt;br /&gt;
=== Enabling Translation ===&lt;br /&gt;
&lt;br /&gt;
Toggle translations using the &#039;&#039;&#039;View Translations&#039;&#039;&#039; button. The &#039;&#039;&#039;Translation&#039;&#039;&#039; dropdown at the bottom of the window selects which translation file to use. The &#039;&#039;&#039;Language&#039;&#039;&#039; dropdown selects the language within that file.&lt;br /&gt;
&lt;br /&gt;
=== Built-in Translation Files ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! File !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| matmas05.xml || SAP MATMAS05 IDoc field translations&lt;br /&gt;
|-&lt;br /&gt;
| zmatmas03.xml || SAP ZMATMAS03 IDoc field translations&lt;br /&gt;
|-&lt;br /&gt;
| productionschedule.xml || Production schedule export field translations&lt;br /&gt;
|-&lt;br /&gt;
| config.xml || Commander4j configuration element translations&lt;br /&gt;
|-&lt;br /&gt;
| default.xml || Generic fallback translations&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Languages ===&lt;br /&gt;
&lt;br /&gt;
The default installation includes English, French, German, and Italian. The active language can be changed at any time from the Language dropdown.&lt;br /&gt;
&lt;br /&gt;
=== Adding Translations ===&lt;br /&gt;
&lt;br /&gt;
Translation files are XML documents located in &amp;lt;code&amp;gt;xml/translations/&amp;lt;/code&amp;gt;. Each file maps element names, attribute names, element values, and attribute values to their translated equivalents for each language. Elements without a translation entry are shown using their original name from the XML file.&lt;br /&gt;
&lt;br /&gt;
== Other Display Options ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Button !! Effect&lt;br /&gt;
|-&lt;br /&gt;
| View Icons || Show or hide the icon column next to each tree node&lt;br /&gt;
|-&lt;br /&gt;
| View Brackets || Wrap element values in &amp;lt;code&amp;gt;[ ]&amp;lt;/code&amp;gt; brackets to distinguish them from element names&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== config.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt;. Stores the last-opened file path, selected translation file, selected language, current expansion level, and the state of all four display toggles (mode, translations, brackets, icons). Updated automatically on exit.&lt;br /&gt;
&lt;br /&gt;
=== log4j2.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/log/log4j2.xml&amp;lt;/code&amp;gt;. Controls logging to &amp;lt;code&amp;gt;logs/XML_View.log&amp;lt;/code&amp;gt;. Log files rotate at 10 MB and are retained for 14 days.&lt;br /&gt;
&lt;br /&gt;
=== fonts.xml / icons ===&lt;br /&gt;
&lt;br /&gt;
Icons are loaded from &amp;lt;code&amp;gt;images/xmlIcons/&amp;lt;/code&amp;gt;. If an icon file referenced by a translation is not found, the icon column is left blank for that element without an error.&lt;br /&gt;
&lt;br /&gt;
See also: [[TreeDoc]], [[Middleware4j]], [[Label Template Syntax]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=TreeDoc&amp;diff=1807</id>
		<title>TreeDoc</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=TreeDoc&amp;diff=1807"/>
		<updated>2026-04-01T15:28:43Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TreeDoc is a desktop utility that generates an ASCII directory tree from a folder you select and displays it in a scrollable text window. The output can be copied to the clipboard or saved as a plain text file.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
TreeDoc is useful for producing a human-readable snapshot of a folder structure — for example, documenting a Commander4j installation layout, comparing the contents of two directories, or quickly exploring an unfamiliar project. The output uses box-drawing characters (├──, └──, │) to show the hierarchy clearly in any monospace environment.&lt;br /&gt;
&lt;br /&gt;
== Running TreeDoc ==&lt;br /&gt;
&lt;br /&gt;
Native install packages for Windows, macOS, and Linux are available from the [[Downloads]] page and are the preferred installation method.&lt;br /&gt;
&lt;br /&gt;
Alternatively, TreeDoc can be run directly from the distribution archive. It is a Java 21 desktop (Swing) application:&lt;br /&gt;
&lt;br /&gt;
 java -jar Tree.jar&lt;br /&gt;
&lt;br /&gt;
The window opens at 900 × 750 pixels.&lt;br /&gt;
&lt;br /&gt;
== Generating a Tree ==&lt;br /&gt;
&lt;br /&gt;
# Click &#039;&#039;&#039;Browse&#039;&#039;&#039; to choose the root folder, or type a path directly into the folder field.&lt;br /&gt;
# Adjust &#039;&#039;&#039;Max Depth&#039;&#039;&#039; and &#039;&#039;&#039;Max Entries&#039;&#039;&#039; if needed (see below).&lt;br /&gt;
# Check &#039;&#039;&#039;Include Files&#039;&#039;&#039; if you want files shown alongside directories.&lt;br /&gt;
# Click &#039;&#039;&#039;Refresh&#039;&#039;&#039; to generate the tree.&lt;br /&gt;
&lt;br /&gt;
The output appears in the central text area. The status bar at the bottom shows the total number of entries printed, and indicates if the output was truncated.&lt;br /&gt;
&lt;br /&gt;
== Options ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Option !! Default !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Max Depth || 9999 || Maximum folder depth to traverse. Set to a small number (e.g. 3) to get a high-level overview of a deep tree.&lt;br /&gt;
|-&lt;br /&gt;
| Max Entries || 10,000 || Maximum number of lines to print. Prevents the output from becoming unmanageable for very large trees.&lt;br /&gt;
|-&lt;br /&gt;
| Include Files || Off || When off, only directory names are shown. When on, files are listed inside their parent directory.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Output Format ==&lt;br /&gt;
&lt;br /&gt;
The output is plain UTF-8 text using box-drawing characters:&lt;br /&gt;
&lt;br /&gt;
 project/&lt;br /&gt;
 ├── src/&lt;br /&gt;
 │   ├── main/&lt;br /&gt;
 │   └── test/&lt;br /&gt;
 ├── docs/&lt;br /&gt;
 └── build.xml&lt;br /&gt;
&lt;br /&gt;
Directories are always included. Files appear indented under their parent directory when &#039;&#039;&#039;Include Files&#039;&#039;&#039; is enabled.&lt;br /&gt;
&lt;br /&gt;
=== What is Excluded ===&lt;br /&gt;
&lt;br /&gt;
The following are always omitted regardless of settings:&lt;br /&gt;
&lt;br /&gt;
* Hidden files and folders (system hidden flag)&lt;br /&gt;
* &amp;lt;code&amp;gt;.DS_Store&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.localized&amp;lt;/code&amp;gt; (macOS metadata)&lt;br /&gt;
* &amp;lt;code&amp;gt;.app&amp;lt;/code&amp;gt; bundles (macOS application packages)&lt;br /&gt;
* Symbolic links (skipped to prevent infinite loops)&lt;br /&gt;
&lt;br /&gt;
== Saving and Copying Output ==&lt;br /&gt;
&lt;br /&gt;
The right sidebar provides:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Save&#039;&#039;&#039; — save the output as a &amp;lt;code&amp;gt;.txt&amp;lt;/code&amp;gt; file (default filename: &amp;lt;code&amp;gt;tree.txt&amp;lt;/code&amp;gt;, UTF-8 encoded)&lt;br /&gt;
* &#039;&#039;&#039;Clipboard&#039;&#039;&#039; — copy the entire output to the system clipboard&lt;br /&gt;
* &#039;&#039;&#039;Clear&#039;&#039;&#039; — clear the output area&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
TreeDoc saves your last-used folder path and the Include Files checkbox state to &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt; automatically on exit. These are restored the next time the application opens.&lt;br /&gt;
&lt;br /&gt;
If the saved folder path no longer exists, TreeDoc prompts you to choose a new folder on startup.&lt;br /&gt;
&lt;br /&gt;
== Log Files ==&lt;br /&gt;
&lt;br /&gt;
Activity is written to &amp;lt;code&amp;gt;logs/TreeDoc.log&amp;lt;/code&amp;gt;. Log files rotate at 10 MB and are retained for 14 days.&lt;br /&gt;
&lt;br /&gt;
See also: [[XML Viewer]], [[Menu4j]], [[Downloads]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Menu4j&amp;diff=1806</id>
		<title>Menu4j</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Menu4j&amp;diff=1806"/>
		<updated>2026-04-01T15:28:41Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Menu4j (JMenuTree) is a desktop command launcher that organises shell commands, scripts, and applications into a hierarchical tree menu. It provides a configurable, script-aware alternative to Finder shortcuts and shell aliases, with support for real-time terminal output, multiple linked menu trees, and optional startup password protection.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
Menu4j is used to organise the day-to-day development and operational commands for the Commander4j suite in a single, structured interface. Menu items can run shell scripts, open applications, pass parameters, capture output, and link to other menu tree files.&lt;br /&gt;
&lt;br /&gt;
== Running Menu4j ==&lt;br /&gt;
&lt;br /&gt;
Native install packages for Windows, macOS, and Linux are available from the [[Downloads]] page and are the preferred installation method.&lt;br /&gt;
&lt;br /&gt;
Alternatively, Menu4j can be run directly from the distribution archive. It is a Java 21 desktop (Swing) application:&lt;br /&gt;
&lt;br /&gt;
 java -jar JMenu.jar&lt;br /&gt;
&lt;br /&gt;
On first launch, if no configuration file is found, Menu4j copies a template configuration from &amp;lt;code&amp;gt;xml/config/init/config.xml&amp;lt;/code&amp;gt; and a template menu tree from &amp;lt;code&amp;gt;xml/tree/init/tree.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If a startup password has been configured, you are prompted to enter it before the menu is shown. Three failed attempts close the application.&lt;br /&gt;
&lt;br /&gt;
== The Menu Tree ==&lt;br /&gt;
&lt;br /&gt;
The main window displays a JTree. There are two node types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| Branch || A folder that contains other branches or leaves&lt;br /&gt;
|-&lt;br /&gt;
| Leaf || An executable item — a command, script, or application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Double-click a leaf to execute it. Double-click a branch to expand or collapse it.&lt;br /&gt;
&lt;br /&gt;
=== Adding and Editing Items ===&lt;br /&gt;
&lt;br /&gt;
The right sidebar toolbar provides:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Add&#039;&#039;&#039; — insert a new branch or leaf under the selected node&lt;br /&gt;
* &#039;&#039;&#039;Edit&#039;&#039;&#039; — open the editor for the selected node&lt;br /&gt;
* &#039;&#039;&#039;Delete&#039;&#039;&#039; — remove the selected node&lt;br /&gt;
* &#039;&#039;&#039;Duplicate&#039;&#039;&#039; — copy the selected node&lt;br /&gt;
&lt;br /&gt;
=== Leaf Properties ===&lt;br /&gt;
&lt;br /&gt;
When editing a leaf node, the following properties are available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Description || The label shown in the menu tree&lt;br /&gt;
|-&lt;br /&gt;
| Directory || The working directory for the command&lt;br /&gt;
|-&lt;br /&gt;
| Command || The executable or system command to run&lt;br /&gt;
|-&lt;br /&gt;
| Parameters || A list of arguments to pass to the command&lt;br /&gt;
|-&lt;br /&gt;
| Shell Script Required || Whether to wrap the command in the configured shell wrapper script&lt;br /&gt;
|-&lt;br /&gt;
| Terminal Window Required || Whether to open a terminal output window to show command output&lt;br /&gt;
|-&lt;br /&gt;
| Confirm Execute || Whether to show a confirmation prompt before running&lt;br /&gt;
|-&lt;br /&gt;
| Link to Menu Tree || Whether this item opens a different tree file instead of running a command&lt;br /&gt;
|-&lt;br /&gt;
| Hint || A tooltip shown when hovering over the item&lt;br /&gt;
|-&lt;br /&gt;
| Icon || An image file to display next to the item label&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Executing Commands ==&lt;br /&gt;
&lt;br /&gt;
When a leaf is executed:&lt;br /&gt;
&lt;br /&gt;
# Menu4j validates that the directory and command exist&lt;br /&gt;
# If &#039;&#039;&#039;Shell Script Required&#039;&#039;&#039; is set, the command is wrapped using the script configured in Settings (typically a shell wrapper that sources the user&#039;s environment)&lt;br /&gt;
# If &#039;&#039;&#039;Terminal Window Required&#039;&#039;&#039; is set, a terminal output window opens and displays stdout and stderr in real time; otherwise the command runs silently in the background&lt;br /&gt;
# Environment variables configured in Settings are injected before execution&lt;br /&gt;
&lt;br /&gt;
=== Terminal Output Window ===&lt;br /&gt;
&lt;br /&gt;
The terminal window displays command output with configurable foreground and background colours and font (configured in Settings). A &#039;&#039;&#039;Respond&#039;&#039;&#039; button allows text to be sent to the command&#039;s standard input for interactive commands. When the command completes, the return code is displayed.&lt;br /&gt;
&lt;br /&gt;
== Multiple Tree Files ==&lt;br /&gt;
&lt;br /&gt;
A leaf node can be configured to switch to a different menu tree rather than execute a command. Set &#039;&#039;&#039;Link to Menu Tree&#039;&#039;&#039; and specify the filename. Double-clicking the leaf saves the current tree&#039;s expansion state and loads the linked tree. The application title bar updates to show the active tree filename.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== config.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt;. This file stores global settings including the active tree filename, shell script settings, colours, fonts, environment variables, system command whitelist, and the encrypted startup password.&lt;br /&gt;
&lt;br /&gt;
=== tree.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/tree/tree.xml&amp;lt;/code&amp;gt; (or a different filename if you have switched trees). This is the menu structure file. It is written automatically when you save from the application.&lt;br /&gt;
&lt;br /&gt;
=== tree.xml.state ===&lt;br /&gt;
&lt;br /&gt;
Located alongside the tree file. Records which branches were expanded on the last exit and restores them on next launch.&lt;br /&gt;
&lt;br /&gt;
== Settings ==&lt;br /&gt;
&lt;br /&gt;
Open Settings from the toolbar to configure:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Password || Optional startup password (stored AES-encrypted)&lt;br /&gt;
|-&lt;br /&gt;
| Shell script || Enable/disable the shell wrapper and set the script filename&lt;br /&gt;
|-&lt;br /&gt;
| Terminal colours || Foreground and background colours for the terminal output window&lt;br /&gt;
|-&lt;br /&gt;
| Tree colours || Foreground colours for leaf and branch labels&lt;br /&gt;
|-&lt;br /&gt;
| Fonts || Font choice and size for the terminal window, leaf labels, and branch labels&lt;br /&gt;
|-&lt;br /&gt;
| Environment variables || Key/value pairs injected into every executed process&lt;br /&gt;
|-&lt;br /&gt;
| System commands || Whitelist of system commands (such as &amp;lt;code&amp;gt;open&amp;lt;/code&amp;gt;) that do not require a file path to be validated&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tree Navigation ==&lt;br /&gt;
&lt;br /&gt;
The top toolbar provides four buttons for expanding and collapsing the tree:&lt;br /&gt;
&lt;br /&gt;
* Expand All&lt;br /&gt;
* Expand Selected Branch&lt;br /&gt;
* Collapse Selected Branch&lt;br /&gt;
* Collapse All&lt;br /&gt;
&lt;br /&gt;
== Saving ==&lt;br /&gt;
&lt;br /&gt;
Changes to the tree structure are saved using the &#039;&#039;&#039;Save&#039;&#039;&#039; button in the sidebar toolbar. You are prompted to save if you close the application with unsaved changes.&lt;br /&gt;
&lt;br /&gt;
See also: [[LaunchPad]], [[Downloads]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=LaunchPad&amp;diff=1805</id>
		<title>LaunchPad</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=LaunchPad&amp;diff=1805"/>
		<updated>2026-04-01T15:28:41Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;LaunchPad is a macOS application organiser and launcher. It provides a tabbed grid interface for grouping macOS applications (.app bundles) into named categories and launching them with a double-click. It is a companion tool to the Commander4j suite, used to organise the suite&#039;s tools and supporting applications in a single place.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
LaunchPad replaces cluttered Dock folders and aliases with a structured, tabbed grid. Each tab is a named category and each cell in the grid holds one application. Applications are added by browsing or dragging from Finder.&lt;br /&gt;
&lt;br /&gt;
== Running LaunchPad ==&lt;br /&gt;
&lt;br /&gt;
A native macOS install package is available from the [[Downloads]] page and is the preferred installation method.&lt;br /&gt;
&lt;br /&gt;
Alternatively, LaunchPad can be run directly from the distribution archive. It is a Java 21 desktop (Swing) application for macOS:&lt;br /&gt;
&lt;br /&gt;
 java -jar JLaunchPad.jar&lt;br /&gt;
&lt;br /&gt;
The window opens at 1300 × 900 pixels. Tabs are listed on the left edge; the grid fills the rest of the window.&lt;br /&gt;
&lt;br /&gt;
== Adding Applications ==&lt;br /&gt;
&lt;br /&gt;
=== Single Application ===&lt;br /&gt;
&lt;br /&gt;
Click the &#039;&#039;&#039;Add App&#039;&#039;&#039; toolbar button. A file chooser opens, defaulting to &amp;lt;code&amp;gt;/Applications&amp;lt;/code&amp;gt; and your home directory. Select any &amp;lt;code&amp;gt;.app&amp;lt;/code&amp;gt; bundle. If you select &amp;lt;code&amp;gt;/Applications&amp;lt;/code&amp;gt;, LaunchPad also scans &amp;lt;code&amp;gt;/System/Applications&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;/System/Applications/Utilities&amp;lt;/code&amp;gt; automatically.&lt;br /&gt;
&lt;br /&gt;
=== Importing a Folder ===&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Import Folder&#039;&#039;&#039; to scan a directory recursively for application bundles. LaunchPad filters out uninstall helpers, login item helpers, and background-only bundles, adding only user-facing applications.&lt;br /&gt;
&lt;br /&gt;
=== Drag and Drop ===&lt;br /&gt;
&lt;br /&gt;
Drag a &amp;lt;code&amp;gt;.app&amp;lt;/code&amp;gt; bundle from Finder directly onto the grid or onto a tab. An application can only appear once across all tabs — dragging a duplicate has no effect.&lt;br /&gt;
&lt;br /&gt;
== Grid Layout ==&lt;br /&gt;
&lt;br /&gt;
Each tab contains a 7-column grid of 150 × 150 pixel cells. Each cell displays the application icon (120 × 120 pixels) and the application&#039;s display name. Click &#039;&#039;&#039;Pack Icons&#039;&#039;&#039; to remove empty cells from the current tab, compacting the grid.&lt;br /&gt;
&lt;br /&gt;
Applications can be reordered within the grid by dragging from one cell to another. The same drag operation works between tabs.&lt;br /&gt;
&lt;br /&gt;
== Tab Management ==&lt;br /&gt;
&lt;br /&gt;
The toolbar provides buttons for:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Add Tab&#039;&#039;&#039; — create a new named category&lt;br /&gt;
* &#039;&#039;&#039;Edit Tab&#039;&#039;&#039; — rename the selected tab&lt;br /&gt;
* &#039;&#039;&#039;Delete Tab&#039;&#039;&#039; — remove the selected tab (with confirmation)&lt;br /&gt;
* &#039;&#039;&#039;Move Up / Move Down&#039;&#039;&#039; — reorder tabs&lt;br /&gt;
&lt;br /&gt;
== Launching Applications ==&lt;br /&gt;
&lt;br /&gt;
Double-click any application icon to launch it. LaunchPad uses the macOS &amp;lt;code&amp;gt;open&amp;lt;/code&amp;gt; command to launch the bundle, so the application opens exactly as if you had double-clicked it in Finder.&lt;br /&gt;
&lt;br /&gt;
== Cell Context Menu ==&lt;br /&gt;
&lt;br /&gt;
Right-click any cell or application to access:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Assign Custom Icon...&#039;&#039;&#039; — replace the icon with any PNG, JPG, GIF, or ICNS image&lt;br /&gt;
* &#039;&#039;&#039;Remove App&#039;&#039;&#039; — clear the cell&lt;br /&gt;
* &#039;&#039;&#039;Reveal in Finder&#039;&#039;&#039; — open the application&#039;s location in Finder&lt;br /&gt;
&lt;br /&gt;
== Icon Resolution ==&lt;br /&gt;
&lt;br /&gt;
When an application is added, LaunchPad attempts to extract its icon automatically. It tries the following in order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;code&amp;gt;.icns&amp;lt;/code&amp;gt; file named in the app&#039;s &amp;lt;code&amp;gt;Info.plist&amp;lt;/code&amp;gt;&lt;br /&gt;
# PNG icons listed in &amp;lt;code&amp;gt;Info.plist&amp;lt;/code&amp;gt; under &amp;lt;code&amp;gt;CFBundleIcons&amp;lt;/code&amp;gt;&lt;br /&gt;
# The app&#039;s &amp;lt;code&amp;gt;Assets.car&amp;lt;/code&amp;gt; (rendered via QuickLook)&lt;br /&gt;
# A generic system icon as a last resort&lt;br /&gt;
&lt;br /&gt;
Extracted icons are scaled to 120 × 120 pixels and cached to &amp;lt;code&amp;gt;images/appIcons/&amp;lt;/code&amp;gt; on disk. On subsequent launches the cached PNG is used unless the app itself has been updated.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
LaunchPad saves its state automatically on exit and restores it on the next launch.&lt;br /&gt;
&lt;br /&gt;
=== launchpad.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/config/launchpad.xml&amp;lt;/code&amp;gt;. This file records all tabs, their names, and the path of each application in the grid. It is written automatically — you do not need to edit it manually.&lt;br /&gt;
&lt;br /&gt;
=== images/appIcons/ ===&lt;br /&gt;
&lt;br /&gt;
The icon cache directory. Each application has a &amp;lt;code&amp;gt;&amp;amp;lt;BundleName&amp;amp;gt;.png&amp;lt;/code&amp;gt; file here. If you use &#039;&#039;&#039;Assign Custom Icon...&#039;&#039;&#039;, the cache file for that application is overwritten with your chosen image.&lt;br /&gt;
&lt;br /&gt;
See also: [[Menu4j]], [[ZPLRenderer]], [[Downloads]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=ZPLRenderer&amp;diff=1804</id>
		<title>ZPLRenderer</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=ZPLRenderer&amp;diff=1804"/>
		<updated>2026-04-01T15:28:39Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ZPL Renderer is a desktop application that interprets ZPL (Zebra Programming Language) commands and renders them as a visual preview of what a label will look like when printed on a physical Zebra printer. It is a companion tool to Commander4j, LabelServer4j, and AutoLab4j.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
ZPL is a text-based command language used to define label layouts, text, graphics, and barcodes for Zebra label printers. The commands are sent directly to the printer as a stream of characters and are not human-readable. ZPL Renderer allows you to:&lt;br /&gt;
&lt;br /&gt;
* Load a ZPL file and see what the label will look like before sending it to a printer&lt;br /&gt;
* Listen on a network socket so that any application sending ZPL to that port renders the label on screen in real time&lt;br /&gt;
* Zoom in and out to examine label detail&lt;br /&gt;
* Preview multiple labels from a single ZPL stream&lt;br /&gt;
* Export the rendered label to PDF&lt;br /&gt;
* Print the rendered label directly from the application&lt;br /&gt;
&lt;br /&gt;
== Running ZPL Renderer ==&lt;br /&gt;
&lt;br /&gt;
Native install packages for Windows, macOS, and Linux are available from the [[Downloads]] page and are the preferred installation method.&lt;br /&gt;
&lt;br /&gt;
Alternatively, ZPL Renderer can be run directly from the distribution archive. It is a Java 21 desktop (Swing) application:&lt;br /&gt;
&lt;br /&gt;
 java -jar zplrenderer.jar&lt;br /&gt;
&lt;br /&gt;
On first launch it reads its configuration from &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Loading a ZPL File ==&lt;br /&gt;
&lt;br /&gt;
Use the &#039;&#039;&#039;Open&#039;&#039;&#039; toolbar button to load a &amp;lt;code&amp;gt;.zpl&amp;lt;/code&amp;gt; text file from disk. The label is rendered immediately. Use &#039;&#039;&#039;Refresh&#039;&#039;&#039; to reload the file after editing it externally.&lt;br /&gt;
&lt;br /&gt;
Several example ZPL files are included in the &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! File !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| example1.zpl || Shipping label with QR code, text, and graphics&lt;br /&gt;
|-&lt;br /&gt;
| example2.zpl || Complex layout with boxes, barcodes, and logo&lt;br /&gt;
|-&lt;br /&gt;
| barcodes.zpl || Showcase of all supported barcode types&lt;br /&gt;
|-&lt;br /&gt;
| pallet_labels.zpl || Pallet label examples typical of Commander4j output&lt;br /&gt;
|-&lt;br /&gt;
| fonts.zpl || Font size and style demonstration&lt;br /&gt;
|-&lt;br /&gt;
| shipping.zpl || Shipping label sample&lt;br /&gt;
|-&lt;br /&gt;
| character.zpl || Character set reference&lt;br /&gt;
|-&lt;br /&gt;
| grid.zpl || Layout grid for alignment reference&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Network Socket Mode ==&lt;br /&gt;
&lt;br /&gt;
ZPL Renderer can listen on a TCP/IP port and render any ZPL label stream sent to it. This allows Commander4j, LabelServer4j, or any other application to use ZPL Renderer as a virtual printer — sending ZPL to the socket and seeing the result on screen instead of printing to paper.&lt;br /&gt;
&lt;br /&gt;
The default port is &#039;&#039;&#039;9100&#039;&#039;&#039; (the standard Zebra raw print port). The IP address and port are configured in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;. Enable listening using the &#039;&#039;&#039;Network&#039;&#039;&#039; button in the toolbar.&lt;br /&gt;
&lt;br /&gt;
ZPL Renderer extracts complete label blocks from the stream, identified by the standard &amp;lt;code&amp;gt;^XA&amp;lt;/code&amp;gt; (start of label) and &amp;lt;code&amp;gt;^XZ&amp;lt;/code&amp;gt; (end of label) delimiters.&lt;br /&gt;
&lt;br /&gt;
== Zoom ==&lt;br /&gt;
&lt;br /&gt;
Use the zoom controls in the toolbar to scale the rendered label between 0.10× and 2.00×. The default zoom is configured in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt; (default: 0.5×). This is useful for examining barcode detail or checking overall label proportions.&lt;br /&gt;
&lt;br /&gt;
== Multiple Labels ==&lt;br /&gt;
&lt;br /&gt;
When a ZPL file or network stream contains multiple labels, ZPL Renderer displays them as pages. Navigation controls allow stepping through each label. The maximum number of pages displayed is configurable (default: 3).&lt;br /&gt;
&lt;br /&gt;
== Export and Print ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PDF Export&#039;&#039;&#039; — saves the rendered label as a vector PDF using Apache PDFBox&lt;br /&gt;
* &#039;&#039;&#039;Print&#039;&#039;&#039; — sends the rendered label to a system printer&lt;br /&gt;
&lt;br /&gt;
== Supported ZPL Commands ==&lt;br /&gt;
&lt;br /&gt;
ZPL Renderer supports over 100 ZPL commands. Key categories:&lt;br /&gt;
&lt;br /&gt;
=== Label Setup ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^XA || Start of label&lt;br /&gt;
|-&lt;br /&gt;
| ^XZ || End of label&lt;br /&gt;
|-&lt;br /&gt;
| ^LL || Label length&lt;br /&gt;
|-&lt;br /&gt;
| ^LH || Label home (origin offset)&lt;br /&gt;
|-&lt;br /&gt;
| ^LT || Label top offset&lt;br /&gt;
|-&lt;br /&gt;
| ^PQ || Print quantity&lt;br /&gt;
|-&lt;br /&gt;
| ^CD || Change delimiter character&lt;br /&gt;
|-&lt;br /&gt;
| ^CC || Change caret character&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Text and Fields ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^FO || Field origin (X,Y position from top-left)&lt;br /&gt;
|-&lt;br /&gt;
| ^FT || Field typeset (X,Y position from bottom-left)&lt;br /&gt;
|-&lt;br /&gt;
| ^FD || Field data (the text content)&lt;br /&gt;
|-&lt;br /&gt;
| ^FS || Field separator&lt;br /&gt;
|-&lt;br /&gt;
| ^FR || Field reverse (inverted colours)&lt;br /&gt;
|-&lt;br /&gt;
| ^FW || Field orientation/rotation&lt;br /&gt;
|-&lt;br /&gt;
| ^FX || Comment (ignored in output)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Fonts ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^A0–^AZ || Select font by ID&lt;br /&gt;
|-&lt;br /&gt;
| ^CF || Change default alphanumeric font&lt;br /&gt;
|-&lt;br /&gt;
| ^CI || Change international character set/encoding&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Graphics ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^GB || Graphic box (rectangle)&lt;br /&gt;
|-&lt;br /&gt;
| ^GC || Graphic circle&lt;br /&gt;
|-&lt;br /&gt;
| ^GD || Graphic diagonal line&lt;br /&gt;
|-&lt;br /&gt;
| ^GE || Graphic ellipse&lt;br /&gt;
|-&lt;br /&gt;
| ^GF || Graphic field (embedded image data)&lt;br /&gt;
|-&lt;br /&gt;
| ^GS || Graphic symbol&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Barcodes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^BC || Code 128 / GS1-128 (EAN-128)&lt;br /&gt;
|-&lt;br /&gt;
| ^BE || EAN-13&lt;br /&gt;
|-&lt;br /&gt;
| ^B8 || EAN-8&lt;br /&gt;
|-&lt;br /&gt;
| ^B3 || Code 39&lt;br /&gt;
|-&lt;br /&gt;
| ^B2 || Interleaved 2 of 5&lt;br /&gt;
|-&lt;br /&gt;
| ^B1 || Code 11&lt;br /&gt;
|-&lt;br /&gt;
| ^BQ || QR Code&lt;br /&gt;
|-&lt;br /&gt;
| ^B7 || PDF417&lt;br /&gt;
|-&lt;br /&gt;
| ^B0 / ^BO || Aztec&lt;br /&gt;
|-&lt;br /&gt;
| ^BY || Bar code field defaults (width, ratio, height)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Barcode rendering uses the OkapiBarcode library. GS1 application identifiers are interpreted from &amp;lt;code&amp;gt;xml/config/gs1_app_defs.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== config.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Input folder || Default directory for ZPL file loading (default: &amp;lt;code&amp;gt;./examples&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| Port || Network socket port to listen on (default: 9100)&lt;br /&gt;
|-&lt;br /&gt;
| Default magnification || Starting zoom level (default: 0.5)&lt;br /&gt;
|-&lt;br /&gt;
| Max pages || Maximum number of label pages to display (default: 3)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fonts.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/config/fonts.xml&amp;lt;/code&amp;gt;, this file maps ZPL font IDs (0, A–Z) to TrueType font files and defines their pixel dimensions. This allows ZPL Renderer to simulate the fonts installed in a physical Zebra printer.&lt;br /&gt;
&lt;br /&gt;
Included fonts: Bitstream Vera, Anonymous Pro, ATTriumvirate.&lt;br /&gt;
&lt;br /&gt;
If your labels use fonts that differ from the defaults, edit &amp;lt;code&amp;gt;fonts.xml&amp;lt;/code&amp;gt; to match the font metrics of your target printer.&lt;br /&gt;
&lt;br /&gt;
== Relationship to Commander4j ==&lt;br /&gt;
&lt;br /&gt;
Commander4j generates ZPL label streams for pallet and case labels. ZPL Renderer allows you to preview these labels before deploying them to production printers, and to verify that label templates produce the correct output after making changes to the template syntax. See [[Label Template Syntax]] and [[Zebra ZPL Label]] for information on ZPL label authoring within Commander4j.&lt;br /&gt;
&lt;br /&gt;
See also: [[Zebra ZPL Label]], [[Label Template Syntax]], [[Printer Queues]], [[Production Lines &amp;amp; Labellers]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=SocketTest&amp;diff=1803</id>
		<title>SocketTest</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=SocketTest&amp;diff=1803"/>
		<updated>2026-04-01T15:28:29Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SocketTest is a TCP/IP network testing utility with a graphical interface. It acts as both a TCP client and a TCP server, allowing you to send and receive arbitrary data over a socket connection, debug protocol implementations, and simulate network endpoints. It is a companion tool to LabelServer4j, AutoLab4j, and ZPL Renderer, which all communicate with devices over raw TCP/IP sockets.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
SocketTest is useful when:&lt;br /&gt;
&lt;br /&gt;
* Testing whether a printer or other device is accepting connections on a given IP address and port&lt;br /&gt;
* Checking what a device responds with when given a specific command&lt;br /&gt;
* Sending raw ZPL or Logopak commands to a printer to verify a script without running the full service&lt;br /&gt;
* Acting as a test server to capture what LabelServer4j or AutoLab4j is actually transmitting&lt;br /&gt;
&lt;br /&gt;
== Running SocketTest ==&lt;br /&gt;
&lt;br /&gt;
Native install packages for Windows, macOS, and Linux are available from the [[Downloads]] page and are the preferred installation method.&lt;br /&gt;
&lt;br /&gt;
Alternatively, SocketTest can be run directly from the distribution archive. It is a Java 21 desktop (Swing) application:&lt;br /&gt;
&lt;br /&gt;
 java -jar SocketTest.jar&lt;br /&gt;
&lt;br /&gt;
The main window contains two tabs: &#039;&#039;&#039;Client&#039;&#039;&#039; and &#039;&#039;&#039;Server&#039;&#039;&#039;. Both tabs can be used independently or together in proxy mode.&lt;br /&gt;
&lt;br /&gt;
== Client Tab ==&lt;br /&gt;
&lt;br /&gt;
The client tab connects to a remote TCP server.&lt;br /&gt;
&lt;br /&gt;
=== Connecting ===&lt;br /&gt;
&lt;br /&gt;
Enter the IP address and port of the remote server and click &#039;&#039;&#039;Connect&#039;&#039;&#039;. The IP address dropdown is pre-populated with the network interfaces found on the local machine. The default port is &#039;&#039;&#039;9100&#039;&#039;&#039; (the standard raw Zebra print port).&lt;br /&gt;
&lt;br /&gt;
=== Sending Data ===&lt;br /&gt;
&lt;br /&gt;
Type or load the message you want to send in the left-hand text area. Use the prefix and suffix dropdowns to select control character sequences that will be prepended or appended to the message:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Token !! Character&lt;br /&gt;
|-&lt;br /&gt;
| (none) || No delimiter&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;CR&amp;amp;gt;&amp;lt;/code&amp;gt; || Carriage return (0x0D)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;LF&amp;amp;gt;&amp;lt;/code&amp;gt; || Line feed (0x0A)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;CR&amp;amp;gt;&amp;amp;lt;LF&amp;amp;gt;&amp;lt;/code&amp;gt; || Carriage return + line feed&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;STX&amp;amp;gt;&amp;lt;/code&amp;gt; || Start of text (0x02)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;ETX&amp;amp;gt;&amp;lt;/code&amp;gt; || End of text (0x03)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;ESC&amp;amp;gt;&amp;lt;/code&amp;gt; || Escape (0x1B)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;ACK&amp;amp;gt;&amp;lt;/code&amp;gt; || Acknowledge (0x06)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;NAK&amp;amp;gt;&amp;lt;/code&amp;gt; || Negative acknowledge (0x15)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Send&#039;&#039;&#039; to transmit. The right-hand log pane shows all data sent and received, colour-coded in green on a black background.&lt;br /&gt;
&lt;br /&gt;
=== Loading and Saving Messages ===&lt;br /&gt;
&lt;br /&gt;
Use &#039;&#039;&#039;Load&#039;&#039;&#039; to populate the input area from a text file, and &#039;&#039;&#039;Save&#039;&#039;&#039; to persist the input area contents. Use &#039;&#039;&#039;Clear&#039;&#039;&#039; and &#039;&#039;&#039;Save&#039;&#039;&#039; on the log pane to manage the communication history.&lt;br /&gt;
&lt;br /&gt;
== Server Tab ==&lt;br /&gt;
&lt;br /&gt;
The server tab listens for incoming TCP connections.&lt;br /&gt;
&lt;br /&gt;
=== Starting the Server ===&lt;br /&gt;
&lt;br /&gt;
Enter the bind IP address (or &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt; to listen on all interfaces) and the port, then click &#039;&#039;&#039;Open&#039;&#039;&#039;. When a client connects, its hostname and IP address are shown in the panel border. The &#039;&#039;&#039;Disconnect&#039;&#039;&#039; button closes the current client connection without stopping the server.&lt;br /&gt;
&lt;br /&gt;
=== Sending Responses ===&lt;br /&gt;
&lt;br /&gt;
Once a client is connected you can type a response in the input area and click &#039;&#039;&#039;Send&#039;&#039;&#039; to transmit it back to the client. All data received from the client is shown in the log pane, colour-coded in white on a black background.&lt;br /&gt;
&lt;br /&gt;
== Proxy Mode ==&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Proxy&#039;&#039;&#039; button on the server tab enables transparent data relay. When proxy mode is active, data received on the server side is automatically forwarded to whatever the client tab is connected to, and vice versa. This allows SocketTest to sit between a client and a real device and relay all traffic in both directions, which is useful for capturing a complete protocol conversation.&lt;br /&gt;
&lt;br /&gt;
== Control Characters ==&lt;br /&gt;
&lt;br /&gt;
Control characters are entered in human-readable token notation (&amp;lt;code&amp;gt;&amp;amp;lt;STX&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;CR&amp;amp;gt;&amp;lt;/code&amp;gt;, etc.) in the input area and converted to the actual byte values before transmission. Incoming bytes are decoded back to token notation in the log. SocketTest supports the full standard ASCII control character set (NUL through DEL).&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
SocketTest has no persistent configuration file. IP addresses, ports, and message formatting options are per-session only and reset when the application is closed.&lt;br /&gt;
&lt;br /&gt;
== Log Files ==&lt;br /&gt;
&lt;br /&gt;
SocketTest does not write a log file. All communication history is displayed in the on-screen log panes and can optionally be saved to a text file using the Save button on each pane.&lt;br /&gt;
&lt;br /&gt;
See also: [[LabelServer4j]], [[ZPLRenderer]], [[Production Lines &amp;amp; Labellers]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Installation_AutoLab4j&amp;diff=1802</id>
		<title>Installation AutoLab4j</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Installation_AutoLab4j&amp;diff=1802"/>
		<updated>2026-04-01T11:35:25Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page covers deploying AutoLab4j on a server or PC connected to the production network.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Java 21 (JRE or JDK)&lt;br /&gt;
* Network access to the Modbus I/O device on each production line (TCP port 502 by default)&lt;br /&gt;
* Network access to each Zebra printer (TCP port 9100)&lt;br /&gt;
* Network access to the Commander4j server (to receive CSV dataset files)&lt;br /&gt;
* Windows, Linux, or macOS&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Download the AutoLab4j distribution from the [[Downloads]] page and extract it to a suitable directory, for example:&lt;br /&gt;
&lt;br /&gt;
 C:\Commander4j\AutoLab4j\          (Windows)&lt;br /&gt;
 /opt/commander4j/autolab4j/        (Linux)&lt;br /&gt;
&lt;br /&gt;
The extracted directory contains:&lt;br /&gt;
&lt;br /&gt;
 AutoLab.jar&lt;br /&gt;
 lib/&lt;br /&gt;
 xml/&lt;br /&gt;
 labels/&lt;br /&gt;
 logs/&lt;br /&gt;
 interface/&lt;br /&gt;
 running/&lt;br /&gt;
&lt;br /&gt;
== Configuration Before First Run ==&lt;br /&gt;
&lt;br /&gt;
Before starting AutoLab4j, complete the following configuration steps.&lt;br /&gt;
&lt;br /&gt;
=== 1. Production Lines ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt; and define each production line. For each line you need:&lt;br /&gt;
&lt;br /&gt;
* The Modbus device IP address and port&lt;br /&gt;
* The coil address that signals a pallet complete event&lt;br /&gt;
* The coil address for semi-pallet detection&lt;br /&gt;
* The printer name (must match the name used in Commander4j)&lt;br /&gt;
&lt;br /&gt;
See [[AutoLab4j Configuration]] for the full XML structure.&lt;br /&gt;
&lt;br /&gt;
=== 2. SSCC Sequence Files ===&lt;br /&gt;
&lt;br /&gt;
Create one SSCC sequence file per printer in &amp;lt;code&amp;gt;xml/sscc/&amp;lt;/code&amp;gt;. The filename must match the printer name configured in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;. For example, for a printer named &amp;lt;code&amp;gt;PRINTER 1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 xml/sscc/PRINTER 1.xml&lt;br /&gt;
&lt;br /&gt;
The file must contain the SSCC prefix, starting sequence number, warning limit, and upper limit. Your GS1 member organisation will provide the prefix. Example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;lt;sscc&amp;gt;&lt;br /&gt;
   &amp;lt;prefix&amp;gt;384133182&amp;lt;/prefix&amp;gt;&lt;br /&gt;
   &amp;lt;sequence&amp;gt;00000001&amp;lt;/sequence&amp;gt;&lt;br /&gt;
   &amp;lt;checkDigit&amp;gt;0&amp;lt;/checkDigit&amp;gt;&lt;br /&gt;
   &amp;lt;upperlimit&amp;gt;00009999&amp;lt;/upperlimit&amp;gt;&lt;br /&gt;
   &amp;lt;warninglimit&amp;gt;00009000&amp;lt;/warninglimit&amp;gt;&lt;br /&gt;
 &amp;lt;/sscc&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Label Templates ===&lt;br /&gt;
&lt;br /&gt;
Copy the ZPL label template files into the &amp;lt;code&amp;gt;labels/&amp;lt;/code&amp;gt; directory. The filename for each template is specified in the CSV dataset file in the &amp;lt;code&amp;gt;REPORT_FILENAME&amp;lt;/code&amp;gt; field. See [[Zebra ZPL Label]] for information on ZPL label authoring.&lt;br /&gt;
&lt;br /&gt;
=== 4. Dataset Directory ===&lt;br /&gt;
&lt;br /&gt;
Ensure the directory configured as &amp;lt;code&amp;gt;dataSet path&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt; is accessible. This is where Commander4j writes the CSV files when an operator assigns a process order to a labeller. The directory can be a local path or a network share.&lt;br /&gt;
&lt;br /&gt;
=== 5. Output Directory ===&lt;br /&gt;
&lt;br /&gt;
Ensure the directory configured as &amp;lt;code&amp;gt;output path&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt; exists and is writable. AutoLab4j writes Production Declaration XML files here after each pallet is printed.&lt;br /&gt;
&lt;br /&gt;
=== 6. Email Notifications (Optional) ===&lt;br /&gt;
&lt;br /&gt;
If you want email alerts for SSCC warnings and service start/stop events, configure &amp;lt;code&amp;gt;xml/config/email.xml&amp;lt;/code&amp;gt; with your SMTP server details and distribution lists.&lt;br /&gt;
&lt;br /&gt;
== Starting AutoLab4j ==&lt;br /&gt;
&lt;br /&gt;
=== Windows ===&lt;br /&gt;
&lt;br /&gt;
 java -jar AutoLab.jar&lt;br /&gt;
&lt;br /&gt;
AutoLab4j can be installed as a Windows service using a wrapper such as WinSW so that it starts automatically on boot.&lt;br /&gt;
&lt;br /&gt;
=== Linux / macOS ===&lt;br /&gt;
&lt;br /&gt;
 java -jar AutoLab.jar&lt;br /&gt;
&lt;br /&gt;
Use systemd, launchd, or nohup for production deployment.&lt;br /&gt;
&lt;br /&gt;
When running, AutoLab4j appears in the system tray with one icon per production line. The System Log window shows startup progress.&lt;br /&gt;
&lt;br /&gt;
== Exclusive Runtime ==&lt;br /&gt;
&lt;br /&gt;
AutoLab4j uses a TCP port (default: 8000) as an exclusive runtime lock. Only one instance can run at a time. If you start a second instance, it sends a shutdown signal to the running instance and waits for it to stop before starting. The watchdog port can be changed in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Verifying the Installation ==&lt;br /&gt;
&lt;br /&gt;
After starting AutoLab4j:&lt;br /&gt;
&lt;br /&gt;
# Check the system tray — there should be one icon per enabled production line.&lt;br /&gt;
# Open the System Log window (right-click the system tray icon).&lt;br /&gt;
# Verify that each production line shows a Modbus connection attempt in its log window.&lt;br /&gt;
# Place a test CSV file in the dataset directory and trigger the Modbus coil to confirm end-to-end operation.&lt;br /&gt;
&lt;br /&gt;
== Log Files ==&lt;br /&gt;
&lt;br /&gt;
All activity is written to &amp;lt;code&amp;gt;logs/AutoLab.log&amp;lt;/code&amp;gt;. Log files rotate at 10 MB and are retained for 14 days. Review this file if any production line fails to connect or if labels are not printing.&lt;br /&gt;
&lt;br /&gt;
See also: [[AutoLab4j Configuration]], [[Overview AutoLab4j]], [[AutoLab4j Operation]]&lt;br /&gt;
&lt;br /&gt;
[[Category:AutoLab4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=AutoLab4j_Folder_Structure&amp;diff=1801</id>
		<title>AutoLab4j Folder Structure</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=AutoLab4j_Folder_Structure&amp;diff=1801"/>
		<updated>2026-04-01T11:35:23Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the directory layout of an AutoLab4j installation and the purpose of each folder.&lt;br /&gt;
&lt;br /&gt;
== Directory Layout ==&lt;br /&gt;
&lt;br /&gt;
 AutoLab4j/&lt;br /&gt;
 ├── AutoLab.jar&lt;br /&gt;
 ├── lib/&lt;br /&gt;
 ├── xml/&lt;br /&gt;
 │   ├── config/&lt;br /&gt;
 │   │   ├── config.xml&lt;br /&gt;
 │   │   ├── email.xml&lt;br /&gt;
 │   │   └── log4j2.xml&lt;br /&gt;
 │   └── sscc/&lt;br /&gt;
 │       └── PRINTER NAME.xml&lt;br /&gt;
 ├── labels/&lt;br /&gt;
 ├── interface/&lt;br /&gt;
 │   ├── input/&lt;br /&gt;
 │   │   └── dataset/&lt;br /&gt;
 │   └── output/&lt;br /&gt;
 │       └── ProdDec/&lt;br /&gt;
 ├── remote_dataset/&lt;br /&gt;
 ├── remote_labels/&lt;br /&gt;
 ├── labelary/&lt;br /&gt;
 ├── logs/&lt;br /&gt;
 └── running/&lt;br /&gt;
&lt;br /&gt;
== File and Folder Descriptions ==&lt;br /&gt;
&lt;br /&gt;
=== AutoLab.jar ===&lt;br /&gt;
&lt;br /&gt;
The main application JAR. Start AutoLab4j by running &amp;lt;code&amp;gt;java -jar AutoLab.jar&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== lib/ ===&lt;br /&gt;
&lt;br /&gt;
Third-party library JARs required by AutoLab4j (referenced in the JAR manifest classpath). Do not modify this directory.&lt;br /&gt;
&lt;br /&gt;
=== xml/config/config.xml ===&lt;br /&gt;
&lt;br /&gt;
The main configuration file. Defines production lines, Modbus connection details, pallet quantities, batch format patterns, and file paths. See [[AutoLab4j Configuration]] for the full structure.&lt;br /&gt;
&lt;br /&gt;
=== xml/config/email.xml ===&lt;br /&gt;
&lt;br /&gt;
SMTP and distribution list settings for email notifications. Used for SSCC warning alerts and service start/stop notifications.&lt;br /&gt;
&lt;br /&gt;
=== xml/config/log4j2.xml ===&lt;br /&gt;
&lt;br /&gt;
Log4j2 logging configuration. Controls log file location, rotation size, and retention period.&lt;br /&gt;
&lt;br /&gt;
=== xml/sscc/ ===&lt;br /&gt;
&lt;br /&gt;
Contains one XML sequence file per printer, named after the printer (for example &amp;lt;code&amp;gt;PRINTER 1.xml&amp;lt;/code&amp;gt;). Each file stores the current SSCC prefix, sequence number, check digit, warning limit, and upper limit. AutoLab4j reads and updates these files atomically each time a new SSCC is generated. Back up this directory regularly — it records how far through the SSCC sequence each printer has progressed.&lt;br /&gt;
&lt;br /&gt;
=== labels/ ===&lt;br /&gt;
&lt;br /&gt;
ZPL label template files. The filename of the template to use for each order is specified in the &amp;lt;code&amp;gt;REPORT_FILENAME&amp;lt;/code&amp;gt; field of the CSV dataset file. Templates contain ZPL commands with field placeholders such as &amp;lt;code&amp;gt;&amp;amp;lt;*MATERIAL*&amp;amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;amp;lt;*SSCC*&amp;amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== interface/input/dataset/ ===&lt;br /&gt;
&lt;br /&gt;
The directory AutoLab4j monitors for incoming CSV dataset files from Commander4j. When Commander4j assigns a process order to a production line, it writes a CSV file here named &amp;lt;code&amp;gt;LINE_NAME_PRINTER_NAME.CSV&amp;lt;/code&amp;gt;. This directory is configured as &amp;lt;code&amp;gt;dataSet path&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== interface/output/ProdDec/ ===&lt;br /&gt;
&lt;br /&gt;
Production Declaration XML files are written here after each pallet is printed — one file per SSCC. These files record the SSCC, product, batch, shelf life, and other details for downstream integration. This directory is configured as &amp;lt;code&amp;gt;output path&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== remote_dataset/ ===&lt;br /&gt;
&lt;br /&gt;
An optional secondary location for CSV dataset files, used when the dataset files are delivered from a remote source and need to be synchronised locally before processing. Configured as &amp;lt;code&amp;gt;dataSet path&amp;lt;/code&amp;gt; if remote synchronisation is in use.&lt;br /&gt;
&lt;br /&gt;
=== remote_labels/ ===&lt;br /&gt;
&lt;br /&gt;
An optional source directory for label template files. The LabelSync thread copies label files from this directory into &amp;lt;code&amp;gt;labels/&amp;lt;/code&amp;gt; at a configurable interval. Used when label templates are maintained centrally and need to be distributed to multiple AutoLab4j instances. Configured as &amp;lt;code&amp;gt;labelSync path&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== labelary/ ===&lt;br /&gt;
&lt;br /&gt;
Cache directory for label preview images fetched from the Labelary API. Each ZPL label that is previewed produces a PNG file here. The cache is used to avoid re-fetching the same label image on repeat prints.&lt;br /&gt;
&lt;br /&gt;
=== logs/ ===&lt;br /&gt;
&lt;br /&gt;
Application log files. The main log file is &amp;lt;code&amp;gt;AutoLab.log&amp;lt;/code&amp;gt;. Log files rotate at 10 MB and are retained for 14 days. Review this directory when diagnosing Modbus connection issues, print failures, or SSCC sequence problems.&lt;br /&gt;
&lt;br /&gt;
=== running/ ===&lt;br /&gt;
&lt;br /&gt;
Temporary runtime flag files created by AutoLab4j while it is running. These files are created on startup and removed on clean shutdown. If they remain after an unexpected exit, AutoLab4j will clear them on the next start. Do not modify or delete these files while the service is running.&lt;br /&gt;
&lt;br /&gt;
See also: [[AutoLab4j Configuration]], [[Installation AutoLab4j]], [[Overview AutoLab4j]]&lt;br /&gt;
&lt;br /&gt;
[[Category:AutoLab4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=AutoLab4j_Dataset_CSV&amp;diff=1800</id>
		<title>AutoLab4j Dataset CSV</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=AutoLab4j_Dataset_CSV&amp;diff=1800"/>
		<updated>2026-04-01T11:35:22Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;When an operator assigns a [[Process Orders|Process Order]] to a production line in Commander4j, a CSV data file is written to the dataset directory monitored by AutoLab4j. This file contains all the product and order information AutoLab4j needs to generate and print labels.&lt;br /&gt;
&lt;br /&gt;
== File Naming ==&lt;br /&gt;
&lt;br /&gt;
The CSV filename follows the format:&lt;br /&gt;
&lt;br /&gt;
 LINE_NAME_PRINTER_NAME.CSV&lt;br /&gt;
&lt;br /&gt;
For example, a production line named &amp;lt;code&amp;gt;LINE 1&amp;lt;/code&amp;gt; with a printer named &amp;lt;code&amp;gt;PRINTER 1&amp;lt;/code&amp;gt; produces:&lt;br /&gt;
&lt;br /&gt;
 LINE 1_PRINTER 1.CSV&lt;br /&gt;
&lt;br /&gt;
AutoLab4j monitors the configured dataset directory and loads this file as soon as it appears. If a new file arrives while production is active, it replaces the previous data immediately.&lt;br /&gt;
&lt;br /&gt;
== File Format ==&lt;br /&gt;
&lt;br /&gt;
The file contains a header row followed by a single data row. Fields are comma-separated. The column headers are used to map values to named variables in the label template and print configuration.&lt;br /&gt;
&lt;br /&gt;
== Fields ==&lt;br /&gt;
&lt;br /&gt;
=== Order and Product ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PROCESS_ORDER || The process order number from Commander4j&lt;br /&gt;
|-&lt;br /&gt;
| MATERIAL || The material/product code&lt;br /&gt;
|-&lt;br /&gt;
| DESCRIPTION || Product description&lt;br /&gt;
|-&lt;br /&gt;
| CUSTOMER_ID || Customer identifier, used to look up batch format patterns in config.xml&lt;br /&gt;
|-&lt;br /&gt;
| LANGUAGE || Language code for label content&lt;br /&gt;
|-&lt;br /&gt;
| REPORT_FILENAME || Filename of the ZPL label template to use (looked up in the &amp;lt;code&amp;gt;labels/&amp;lt;/code&amp;gt; directory)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Batch and Expiry ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Description&lt;br /&gt;
|-&lt;br /&gt;
| BATCH_FORMAT || Batch number format pattern (overrides the customer default in config.xml if present)&lt;br /&gt;
|-&lt;br /&gt;
| BATCH_NUMBER || Pre-calculated batch number (used directly if BATCH_FORMAT is not specified)&lt;br /&gt;
|-&lt;br /&gt;
| BATCH_PREFIX || Optional prefix prepended to the calculated batch number&lt;br /&gt;
|-&lt;br /&gt;
| DATE_OF_MANUFACTURE || Manufacturing date, used as the base for expiry date calculation&lt;br /&gt;
|-&lt;br /&gt;
| EXPIRY_DATE || Pre-calculated expiry date (used directly if shelf life fields are not present)&lt;br /&gt;
|-&lt;br /&gt;
| SHELF_LIFE || Numeric shelf life value&lt;br /&gt;
|-&lt;br /&gt;
| SHELF_LIFE_UOM || Shelf life unit of measure (D = days, M = months, Y = years)&lt;br /&gt;
|-&lt;br /&gt;
| SHELF_LIFE_RULE || Rule for how the expiry date is calculated from the manufacture date and shelf life&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Barcodes and Identifiers ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Description&lt;br /&gt;
|-&lt;br /&gt;
| EAN || EAN-13 barcode value for the product (trading unit barcode)&lt;br /&gt;
|-&lt;br /&gt;
| PROD_EAN || EAN used specifically for the production label barcode (may differ from EAN)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pallet Configuration ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Description&lt;br /&gt;
|-&lt;br /&gt;
| SSCC_PER_PALLET || Number of SSCCs (pallet labels) to generate for a full pallet&lt;br /&gt;
|-&lt;br /&gt;
| LABELS_PER_SSCC || Number of label copies to print for each SSCC&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Printer Destination ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Description&lt;br /&gt;
|-&lt;br /&gt;
| IP_ADDRESS || IP address of the Zebra printer for this line&lt;br /&gt;
|-&lt;br /&gt;
| PORT || TCP port of the Zebra printer (typically 9100)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Field Substitution in Label Templates ==&lt;br /&gt;
&lt;br /&gt;
All fields in the CSV are available as placeholders in the ZPL label template using the syntax &amp;lt;code&amp;gt;&amp;amp;lt;*FIELD_NAME*&amp;amp;gt;&amp;lt;/code&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;amp;lt;*MATERIAL*&amp;amp;gt;&amp;lt;/code&amp;gt; is replaced with the MATERIAL field value&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;amp;lt;*SSCC*&amp;amp;gt;&amp;lt;/code&amp;gt; is replaced with the generated SSCC&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;amp;lt;*EXPIRY_DATE*&amp;amp;gt;&amp;lt;/code&amp;gt; is replaced with the calculated expiry date&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;fieldNamesLookup&amp;lt;/code&amp;gt; section in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt; can map CSV field names to different template placeholder names if the CSV field names do not match the placeholder names in the template. The &amp;lt;code&amp;gt;clone&amp;lt;/code&amp;gt; section can copy a field value under an additional name, and the &amp;lt;code&amp;gt;formats&amp;lt;/code&amp;gt; section can apply numeric formatting to a field before substitution.&lt;br /&gt;
&lt;br /&gt;
== SSCC Field ==&lt;br /&gt;
&lt;br /&gt;
The SSCC is not present in the CSV file — it is generated by AutoLab4j at print time from the sequence file for the printer. It is available in the label template as &amp;lt;code&amp;gt;&amp;amp;lt;*SSCC*&amp;amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
See also: [[AutoLab4j Operation]], [[AutoLab4j Configuration]], [[Zebra ZPL Label]], [[Label Template Syntax]]&lt;br /&gt;
&lt;br /&gt;
[[Category:AutoLab4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=AutoLab4j_Operation&amp;diff=1799</id>
		<title>AutoLab4j Operation</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=AutoLab4j_Operation&amp;diff=1799"/>
		<updated>2026-04-01T11:35:21Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the end-to-end operational workflow of AutoLab4j — from an operator assigning a process order in Commander4j through to a label being printed on the production line.&lt;br /&gt;
&lt;br /&gt;
== Step 1 — Assign a Process Order ==&lt;br /&gt;
&lt;br /&gt;
In the Commander4j desktop application, an operator assigns a [[Process Orders|Process Order]] to a production line using the [[Process Order Assign to Labeller|Pallet Labelling]] screen.&lt;br /&gt;
&lt;br /&gt;
Commander4j validates the assignment and writes a CSV data file to the dataset directory configured for that line. The filename follows the format &amp;lt;code&amp;gt;LINE_NAME_PRINTER_NAME.CSV&amp;lt;/code&amp;gt;. See [[AutoLab4j Dataset CSV]] for the full list of fields in this file.&lt;br /&gt;
&lt;br /&gt;
== Step 2 — Data File Detection ==&lt;br /&gt;
&lt;br /&gt;
AutoLab4j monitors the dataset directory continuously. When the CSV file appears, it is parsed and all fields are loaded into memory and made available to the label generation and Modbus threads for that production line.&lt;br /&gt;
&lt;br /&gt;
If a new CSV file arrives while production is active, it replaces the previous data immediately. The next pallet printed will use the new product information.&lt;br /&gt;
&lt;br /&gt;
== Step 3 — Modbus Polling ==&lt;br /&gt;
&lt;br /&gt;
AutoLab4j polls the Modbus coil address configured for the production line every 250 ms. When the coil transitions to the configured trigger value (typically &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;), a print sequence is initiated.&lt;br /&gt;
&lt;br /&gt;
A second coil address is read at the same time to determine whether this is a full pallet or a semi-pallet. Full pallets and semi-pallets can have different quantities of SSCCs per pallet and labels per SSCC, as configured in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Step 4 — SSCC Generation ==&lt;br /&gt;
&lt;br /&gt;
For each SSCC to be printed on the pallet, AutoLab4j reads the next sequence number from the SSCC sequence file for this printer (&amp;lt;code&amp;gt;xml/sscc/PRINTER_NAME.xml&amp;lt;/code&amp;gt;), calculates the EAN-13 check digit, and composes the 18-digit SSCC. The sequence file is updated immediately after each read so that the number is never reused even if the application restarts.&lt;br /&gt;
&lt;br /&gt;
If the sequence number reaches the configured warning limit, an email alert is sent to the SSCC distribution list.&lt;br /&gt;
&lt;br /&gt;
== Step 5 — Label Generation ==&lt;br /&gt;
&lt;br /&gt;
For each label to be printed, AutoLab4j loads the ZPL label template specified in the &amp;lt;code&amp;gt;REPORT_FILENAME&amp;lt;/code&amp;gt; field of the CSV file. Field placeholders in the template (for example &amp;lt;code&amp;gt;&amp;amp;lt;*MATERIAL*&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;*SSCC*&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;*EXPIRY_DATE*&amp;amp;gt;&amp;lt;/code&amp;gt;) are replaced with values from the dataset.&lt;br /&gt;
&lt;br /&gt;
Batch numbers are calculated dynamically from the pattern configured for the customer in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;, using values such as the Julian day, week number, year, or process order number.&lt;br /&gt;
&lt;br /&gt;
Expiry dates are calculated from the date of manufacture and shelf life values in the CSV.&lt;br /&gt;
&lt;br /&gt;
== Step 6 — Sending to the Printer ==&lt;br /&gt;
&lt;br /&gt;
The completed ZPL is sent to the printer&#039;s IP address and port (read from the CSV dataset) over a raw TCP/IP socket connection on port 9100. AutoLab4j waits for the print thread to confirm transmission before moving to the next label.&lt;br /&gt;
&lt;br /&gt;
If the Labelary preview is enabled, the ZPL is also sent to the Labelary API to render a preview image, which is displayed in the preview window on screen.&lt;br /&gt;
&lt;br /&gt;
== Step 7 — Production Declaration ==&lt;br /&gt;
&lt;br /&gt;
After all labels for the pallet have been printed, AutoLab4j writes a Production Declaration XML file to the output directory. One file is produced per SSCC. The file records the SSCC, product, batch number, shelf life, and other details for downstream integration.&lt;br /&gt;
&lt;br /&gt;
== Step 8 — Ready for Next Pallet ==&lt;br /&gt;
&lt;br /&gt;
The Modbus poller immediately resumes monitoring for the next coil transition. When the signal fires again, the same process repeats with the next SSCC sequence number.&lt;br /&gt;
&lt;br /&gt;
== Monitoring ==&lt;br /&gt;
&lt;br /&gt;
=== System Tray Icons ===&lt;br /&gt;
&lt;br /&gt;
AutoLab4j shows one system tray icon per production line. The icon colour indicates status:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Colour !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| Green || Operating normally&lt;br /&gt;
|-&lt;br /&gt;
| Yellow || Warning (SSCC sequence approaching limit)&lt;br /&gt;
|-&lt;br /&gt;
| Red || Error (Modbus connection failure or print failure)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Right-click any tray icon for options:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Information&#039;&#039;&#039; — shows the Modbus and printer connection details for that line&lt;br /&gt;
* &#039;&#039;&#039;View Order&#039;&#039;&#039; — shows the current product data loaded from the CSV&lt;br /&gt;
* &#039;&#039;&#039;View Log&#039;&#039;&#039; — opens the notification window for that line&lt;br /&gt;
&lt;br /&gt;
=== Log Windows ===&lt;br /&gt;
&lt;br /&gt;
Each production line has its own notification window showing the last 50 log messages for that line. A separate System Log window shows service-level events. Right-click the system tray icon and select &#039;&#039;&#039;View Log&#039;&#039;&#039; to open it.&lt;br /&gt;
&lt;br /&gt;
=== Log Files ===&lt;br /&gt;
&lt;br /&gt;
All activity is written to &amp;lt;code&amp;gt;logs/AutoLab.log&amp;lt;/code&amp;gt; with rolling rotation (10 MB per file, 14 days retention). The log records every Modbus poll result, every SSCC generated, every label sent, and every print confirmation.&lt;br /&gt;
&lt;br /&gt;
== Changing the Active Product ==&lt;br /&gt;
&lt;br /&gt;
To switch product on a running line, an operator assigns a new process order in Commander4j. Commander4j overwrites the CSV file in the dataset directory. AutoLab4j detects the new file and loads it. The next Modbus trigger will use the new product data.&lt;br /&gt;
&lt;br /&gt;
== Stopping AutoLab4j ==&lt;br /&gt;
&lt;br /&gt;
Stopping the service (via Windows Services, Ctrl+C, or the system tray Exit option) triggers a graceful shutdown. AutoLab4j signals all threads to stop, waits for any in-progress print jobs to complete, flushes the email queue, and exits cleanly.&lt;br /&gt;
&lt;br /&gt;
See also: [[Overview AutoLab4j]], [[AutoLab4j Configuration]], [[AutoLab4j Dataset CSV]], [[Installation AutoLab4j]]&lt;br /&gt;
&lt;br /&gt;
[[Category:AutoLab4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Overview_AutoLab4j&amp;diff=1798</id>
		<title>Overview AutoLab4j</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Overview_AutoLab4j&amp;diff=1798"/>
		<updated>2026-04-01T11:35:20Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;AutoLab4j is an automated label printing and SSCC generation service for production lines. It monitors Modbus digital signals from production equipment, reads product data from CSV files exported by Commander4j, generates ZPL labels, sends them to networked Zebra printers over TCP/IP, and produces Production Declaration XML documents for each pallet printed.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
When a pallet is complete on a production line, the line&#039;s PLC or I/O module raises a Modbus coil signal. AutoLab4j detects this signal, generates a unique SSCC (Serial Shipping Container Code), builds the ZPL label from the active product data and label template, and sends it to the printer — all without any operator interaction.&lt;br /&gt;
&lt;br /&gt;
This separates label printing from the Commander4j desktop application and ties it directly to the physical production event rather than a manual operator action.&lt;br /&gt;
&lt;br /&gt;
== Difference from LabelServer4j ==&lt;br /&gt;
&lt;br /&gt;
AutoLab4j and LabelServer4j both print labels from Commander4j data, but serve different roles:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Feature !! AutoLab4j !! LabelServer4j&lt;br /&gt;
|-&lt;br /&gt;
| Typical use || Pallet labellers || Case and secondary labellers&lt;br /&gt;
|-&lt;br /&gt;
| Print trigger || Modbus coil signal from production line equipment || CSV file placed by Commander4j&lt;br /&gt;
|-&lt;br /&gt;
| SSCC generation || Yes — generates unique SSCCs automatically || No — SSCC is supplied in the CSV&lt;br /&gt;
|-&lt;br /&gt;
| User interface || Graphical window with per-line status displays || None — background service only&lt;br /&gt;
|-&lt;br /&gt;
| Output documents || Produces Production Declaration XML per pallet || No output documents&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== How It Works ==&lt;br /&gt;
&lt;br /&gt;
# Commander4j writes a CSV data file to the configured dataset directory when an operator assigns a process order to a production line.&lt;br /&gt;
# AutoLab4j monitors that directory. When a CSV file appears, it reads the product data into memory.&lt;br /&gt;
# AutoLab4j polls the Modbus coil address for the production line every 250 ms.&lt;br /&gt;
# When the coil signal matches the configured trigger value, AutoLab4j reads the semi-pallet coil to determine whether this is a full or semi pallet.&lt;br /&gt;
# For each SSCC in the pallet, AutoLab4j generates a unique SSCC number, builds the ZPL label from the template, and sends it to the printer over TCP/IP (port 9100).&lt;br /&gt;
# After printing, a Production Declaration XML file is written to the output directory.&lt;br /&gt;
# The SSCC sequence number is incremented and persisted to disk.&lt;br /&gt;
&lt;br /&gt;
== SSCC Generation ==&lt;br /&gt;
&lt;br /&gt;
SSCC numbers are generated from a configurable prefix and an incrementing sequence number. The sequence is stored in a per-printer XML file and updated atomically after each print. When the sequence approaches the configured warning limit, AutoLab4j sends an email alert. When it reaches the upper limit, printing stops until the sequence file is reset.&lt;br /&gt;
&lt;br /&gt;
== Pallet and Semi-Pallet Support ==&lt;br /&gt;
&lt;br /&gt;
Two Modbus coil addresses are used per production line:&lt;br /&gt;
&lt;br /&gt;
* A primary coil that signals a pallet is complete and a label should be printed&lt;br /&gt;
* A semi-pallet coil that determines whether this is a full pallet or a semi-pallet&lt;br /&gt;
&lt;br /&gt;
Full pallets and semi-pallets can be configured with different quantities of SSCCs per pallet and labels per SSCC.&lt;br /&gt;
&lt;br /&gt;
== Supported Printer Types ==&lt;br /&gt;
&lt;br /&gt;
AutoLab4j communicates with printers using ZPL (Zebra Programming Language) over raw TCP/IP sockets. Any printer that accepts raw ZPL on a configurable IP address and port is supported.&lt;br /&gt;
&lt;br /&gt;
== Multi-Line Support ==&lt;br /&gt;
&lt;br /&gt;
AutoLab4j supports multiple production lines simultaneously. Each line runs its own independent set of threads (dataset monitor, Modbus poller, print handler) and has its own system tray icon showing the current status.&lt;br /&gt;
&lt;br /&gt;
== Label Preview ==&lt;br /&gt;
&lt;br /&gt;
If enabled, AutoLab4j calls the Labelary web API to render each ZPL label as a PNG image and displays it on screen before sending to the printer. This provides a visual confirmation that the correct label is being printed.&lt;br /&gt;
&lt;br /&gt;
== Production Declaration Output ==&lt;br /&gt;
&lt;br /&gt;
After each pallet is printed, AutoLab4j writes an XML Production Declaration file to the configured output directory. This document records the SSCC, product, batch, shelf life, and other details for downstream integration.&lt;br /&gt;
&lt;br /&gt;
See also: [[AutoLab4j Configuration]], [[AutoLab4j Operation]], [[AutoLab4j Dataset CSV]], [[LabelServer4j]]&lt;br /&gt;
&lt;br /&gt;
[[Category:AutoLab4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=TreeDoc&amp;diff=1797</id>
		<title>TreeDoc</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=TreeDoc&amp;diff=1797"/>
		<updated>2026-04-01T11:29:49Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TreeDoc is a desktop utility that generates an ASCII directory tree from a folder you select and displays it in a scrollable text window. The output can be copied to the clipboard or saved as a plain text file.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
TreeDoc is useful for producing a human-readable snapshot of a folder structure — for example, documenting a Commander4j installation layout, comparing the contents of two directories, or quickly exploring an unfamiliar project. The output uses box-drawing characters (├──, └──, │) to show the hierarchy clearly in any monospace environment.&lt;br /&gt;
&lt;br /&gt;
== Running TreeDoc ==&lt;br /&gt;
&lt;br /&gt;
TreeDoc is a Java 21 desktop (Swing) application:&lt;br /&gt;
&lt;br /&gt;
 java -jar Tree.jar&lt;br /&gt;
&lt;br /&gt;
The window opens at 900 × 750 pixels.&lt;br /&gt;
&lt;br /&gt;
== Generating a Tree ==&lt;br /&gt;
&lt;br /&gt;
# Click &#039;&#039;&#039;Browse&#039;&#039;&#039; to choose the root folder, or type a path directly into the folder field.&lt;br /&gt;
# Adjust &#039;&#039;&#039;Max Depth&#039;&#039;&#039; and &#039;&#039;&#039;Max Entries&#039;&#039;&#039; if needed (see below).&lt;br /&gt;
# Check &#039;&#039;&#039;Include Files&#039;&#039;&#039; if you want files shown alongside directories.&lt;br /&gt;
# Click &#039;&#039;&#039;Refresh&#039;&#039;&#039; to generate the tree.&lt;br /&gt;
&lt;br /&gt;
The output appears in the central text area. The status bar at the bottom shows the total number of entries printed, and indicates if the output was truncated.&lt;br /&gt;
&lt;br /&gt;
== Options ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Option !! Default !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Max Depth || 9999 || Maximum folder depth to traverse. Set to a small number (e.g. 3) to get a high-level overview of a deep tree.&lt;br /&gt;
|-&lt;br /&gt;
| Max Entries || 10,000 || Maximum number of lines to print. Prevents the output from becoming unmanageable for very large trees.&lt;br /&gt;
|-&lt;br /&gt;
| Include Files || Off || When off, only directory names are shown. When on, files are listed inside their parent directory.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Output Format ==&lt;br /&gt;
&lt;br /&gt;
The output is plain UTF-8 text using box-drawing characters:&lt;br /&gt;
&lt;br /&gt;
 project/&lt;br /&gt;
 ├── src/&lt;br /&gt;
 │   ├── main/&lt;br /&gt;
 │   └── test/&lt;br /&gt;
 ├── docs/&lt;br /&gt;
 └── build.xml&lt;br /&gt;
&lt;br /&gt;
Directories are always included. Files appear indented under their parent directory when &#039;&#039;&#039;Include Files&#039;&#039;&#039; is enabled.&lt;br /&gt;
&lt;br /&gt;
=== What is Excluded ===&lt;br /&gt;
&lt;br /&gt;
The following are always omitted regardless of settings:&lt;br /&gt;
&lt;br /&gt;
* Hidden files and folders (system hidden flag)&lt;br /&gt;
* &amp;lt;code&amp;gt;.DS_Store&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.localized&amp;lt;/code&amp;gt; (macOS metadata)&lt;br /&gt;
* &amp;lt;code&amp;gt;.app&amp;lt;/code&amp;gt; bundles (macOS application packages)&lt;br /&gt;
* Symbolic links (skipped to prevent infinite loops)&lt;br /&gt;
&lt;br /&gt;
== Saving and Copying Output ==&lt;br /&gt;
&lt;br /&gt;
The right sidebar provides:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Save&#039;&#039;&#039; — save the output as a &amp;lt;code&amp;gt;.txt&amp;lt;/code&amp;gt; file (default filename: &amp;lt;code&amp;gt;tree.txt&amp;lt;/code&amp;gt;, UTF-8 encoded)&lt;br /&gt;
* &#039;&#039;&#039;Clipboard&#039;&#039;&#039; — copy the entire output to the system clipboard&lt;br /&gt;
* &#039;&#039;&#039;Clear&#039;&#039;&#039; — clear the output area&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
TreeDoc saves your last-used folder path and the Include Files checkbox state to &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt; automatically on exit. These are restored the next time the application opens.&lt;br /&gt;
&lt;br /&gt;
If the saved folder path no longer exists, TreeDoc prompts you to choose a new folder on startup.&lt;br /&gt;
&lt;br /&gt;
== Log Files ==&lt;br /&gt;
&lt;br /&gt;
Activity is written to &amp;lt;code&amp;gt;logs/TreeDoc.log&amp;lt;/code&amp;gt;. Log files rotate at 10 MB and are retained for 14 days.&lt;br /&gt;
&lt;br /&gt;
See also: [[XML Viewer]], [[Menu4j]], [[Downloads]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Menu4j&amp;diff=1796</id>
		<title>Menu4j</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Menu4j&amp;diff=1796"/>
		<updated>2026-04-01T11:29:48Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Menu4j (JMenuTree) is a desktop command launcher that organises shell commands, scripts, and applications into a hierarchical tree menu. It provides a configurable, script-aware alternative to Finder shortcuts and shell aliases, with support for real-time terminal output, multiple linked menu trees, and optional startup password protection.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
Menu4j is used to organise the day-to-day development and operational commands for the Commander4j suite in a single, structured interface. Menu items can run shell scripts, open applications, pass parameters, capture output, and link to other menu tree files.&lt;br /&gt;
&lt;br /&gt;
== Running Menu4j ==&lt;br /&gt;
&lt;br /&gt;
Menu4j is a Java 21 desktop (Swing) application:&lt;br /&gt;
&lt;br /&gt;
 java -jar JMenu.jar&lt;br /&gt;
&lt;br /&gt;
On first launch, if no configuration file is found, Menu4j copies a template configuration from &amp;lt;code&amp;gt;xml/config/init/config.xml&amp;lt;/code&amp;gt; and a template menu tree from &amp;lt;code&amp;gt;xml/tree/init/tree.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If a startup password has been configured, you are prompted to enter it before the menu is shown. Three failed attempts close the application.&lt;br /&gt;
&lt;br /&gt;
== The Menu Tree ==&lt;br /&gt;
&lt;br /&gt;
The main window displays a JTree. There are two node types:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| Branch || A folder that contains other branches or leaves&lt;br /&gt;
|-&lt;br /&gt;
| Leaf || An executable item — a command, script, or application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Double-click a leaf to execute it. Double-click a branch to expand or collapse it.&lt;br /&gt;
&lt;br /&gt;
=== Adding and Editing Items ===&lt;br /&gt;
&lt;br /&gt;
The right sidebar toolbar provides:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Add&#039;&#039;&#039; — insert a new branch or leaf under the selected node&lt;br /&gt;
* &#039;&#039;&#039;Edit&#039;&#039;&#039; — open the editor for the selected node&lt;br /&gt;
* &#039;&#039;&#039;Delete&#039;&#039;&#039; — remove the selected node&lt;br /&gt;
* &#039;&#039;&#039;Duplicate&#039;&#039;&#039; — copy the selected node&lt;br /&gt;
&lt;br /&gt;
=== Leaf Properties ===&lt;br /&gt;
&lt;br /&gt;
When editing a leaf node, the following properties are available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Description || The label shown in the menu tree&lt;br /&gt;
|-&lt;br /&gt;
| Directory || The working directory for the command&lt;br /&gt;
|-&lt;br /&gt;
| Command || The executable or system command to run&lt;br /&gt;
|-&lt;br /&gt;
| Parameters || A list of arguments to pass to the command&lt;br /&gt;
|-&lt;br /&gt;
| Shell Script Required || Whether to wrap the command in the configured shell wrapper script&lt;br /&gt;
|-&lt;br /&gt;
| Terminal Window Required || Whether to open a terminal output window to show command output&lt;br /&gt;
|-&lt;br /&gt;
| Confirm Execute || Whether to show a confirmation prompt before running&lt;br /&gt;
|-&lt;br /&gt;
| Link to Menu Tree || Whether this item opens a different tree file instead of running a command&lt;br /&gt;
|-&lt;br /&gt;
| Hint || A tooltip shown when hovering over the item&lt;br /&gt;
|-&lt;br /&gt;
| Icon || An image file to display next to the item label&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Executing Commands ==&lt;br /&gt;
&lt;br /&gt;
When a leaf is executed:&lt;br /&gt;
&lt;br /&gt;
# Menu4j validates that the directory and command exist&lt;br /&gt;
# If &#039;&#039;&#039;Shell Script Required&#039;&#039;&#039; is set, the command is wrapped using the script configured in Settings (typically a shell wrapper that sources the user&#039;s environment)&lt;br /&gt;
# If &#039;&#039;&#039;Terminal Window Required&#039;&#039;&#039; is set, a terminal output window opens and displays stdout and stderr in real time; otherwise the command runs silently in the background&lt;br /&gt;
# Environment variables configured in Settings are injected before execution&lt;br /&gt;
&lt;br /&gt;
=== Terminal Output Window ===&lt;br /&gt;
&lt;br /&gt;
The terminal window displays command output with configurable foreground and background colours and font (configured in Settings). A &#039;&#039;&#039;Respond&#039;&#039;&#039; button allows text to be sent to the command&#039;s standard input for interactive commands. When the command completes, the return code is displayed.&lt;br /&gt;
&lt;br /&gt;
== Multiple Tree Files ==&lt;br /&gt;
&lt;br /&gt;
A leaf node can be configured to switch to a different menu tree rather than execute a command. Set &#039;&#039;&#039;Link to Menu Tree&#039;&#039;&#039; and specify the filename. Double-clicking the leaf saves the current tree&#039;s expansion state and loads the linked tree. The application title bar updates to show the active tree filename.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== config.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt;. This file stores global settings including the active tree filename, shell script settings, colours, fonts, environment variables, system command whitelist, and the encrypted startup password.&lt;br /&gt;
&lt;br /&gt;
=== tree.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/tree/tree.xml&amp;lt;/code&amp;gt; (or a different filename if you have switched trees). This is the menu structure file. It is written automatically when you save from the application.&lt;br /&gt;
&lt;br /&gt;
=== tree.xml.state ===&lt;br /&gt;
&lt;br /&gt;
Located alongside the tree file. Records which branches were expanded on the last exit and restores them on next launch.&lt;br /&gt;
&lt;br /&gt;
== Settings ==&lt;br /&gt;
&lt;br /&gt;
Open Settings from the toolbar to configure:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Password || Optional startup password (stored AES-encrypted)&lt;br /&gt;
|-&lt;br /&gt;
| Shell script || Enable/disable the shell wrapper and set the script filename&lt;br /&gt;
|-&lt;br /&gt;
| Terminal colours || Foreground and background colours for the terminal output window&lt;br /&gt;
|-&lt;br /&gt;
| Tree colours || Foreground colours for leaf and branch labels&lt;br /&gt;
|-&lt;br /&gt;
| Fonts || Font choice and size for the terminal window, leaf labels, and branch labels&lt;br /&gt;
|-&lt;br /&gt;
| Environment variables || Key/value pairs injected into every executed process&lt;br /&gt;
|-&lt;br /&gt;
| System commands || Whitelist of system commands (such as &amp;lt;code&amp;gt;open&amp;lt;/code&amp;gt;) that do not require a file path to be validated&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tree Navigation ==&lt;br /&gt;
&lt;br /&gt;
The top toolbar provides four buttons for expanding and collapsing the tree:&lt;br /&gt;
&lt;br /&gt;
* Expand All&lt;br /&gt;
* Expand Selected Branch&lt;br /&gt;
* Collapse Selected Branch&lt;br /&gt;
* Collapse All&lt;br /&gt;
&lt;br /&gt;
== Saving ==&lt;br /&gt;
&lt;br /&gt;
Changes to the tree structure are saved using the &#039;&#039;&#039;Save&#039;&#039;&#039; button in the sidebar toolbar. You are prompted to save if you close the application with unsaved changes.&lt;br /&gt;
&lt;br /&gt;
See also: [[LaunchPad]], [[Downloads]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=LaunchPad&amp;diff=1795</id>
		<title>LaunchPad</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=LaunchPad&amp;diff=1795"/>
		<updated>2026-04-01T11:29:47Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;LaunchPad is a macOS application organiser and launcher. It provides a tabbed grid interface for grouping macOS applications (.app bundles) into named categories and launching them with a double-click. It is a companion tool to the Commander4j suite, used to organise the suite&#039;s tools and supporting applications in a single place.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
LaunchPad replaces cluttered Dock folders and aliases with a structured, tabbed grid. Each tab is a named category and each cell in the grid holds one application. Applications are added by browsing or dragging from Finder.&lt;br /&gt;
&lt;br /&gt;
== Running LaunchPad ==&lt;br /&gt;
&lt;br /&gt;
LaunchPad is a Java 21 desktop (Swing) application for macOS:&lt;br /&gt;
&lt;br /&gt;
 java -jar JLaunchPad.jar&lt;br /&gt;
&lt;br /&gt;
The window opens at 1300 × 900 pixels. Tabs are listed on the left edge; the grid fills the rest of the window.&lt;br /&gt;
&lt;br /&gt;
== Adding Applications ==&lt;br /&gt;
&lt;br /&gt;
=== Single Application ===&lt;br /&gt;
&lt;br /&gt;
Click the &#039;&#039;&#039;Add App&#039;&#039;&#039; toolbar button. A file chooser opens, defaulting to &amp;lt;code&amp;gt;/Applications&amp;lt;/code&amp;gt; and your home directory. Select any &amp;lt;code&amp;gt;.app&amp;lt;/code&amp;gt; bundle. If you select &amp;lt;code&amp;gt;/Applications&amp;lt;/code&amp;gt;, LaunchPad also scans &amp;lt;code&amp;gt;/System/Applications&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;/System/Applications/Utilities&amp;lt;/code&amp;gt; automatically.&lt;br /&gt;
&lt;br /&gt;
=== Importing a Folder ===&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Import Folder&#039;&#039;&#039; to scan a directory recursively for application bundles. LaunchPad filters out uninstall helpers, login item helpers, and background-only bundles, adding only user-facing applications.&lt;br /&gt;
&lt;br /&gt;
=== Drag and Drop ===&lt;br /&gt;
&lt;br /&gt;
Drag a &amp;lt;code&amp;gt;.app&amp;lt;/code&amp;gt; bundle from Finder directly onto the grid or onto a tab. An application can only appear once across all tabs — dragging a duplicate has no effect.&lt;br /&gt;
&lt;br /&gt;
== Grid Layout ==&lt;br /&gt;
&lt;br /&gt;
Each tab contains a 7-column grid of 150 × 150 pixel cells. Each cell displays the application icon (120 × 120 pixels) and the application&#039;s display name. Click &#039;&#039;&#039;Pack Icons&#039;&#039;&#039; to remove empty cells from the current tab, compacting the grid.&lt;br /&gt;
&lt;br /&gt;
Applications can be reordered within the grid by dragging from one cell to another. The same drag operation works between tabs.&lt;br /&gt;
&lt;br /&gt;
== Tab Management ==&lt;br /&gt;
&lt;br /&gt;
The toolbar provides buttons for:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Add Tab&#039;&#039;&#039; — create a new named category&lt;br /&gt;
* &#039;&#039;&#039;Edit Tab&#039;&#039;&#039; — rename the selected tab&lt;br /&gt;
* &#039;&#039;&#039;Delete Tab&#039;&#039;&#039; — remove the selected tab (with confirmation)&lt;br /&gt;
* &#039;&#039;&#039;Move Up / Move Down&#039;&#039;&#039; — reorder tabs&lt;br /&gt;
&lt;br /&gt;
== Launching Applications ==&lt;br /&gt;
&lt;br /&gt;
Double-click any application icon to launch it. LaunchPad uses the macOS &amp;lt;code&amp;gt;open&amp;lt;/code&amp;gt; command to launch the bundle, so the application opens exactly as if you had double-clicked it in Finder.&lt;br /&gt;
&lt;br /&gt;
== Cell Context Menu ==&lt;br /&gt;
&lt;br /&gt;
Right-click any cell or application to access:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Assign Custom Icon...&#039;&#039;&#039; — replace the icon with any PNG, JPG, GIF, or ICNS image&lt;br /&gt;
* &#039;&#039;&#039;Remove App&#039;&#039;&#039; — clear the cell&lt;br /&gt;
* &#039;&#039;&#039;Reveal in Finder&#039;&#039;&#039; — open the application&#039;s location in Finder&lt;br /&gt;
&lt;br /&gt;
== Icon Resolution ==&lt;br /&gt;
&lt;br /&gt;
When an application is added, LaunchPad attempts to extract its icon automatically. It tries the following in order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;code&amp;gt;.icns&amp;lt;/code&amp;gt; file named in the app&#039;s &amp;lt;code&amp;gt;Info.plist&amp;lt;/code&amp;gt;&lt;br /&gt;
# PNG icons listed in &amp;lt;code&amp;gt;Info.plist&amp;lt;/code&amp;gt; under &amp;lt;code&amp;gt;CFBundleIcons&amp;lt;/code&amp;gt;&lt;br /&gt;
# The app&#039;s &amp;lt;code&amp;gt;Assets.car&amp;lt;/code&amp;gt; (rendered via QuickLook)&lt;br /&gt;
# A generic system icon as a last resort&lt;br /&gt;
&lt;br /&gt;
Extracted icons are scaled to 120 × 120 pixels and cached to &amp;lt;code&amp;gt;images/appIcons/&amp;lt;/code&amp;gt; on disk. On subsequent launches the cached PNG is used unless the app itself has been updated.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
LaunchPad saves its state automatically on exit and restores it on the next launch.&lt;br /&gt;
&lt;br /&gt;
=== launchpad.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/config/launchpad.xml&amp;lt;/code&amp;gt;. This file records all tabs, their names, and the path of each application in the grid. It is written automatically — you do not need to edit it manually.&lt;br /&gt;
&lt;br /&gt;
=== images/appIcons/ ===&lt;br /&gt;
&lt;br /&gt;
The icon cache directory. Each application has a &amp;lt;code&amp;gt;&amp;amp;lt;BundleName&amp;amp;gt;.png&amp;lt;/code&amp;gt; file here. If you use &#039;&#039;&#039;Assign Custom Icon...&#039;&#039;&#039;, the cache file for that application is overwritten with your chosen image.&lt;br /&gt;
&lt;br /&gt;
See also: [[Menu4j]], [[ZPLRenderer]], [[Downloads]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=SocketTest&amp;diff=1794</id>
		<title>SocketTest</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=SocketTest&amp;diff=1794"/>
		<updated>2026-04-01T11:29:46Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SocketTest is a TCP/IP network testing utility with a graphical interface. It acts as both a TCP client and a TCP server, allowing you to send and receive arbitrary data over a socket connection, debug protocol implementations, and simulate network endpoints. It is a companion tool to LabelServer4j, AutoLab4j, and ZPL Renderer, which all communicate with devices over raw TCP/IP sockets.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
SocketTest is useful when:&lt;br /&gt;
&lt;br /&gt;
* Testing whether a printer or other device is accepting connections on a given IP address and port&lt;br /&gt;
* Checking what a device responds with when given a specific command&lt;br /&gt;
* Sending raw ZPL or Logopak commands to a printer to verify a script without running the full service&lt;br /&gt;
* Acting as a test server to capture what LabelServer4j or AutoLab4j is actually transmitting&lt;br /&gt;
&lt;br /&gt;
== Running SocketTest ==&lt;br /&gt;
&lt;br /&gt;
SocketTest is a Java 21 desktop (Swing) application:&lt;br /&gt;
&lt;br /&gt;
 java -jar SocketTest.jar&lt;br /&gt;
&lt;br /&gt;
The main window contains two tabs: &#039;&#039;&#039;Client&#039;&#039;&#039; and &#039;&#039;&#039;Server&#039;&#039;&#039;. Both tabs can be used independently or together in proxy mode.&lt;br /&gt;
&lt;br /&gt;
== Client Tab ==&lt;br /&gt;
&lt;br /&gt;
The client tab connects to a remote TCP server.&lt;br /&gt;
&lt;br /&gt;
=== Connecting ===&lt;br /&gt;
&lt;br /&gt;
Enter the IP address and port of the remote server and click &#039;&#039;&#039;Connect&#039;&#039;&#039;. The IP address dropdown is pre-populated with the network interfaces found on the local machine. The default port is &#039;&#039;&#039;9100&#039;&#039;&#039; (the standard raw Zebra print port).&lt;br /&gt;
&lt;br /&gt;
=== Sending Data ===&lt;br /&gt;
&lt;br /&gt;
Type or load the message you want to send in the left-hand text area. Use the prefix and suffix dropdowns to select control character sequences that will be prepended or appended to the message:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Token !! Character&lt;br /&gt;
|-&lt;br /&gt;
| (none) || No delimiter&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;CR&amp;amp;gt;&amp;lt;/code&amp;gt; || Carriage return (0x0D)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;LF&amp;amp;gt;&amp;lt;/code&amp;gt; || Line feed (0x0A)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;CR&amp;amp;gt;&amp;amp;lt;LF&amp;amp;gt;&amp;lt;/code&amp;gt; || Carriage return + line feed&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;STX&amp;amp;gt;&amp;lt;/code&amp;gt; || Start of text (0x02)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;ETX&amp;amp;gt;&amp;lt;/code&amp;gt; || End of text (0x03)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;ESC&amp;amp;gt;&amp;lt;/code&amp;gt; || Escape (0x1B)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;ACK&amp;amp;gt;&amp;lt;/code&amp;gt; || Acknowledge (0x06)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;amp;lt;NAK&amp;amp;gt;&amp;lt;/code&amp;gt; || Negative acknowledge (0x15)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Send&#039;&#039;&#039; to transmit. The right-hand log pane shows all data sent and received, colour-coded in green on a black background.&lt;br /&gt;
&lt;br /&gt;
=== Loading and Saving Messages ===&lt;br /&gt;
&lt;br /&gt;
Use &#039;&#039;&#039;Load&#039;&#039;&#039; to populate the input area from a text file, and &#039;&#039;&#039;Save&#039;&#039;&#039; to persist the input area contents. Use &#039;&#039;&#039;Clear&#039;&#039;&#039; and &#039;&#039;&#039;Save&#039;&#039;&#039; on the log pane to manage the communication history.&lt;br /&gt;
&lt;br /&gt;
== Server Tab ==&lt;br /&gt;
&lt;br /&gt;
The server tab listens for incoming TCP connections.&lt;br /&gt;
&lt;br /&gt;
=== Starting the Server ===&lt;br /&gt;
&lt;br /&gt;
Enter the bind IP address (or &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt; to listen on all interfaces) and the port, then click &#039;&#039;&#039;Open&#039;&#039;&#039;. When a client connects, its hostname and IP address are shown in the panel border. The &#039;&#039;&#039;Disconnect&#039;&#039;&#039; button closes the current client connection without stopping the server.&lt;br /&gt;
&lt;br /&gt;
=== Sending Responses ===&lt;br /&gt;
&lt;br /&gt;
Once a client is connected you can type a response in the input area and click &#039;&#039;&#039;Send&#039;&#039;&#039; to transmit it back to the client. All data received from the client is shown in the log pane, colour-coded in white on a black background.&lt;br /&gt;
&lt;br /&gt;
== Proxy Mode ==&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Proxy&#039;&#039;&#039; button on the server tab enables transparent data relay. When proxy mode is active, data received on the server side is automatically forwarded to whatever the client tab is connected to, and vice versa. This allows SocketTest to sit between a client and a real device and relay all traffic in both directions, which is useful for capturing a complete protocol conversation.&lt;br /&gt;
&lt;br /&gt;
== Control Characters ==&lt;br /&gt;
&lt;br /&gt;
Control characters are entered in human-readable token notation (&amp;lt;code&amp;gt;&amp;amp;lt;STX&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;CR&amp;amp;gt;&amp;lt;/code&amp;gt;, etc.) in the input area and converted to the actual byte values before transmission. Incoming bytes are decoded back to token notation in the log. SocketTest supports the full standard ASCII control character set (NUL through DEL).&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
SocketTest has no persistent configuration file. IP addresses, ports, and message formatting options are per-session only and reset when the application is closed.&lt;br /&gt;
&lt;br /&gt;
== Log Files ==&lt;br /&gt;
&lt;br /&gt;
SocketTest does not write a log file. All communication history is displayed in the on-screen log panes and can optionally be saved to a text file using the Save button on each pane.&lt;br /&gt;
&lt;br /&gt;
See also: [[LabelServer4j]], [[ZPLRenderer]], [[Production Lines &amp;amp; Labellers]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=XML_Viewer&amp;diff=1793</id>
		<title>XML Viewer</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=XML_Viewer&amp;diff=1793"/>
		<updated>2026-04-01T11:29:26Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;XML Viewer is a desktop application for exploring XML documents as an interactive, expandable tree. It supports configurable display modes, multi-language element name translation, and adjustable tree expansion depth. It is designed for viewing structured XML files such as SAP IDoc messages, Commander4j configuration files, and production schedule exports.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
XML Viewer makes it practical to inspect complex XML files that are difficult to read as raw text. Element names can be translated into plain-language descriptions (for example, the SAP field code &amp;lt;code&amp;gt;ABWKZ&amp;lt;/code&amp;gt; becomes &amp;quot;Deviation indicator&amp;quot; in the English translation), and the tree can be expanded to a specific depth to give a high-level overview without showing every leaf value.&lt;br /&gt;
&lt;br /&gt;
== Running XML Viewer ==&lt;br /&gt;
&lt;br /&gt;
XML Viewer is a Java 21 desktop (Swing) application:&lt;br /&gt;
&lt;br /&gt;
 java -jar xmlviewer.jar [optional path to XML file]&lt;br /&gt;
&lt;br /&gt;
If a file path is provided on the command line, that file is opened immediately on launch. Otherwise, the last-opened file from the configuration is loaded.&lt;br /&gt;
&lt;br /&gt;
== Loading a Document ==&lt;br /&gt;
&lt;br /&gt;
Click the &#039;&#039;&#039;Open XML Document&#039;&#039;&#039; button in the right sidebar, or pass a file path on the command line. Only well-formed XML files are supported. Click &#039;&#039;&#039;Reload XML Document&#039;&#039;&#039; to re-read the current file after it has been changed externally.&lt;br /&gt;
&lt;br /&gt;
== Display Modes ==&lt;br /&gt;
&lt;br /&gt;
=== Standard Mode ===&lt;br /&gt;
&lt;br /&gt;
The XML hierarchy is displayed exactly as it appears in the file — elements nest within their parent elements, forming a tree that mirrors the XML structure.&lt;br /&gt;
&lt;br /&gt;
=== Flat Mode ===&lt;br /&gt;
&lt;br /&gt;
Leaf elements (those containing only text, no child elements) are collapsed into their parent&#039;s row rather than appearing as separate tree nodes. Only elements that contain child elements appear as tree nodes. This produces a more compact view of documents with many small leaf values.&lt;br /&gt;
&lt;br /&gt;
Toggle between modes using the &#039;&#039;&#039;View Mode&#039;&#039;&#039; button in the right sidebar.&lt;br /&gt;
&lt;br /&gt;
== Tree Expansion Control ==&lt;br /&gt;
&lt;br /&gt;
The top toolbar provides four buttons:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Expand All&#039;&#039;&#039; — expand every node in the tree&lt;br /&gt;
* &#039;&#039;&#039;Expand Selected&#039;&#039;&#039; — expand only the selected subtree&lt;br /&gt;
* &#039;&#039;&#039;Collapse Selected&#039;&#039;&#039; — collapse the selected subtree&lt;br /&gt;
* &#039;&#039;&#039;Collapse All&#039;&#039;&#039; — collapse everything to root level&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;−&#039;&#039;&#039; and &#039;&#039;&#039;+&#039;&#039;&#039; buttons in the toolbar adjust the current expansion level (shown as a number between the buttons). Clicking &#039;&#039;&#039;Refresh&#039;&#039;&#039; after changing the level re-expands the tree to that depth.&lt;br /&gt;
&lt;br /&gt;
The expansion level is saved in the configuration and restored on next launch.&lt;br /&gt;
&lt;br /&gt;
== Translation ==&lt;br /&gt;
&lt;br /&gt;
XML Viewer can replace technical XML element names and values with plain-language descriptions from a translation file.&lt;br /&gt;
&lt;br /&gt;
=== Enabling Translation ===&lt;br /&gt;
&lt;br /&gt;
Toggle translations using the &#039;&#039;&#039;View Translations&#039;&#039;&#039; button. The &#039;&#039;&#039;Translation&#039;&#039;&#039; dropdown at the bottom of the window selects which translation file to use. The &#039;&#039;&#039;Language&#039;&#039;&#039; dropdown selects the language within that file.&lt;br /&gt;
&lt;br /&gt;
=== Built-in Translation Files ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! File !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| matmas05.xml || SAP MATMAS05 IDoc field translations&lt;br /&gt;
|-&lt;br /&gt;
| zmatmas03.xml || SAP ZMATMAS03 IDoc field translations&lt;br /&gt;
|-&lt;br /&gt;
| productionschedule.xml || Production schedule export field translations&lt;br /&gt;
|-&lt;br /&gt;
| config.xml || Commander4j configuration element translations&lt;br /&gt;
|-&lt;br /&gt;
| default.xml || Generic fallback translations&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Languages ===&lt;br /&gt;
&lt;br /&gt;
The default installation includes English, French, German, and Italian. The active language can be changed at any time from the Language dropdown.&lt;br /&gt;
&lt;br /&gt;
=== Adding Translations ===&lt;br /&gt;
&lt;br /&gt;
Translation files are XML documents located in &amp;lt;code&amp;gt;xml/translations/&amp;lt;/code&amp;gt;. Each file maps element names, attribute names, element values, and attribute values to their translated equivalents for each language. Elements without a translation entry are shown using their original name from the XML file.&lt;br /&gt;
&lt;br /&gt;
== Other Display Options ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Button !! Effect&lt;br /&gt;
|-&lt;br /&gt;
| View Icons || Show or hide the icon column next to each tree node&lt;br /&gt;
|-&lt;br /&gt;
| View Brackets || Wrap element values in &amp;lt;code&amp;gt;[ ]&amp;lt;/code&amp;gt; brackets to distinguish them from element names&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== config.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt;. Stores the last-opened file path, selected translation file, selected language, current expansion level, and the state of all four display toggles (mode, translations, brackets, icons). Updated automatically on exit.&lt;br /&gt;
&lt;br /&gt;
=== log4j2.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/log/log4j2.xml&amp;lt;/code&amp;gt;. Controls logging to &amp;lt;code&amp;gt;logs/XML_View.log&amp;lt;/code&amp;gt;. Log files rotate at 10 MB and are retained for 14 days.&lt;br /&gt;
&lt;br /&gt;
=== fonts.xml / icons ===&lt;br /&gt;
&lt;br /&gt;
Icons are loaded from &amp;lt;code&amp;gt;images/xmlIcons/&amp;lt;/code&amp;gt;. If an icon file referenced by a translation is not found, the icon column is left blank for that element without an error.&lt;br /&gt;
&lt;br /&gt;
See also: [[TreeDoc]], [[Middleware4j]], [[Label Template Syntax]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=SFTPTransfer&amp;diff=1792</id>
		<title>SFTPTransfer</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=SFTPTransfer&amp;diff=1792"/>
		<updated>2026-04-01T10:31:55Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SFTPTransfer is a background file transfer service that moves files between a local filesystem and a remote SFTP server. It is a standalone Java application that runs either as a headless background service or as a desktop application with a minimal GUI, and supports both uploading (PUT) and downloading (GET) in independent threads.&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer replaces the earlier sftpSend and sftpGet tools with a unified, configurable service.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer automates recurring file transfers between Commander4j and external systems — for example, uploading despatch notifications to a customer portal or downloading order files from a supplier. It runs continuously, polling for new files at a configurable interval, and handles authentication, retry, backup, and archiving without operator involvement.&lt;br /&gt;
&lt;br /&gt;
== Startup Modes ==&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer supports two startup modes selected at launch time:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Mode !! Behaviour&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Start desktop&#039;&#039;&#039; || Opens a small GUI window. Transfer threads start in a paused state; the operator must click Start in the interface to begin polling. Useful for testing configuration.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Start service&#039;&#039;&#039; || Headless — no GUI window. Transfer threads start immediately on launch. Suitable for production deployment as a background service or scheduled task.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On Windows the service mode can be managed using a wrapper such as WinSW. On Linux/macOS, use systemd, launchd, or nohup.&lt;br /&gt;
&lt;br /&gt;
== Configuration Files ==&lt;br /&gt;
&lt;br /&gt;
All configuration is held in XML files under the &amp;lt;code&amp;gt;xml/config/&amp;lt;/code&amp;gt; directory. Changes require a service restart unless hot-reload is triggered (see below).&lt;br /&gt;
&lt;br /&gt;
=== sftp_common.xml ===&lt;br /&gt;
&lt;br /&gt;
Shared settings used by all transfer threads:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Poll interval || How often (in seconds) each thread checks for new files. Default: 10 seconds.&lt;br /&gt;
|-&lt;br /&gt;
| Backup retention || Number of days to keep backed-up files before automatic deletion.&lt;br /&gt;
|-&lt;br /&gt;
| Log level || Logging verbosity passed to Log4j.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sftp_put.xml ===&lt;br /&gt;
&lt;br /&gt;
Configures one or more PUT (upload) profiles. Each profile defines:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Enabled || Whether this profile&#039;s thread is active.&lt;br /&gt;
|-&lt;br /&gt;
| Local path || Local directory to watch for outbound files.&lt;br /&gt;
|-&lt;br /&gt;
| File mask || Wildcard pattern to match files (e.g. &amp;lt;code&amp;gt;*.xml&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;order_*.csv&amp;lt;/code&amp;gt;). Uses Apache Commons IO WildcardFileFilter.&lt;br /&gt;
|-&lt;br /&gt;
| Remote host || SFTP server hostname or IP address.&lt;br /&gt;
|-&lt;br /&gt;
| Remote port || SFTP port (default: 22).&lt;br /&gt;
|-&lt;br /&gt;
| Remote path || Target directory on the remote server.&lt;br /&gt;
|-&lt;br /&gt;
| Username || SFTP login username.&lt;br /&gt;
|-&lt;br /&gt;
| Password || AES-encrypted password (see [[#Password Encryption|Password Encryption]]).&lt;br /&gt;
|-&lt;br /&gt;
| Private key path || Path to SSH private key file (alternative to password authentication).&lt;br /&gt;
|-&lt;br /&gt;
| Backup path || Local directory where successfully uploaded files are moved.&lt;br /&gt;
|-&lt;br /&gt;
| Error path || Local directory where files that failed to upload are moved.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sftp_get.xml ===&lt;br /&gt;
&lt;br /&gt;
Configures one or more GET (download) profiles. Each profile defines:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Enabled || Whether this profile&#039;s thread is active.&lt;br /&gt;
|-&lt;br /&gt;
| Remote host || SFTP server hostname or IP address.&lt;br /&gt;
|-&lt;br /&gt;
| Remote port || SFTP port (default: 22).&lt;br /&gt;
|-&lt;br /&gt;
| Remote path || Directory on the remote server to poll for incoming files.&lt;br /&gt;
|-&lt;br /&gt;
| File mask || Wildcard pattern matched against the remote file listing (server-side ls).&lt;br /&gt;
|-&lt;br /&gt;
| Local path || Local directory where downloaded files are saved.&lt;br /&gt;
|-&lt;br /&gt;
| Username || SFTP login username.&lt;br /&gt;
|-&lt;br /&gt;
| Password || AES-encrypted password.&lt;br /&gt;
|-&lt;br /&gt;
| Private key path || Path to SSH private key file.&lt;br /&gt;
|-&lt;br /&gt;
| Delete after download || Whether to delete the remote file after successful download.&lt;br /&gt;
|-&lt;br /&gt;
| Backup path || Local directory where a copy of each downloaded file is kept.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== jsch_properties.xml ===&lt;br /&gt;
&lt;br /&gt;
Advanced SSH session parameters passed directly to the JSch library. Used to control host key checking, preferred algorithms, and connection timeouts. In most deployments this file can be left at its defaults.&lt;br /&gt;
&lt;br /&gt;
=== email_properties.xml ===&lt;br /&gt;
&lt;br /&gt;
SMTP settings for error notification emails. When a transfer failure occurs and email notification is enabled, SFTPTransfer sends an alert to the configured address. Fields include SMTP host, port, sender address, recipient address, and AES-encrypted SMTP password.&lt;br /&gt;
&lt;br /&gt;
== Authentication ==&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer supports two authentication methods, configured per profile:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Method !! How to configure&lt;br /&gt;
|-&lt;br /&gt;
| Password || Set the &amp;lt;code&amp;gt;Password&amp;lt;/code&amp;gt; field in the profile to an AES-encrypted value. Leave the private key path empty.&lt;br /&gt;
|-&lt;br /&gt;
| SSH private key || Set the &amp;lt;code&amp;gt;Private key path&amp;lt;/code&amp;gt; field to the path of a PEM-format private key file. The password field is ignored.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Both methods use the JSch 2.x SSH library with Bouncy Castle as the cryptographic provider.&lt;br /&gt;
&lt;br /&gt;
=== Password Encryption ===&lt;br /&gt;
&lt;br /&gt;
Passwords stored in configuration files are AES-encrypted. Plain-text passwords are never stored on disk. To encrypt a password, use the password utility included with Commander4j (the same utility used for database passwords in Commander4j&#039;s own configuration).&lt;br /&gt;
&lt;br /&gt;
== File Transfer Behaviour ==&lt;br /&gt;
&lt;br /&gt;
=== PUT (Upload) ===&lt;br /&gt;
&lt;br /&gt;
# SFTPTransfer polls the local input directory every 10 seconds (configurable).&lt;br /&gt;
# Files matching the file mask are selected for upload.&lt;br /&gt;
# Each file is uploaded to the remote path using a temporary name with a &amp;lt;code&amp;gt;.tmp&amp;lt;/code&amp;gt; extension.&lt;br /&gt;
# On successful transfer, the remote file is renamed to its final name (atomic rename — the remote system never sees a partial file).&lt;br /&gt;
# The local source file is moved to the backup directory.&lt;br /&gt;
# If the transfer fails, the file is moved to the error directory and an error is logged.&lt;br /&gt;
&lt;br /&gt;
=== GET (Download) ===&lt;br /&gt;
&lt;br /&gt;
# SFTPTransfer lists the remote directory every 10 seconds (configurable).&lt;br /&gt;
# Files matching the file mask are selected for download.&lt;br /&gt;
# Each file is downloaded to the local path using a &amp;lt;code&amp;gt;.tmp&amp;lt;/code&amp;gt; extension.&lt;br /&gt;
# On successful download, the local file is renamed to its final name.&lt;br /&gt;
# If configured, the remote file is deleted after download.&lt;br /&gt;
# A backup copy is optionally saved to the local backup directory.&lt;br /&gt;
&lt;br /&gt;
== Thread Architecture ==&lt;br /&gt;
&lt;br /&gt;
When running, SFTPTransfer maintains the following threads:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Thread !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| TransferPUT || One thread per enabled PUT profile, each managing its own SFTP connection.&lt;br /&gt;
|-&lt;br /&gt;
| TransferGET || One thread per enabled GET profile, each managing its own SFTP connection.&lt;br /&gt;
|-&lt;br /&gt;
| EmailThread || Sends error notification emails asynchronously.&lt;br /&gt;
|-&lt;br /&gt;
| ArchiveThread || Periodically purges backup files older than the configured retention period.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Hot Configuration Reload ==&lt;br /&gt;
&lt;br /&gt;
SFTPTransfer supports a configuration reload mode (&amp;lt;code&amp;gt;Mode_CONFIG_UPDATE&amp;lt;/code&amp;gt;). When this mode is triggered, running threads re-read their configuration files without requiring a full service restart. This allows profile changes — such as updating a remote path or rotating credentials — to be applied with minimal disruption.&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
All activity is written to the Log4j log file. The log records:&lt;br /&gt;
&lt;br /&gt;
* Service startup and configuration loaded&lt;br /&gt;
* Each thread starting and its profile settings&lt;br /&gt;
* Every file detected, transfer attempted, and outcome&lt;br /&gt;
* Every remote connection attempt and disconnect&lt;br /&gt;
* File move operations (to backup or error directories)&lt;br /&gt;
* Errors and exceptions with full context&lt;br /&gt;
&lt;br /&gt;
Log rotation and retention are configured in the Log4j configuration file included in the distribution.&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Library !! Version !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| JSch || 2.27.9 || SSH/SFTP client&lt;br /&gt;
|-&lt;br /&gt;
| Bouncy Castle || current || Cryptographic provider for JSch&lt;br /&gt;
|-&lt;br /&gt;
| Apache Commons IO || current || WildcardFileFilter for local file matching&lt;br /&gt;
|-&lt;br /&gt;
| Log4j || 2.25.3 || Logging&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
See also: [[LabelServer4j]], [[Middleware4j]], [[Production Lines &amp;amp; Labellers]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=LabelServer4j&amp;diff=1791</id>
		<title>LabelServer4j</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=LabelServer4j&amp;diff=1791"/>
		<updated>2026-04-01T10:26:19Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;LabelServer4j&#039;&#039;&#039; is a background label printing service that bridges Commander4j and physical label printer devices on a production line. When an operator assigns a [[Process Orders|Process Order]] to a production line, Commander4j exports a data file which LabelServer4j picks up, processes through a configurable script, and uses to drive the printer over TCP/IP.&lt;br /&gt;
&lt;br /&gt;
LabelServer4j supports Zebra ZPL printers, Logopak labellers, and any device that accepts raw TCP/IP text commands. It runs as a headless background service with no graphical interface, and can manage multiple printers simultaneously in independent threads.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [[Overview LabelServer4j]] || What LabelServer4j does and how it differs from AutoLab4j&lt;br /&gt;
|-&lt;br /&gt;
| [[Downloads]] || Download the latest release&lt;br /&gt;
|-&lt;br /&gt;
| [[LabelServer4j Configuration]] || Configuring sites, labellers, and database connections&lt;br /&gt;
|-&lt;br /&gt;
| [[LabelServer4j Folder Structure]] || Directory layout and purpose of each folder&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== User Guide ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [[LabelServer4j Operation]] || End-to-end workflow from order assignment to label printed&lt;br /&gt;
|-&lt;br /&gt;
| [[LabelServer4j Dataset CSV]] || Fields available in the CSV data file from Commander4j&lt;br /&gt;
|-&lt;br /&gt;
| [[LabelServer4j Example User Interface]] || Deployment, startup, monitoring, and log file reference&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Related Pages ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [[Production Lines &amp;amp; Labellers]] || Configuring production lines in Commander4j&lt;br /&gt;
|-&lt;br /&gt;
| [[Process Order Assign to Labeller]] || Assigning orders to labellers from Commander4j&lt;br /&gt;
|-&lt;br /&gt;
| [[Zebra ZPL Label]] || ZPL label template syntax reference&lt;br /&gt;
|-&lt;br /&gt;
| [[Label Template Syntax]] || Commander4j label template language&lt;br /&gt;
|-&lt;br /&gt;
| [[ZPLRenderer]] || Tool for previewing ZPL labels before printing&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:LabelServer4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=LabelServer4j_Example_User_Interface&amp;diff=1790</id>
		<title>LabelServer4j Example User Interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=LabelServer4j_Example_User_Interface&amp;diff=1790"/>
		<updated>2026-04-01T10:26:18Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;LabelServer4j is a headless background service — it has no graphical user interface. All interaction with the service is through configuration files, log files, and (on Windows) the Windows Services control panel.&lt;br /&gt;
&lt;br /&gt;
== Starting LabelServer4j ==&lt;br /&gt;
&lt;br /&gt;
=== Windows ===&lt;br /&gt;
&lt;br /&gt;
LabelServer4j can be installed as a Windows service so that it starts automatically when the server boots and restarts automatically if it crashes. Once installed as a service it is managed through the standard Windows Services management console (&amp;lt;code&amp;gt;services.msc&amp;lt;/code&amp;gt;) or the command line:&lt;br /&gt;
&lt;br /&gt;
 net start LabelServer4j&lt;br /&gt;
 net stop LabelServer4j&lt;br /&gt;
&lt;br /&gt;
It can also be started directly from a command prompt for testing:&lt;br /&gt;
&lt;br /&gt;
 start_labeller.cmd&lt;br /&gt;
&lt;br /&gt;
=== Linux / macOS ===&lt;br /&gt;
&lt;br /&gt;
Start from the terminal using the provided shell script:&lt;br /&gt;
&lt;br /&gt;
 ./start_labeller.sh&lt;br /&gt;
&lt;br /&gt;
Or directly:&lt;br /&gt;
&lt;br /&gt;
 java -cp ./LabelServer.jar:./lib/devonly/i4jruntime.jar com.commander4j.labeller.Service&lt;br /&gt;
&lt;br /&gt;
The process runs in the foreground. Use a process manager (systemd, launchd, or nohup) for production deployment.&lt;br /&gt;
&lt;br /&gt;
== Monitoring ==&lt;br /&gt;
&lt;br /&gt;
Since there is no GUI, the primary monitoring tool is the log file:&lt;br /&gt;
&lt;br /&gt;
 logs/c4jLabelServer.log&lt;br /&gt;
&lt;br /&gt;
The log records every event in detail:&lt;br /&gt;
&lt;br /&gt;
* Service startup and configuration loading&lt;br /&gt;
* Each labeller thread starting&lt;br /&gt;
* Every CSV file detected and processed&lt;br /&gt;
* Every command sent to a printer and every response received&lt;br /&gt;
* File operations (upload, download, backup, delete)&lt;br /&gt;
* Errors and exceptions with full context&lt;br /&gt;
&lt;br /&gt;
Log files rotate at 10 MB and are retained for 14 days.&lt;br /&gt;
&lt;br /&gt;
=== What to Look For ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Situation !! What to check in the log&lt;br /&gt;
|-&lt;br /&gt;
| Label not printing || Look for the CSV filename being detected; if absent, check the input path in labellers.xml&lt;br /&gt;
|-&lt;br /&gt;
| Printer not responding || Look for TCP connection errors or timeout messages for that labeller&#039;s IP and port&lt;br /&gt;
|-&lt;br /&gt;
| Wrong data on label || Check the variable substitution log lines to see what values were sent&lt;br /&gt;
|-&lt;br /&gt;
| Script error || Look for the script line number and command that caused the failure&lt;br /&gt;
|-&lt;br /&gt;
| File stuck in input directory || File renamed to &amp;lt;code&amp;gt;.in&amp;lt;/code&amp;gt; means the script is running or failed — check for a &amp;lt;code&amp;gt;.error&amp;lt;/code&amp;gt; file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Configuration Changes ==&lt;br /&gt;
&lt;br /&gt;
To change a labeller&#039;s IP address, port, command script, or input path, edit the relevant &amp;lt;code&amp;gt;labellers.xml&amp;lt;/code&amp;gt; file and restart the service. Changes to configuration files are not picked up at runtime.&lt;br /&gt;
&lt;br /&gt;
To switch site, edit &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt; and change the &amp;lt;code&amp;gt;site id&amp;lt;/code&amp;gt; attribute, then restart.&lt;br /&gt;
&lt;br /&gt;
== Thread Architecture ==&lt;br /&gt;
&lt;br /&gt;
When running, LabelServer4j maintains the following threads:&lt;br /&gt;
&lt;br /&gt;
* One main service thread (lifecycle management)&lt;br /&gt;
* One server thread (configuration and orchestration)&lt;br /&gt;
* Per enabled labeller: one labeller thread, one TCP receive thread, one TCP transmit thread&lt;br /&gt;
&lt;br /&gt;
The thread count grows with the number of configured printers. A site with six printers typically runs around 20 threads in total.&lt;br /&gt;
&lt;br /&gt;
== Graceful Shutdown ==&lt;br /&gt;
&lt;br /&gt;
Sending a termination signal (Ctrl+C on Linux/macOS, or stopping the Windows service) triggers the shutdown hook. LabelServer4j signals all labeller threads to stop, waits for any in-progress print jobs to complete, then exits cleanly.&lt;br /&gt;
&lt;br /&gt;
See also: [[Overview LabelServer4j]], [[LabelServer4j Configuration]], [[LabelServer4j Operation]], [[Install Interface Services]]&lt;br /&gt;
&lt;br /&gt;
[[Category:LabelServer4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=LabelServer4j_Operation&amp;diff=1789</id>
		<title>LabelServer4j Operation</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=LabelServer4j_Operation&amp;diff=1789"/>
		<updated>2026-04-01T10:26:16Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the end-to-end operational workflow of LabelServer4j — from an operator assigning a process order in Commander4j through to a label being printed on the production line.&lt;br /&gt;
&lt;br /&gt;
== Step 1 — Assign a Process Order to a Labeller ==&lt;br /&gt;
&lt;br /&gt;
In the Commander4j desktop application, an operator opens the Pallet Labelling screen (or uses the [[Process_Order_Assign_to_Labeller|Process Order Assign to Labeller]] function) and assigns a [[Process Orders|Process Order]] to a configured production line.&lt;br /&gt;
&lt;br /&gt;
Commander4j validates:&lt;br /&gt;
* That the operator&#039;s workstation is permitted to assign to that line (if workstation validation is enabled)&lt;br /&gt;
* That the order&#039;s Required Resource matches the line (if resource validation is enabled)&lt;br /&gt;
&lt;br /&gt;
== Step 2 — CSV Export ==&lt;br /&gt;
&lt;br /&gt;
Commander4j writes a CSV data file to the labeller&#039;s input directory. The filename follows the format &amp;lt;code&amp;gt;LINE_NAME_PRINTER_NAME.CSV&amp;lt;/code&amp;gt;. The file contains a header row and a single data row with all the fields needed to produce the label. See [[LabelServer4j Dataset CSV]] for the full list of fields.&lt;br /&gt;
&lt;br /&gt;
== Step 3 — File Detection ==&lt;br /&gt;
&lt;br /&gt;
LabelServer4j polls the input directory every 250 ms. When the CSV file appears:&lt;br /&gt;
&lt;br /&gt;
# The file is immediately renamed to &amp;lt;code&amp;gt;.in&amp;lt;/code&amp;gt; to prevent it being picked up twice.&lt;br /&gt;
# The file is parsed using the column headers to map each value to a named variable (e.g. &amp;lt;code&amp;gt;$data_BATCH_SUFFIX&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;$data_SSCC&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== Step 4 — Script Execution ==&lt;br /&gt;
&lt;br /&gt;
LabelServer4j loads the command script configured for this labeller (a plain text &amp;lt;code&amp;gt;.txt&amp;lt;/code&amp;gt; file from the &amp;lt;code&amp;gt;labeller_cmd/&amp;lt;/code&amp;gt; directory). The script is executed line by line. Each line consists of a label (for flow control) and a command with its arguments.&lt;br /&gt;
&lt;br /&gt;
During execution, data variables from the CSV are substituted into the commands. Functions such as &amp;lt;code&amp;gt;SUBSTRING()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;PADLEFT()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;EXTRACT_DATE()&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;CODE128SWITCHER()&amp;lt;/code&amp;gt; can be used to format values before transmission.&lt;br /&gt;
&lt;br /&gt;
=== Control Flow ===&lt;br /&gt;
&lt;br /&gt;
Scripts support conditional branching and looping:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;GOTO label&amp;lt;/code&amp;gt; — unconditional jump&lt;br /&gt;
* &amp;lt;code&amp;gt;IF (condition) GOTO label&amp;lt;/code&amp;gt; — conditional jump&lt;br /&gt;
* Labels can be used to structure sections for different label types within a single script&lt;br /&gt;
&lt;br /&gt;
This allows one script to handle multiple label variants based on a field value in the CSV (for example, switching between a production layout and a rework layout based on &amp;lt;code&amp;gt;$data_MODULE_ID&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Database Queries ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;DB_QUERY&amp;lt;/code&amp;gt; command executes a parameterised SQL statement against the Commander4j database and stores the result in a variable. This enriches label data beyond what Commander4j included in the CSV.&lt;br /&gt;
&lt;br /&gt;
=== Sending to the Printer ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;SEND&amp;lt;/code&amp;gt; command transmits a line of text to the printer over the TCP/IP connection. Control characters such as &amp;lt;code&amp;gt;&amp;amp;lt;CR&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;LF&amp;amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;STX&amp;amp;gt;&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;&amp;amp;lt;ETX&amp;amp;gt;&amp;lt;/code&amp;gt; are encoded in the script and expanded at send time.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;WAIT_FOR_REPLY&amp;lt;/code&amp;gt; blocks execution until a response is received. &amp;lt;code&amp;gt;CHECK_SUCCESS&amp;lt;/code&amp;gt; compares the response against configured success and failure patterns.&lt;br /&gt;
&lt;br /&gt;
=== File Operations ===&lt;br /&gt;
&lt;br /&gt;
For Logopak and similar printers that use stored label templates, LabelServer4j can upload (&amp;lt;code&amp;gt;SEND_FILE_INTELHEX&amp;lt;/code&amp;gt;) and download (&amp;lt;code&amp;gt;RECEIVE_FILE_INTELHEX&amp;lt;/code&amp;gt;) binary files to and from the printer using Intel Hex encoding. It can also list remote files, delete them, and back them up locally.&lt;br /&gt;
&lt;br /&gt;
== Step 5 — Completion ==&lt;br /&gt;
&lt;br /&gt;
On successful completion of the script, the input CSV file is deleted and a record written to the log. The labeller thread immediately returns to polling for the next file.&lt;br /&gt;
&lt;br /&gt;
If the script fails (invalid response, connection error, or script error), the CSV file is moved to an error directory and an error message is logged. If email notifications are configured, an alert is sent.&lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
&lt;br /&gt;
All activity is written to &amp;lt;code&amp;gt;logs/c4jLabelServer.log&amp;lt;/code&amp;gt; with rolling rotation (10 MB per file, 14 days retention). The log records every command sent, every response received, and all file operations. This makes diagnosing communication issues straightforward.&lt;br /&gt;
&lt;br /&gt;
== Running Multiple Labellers ==&lt;br /&gt;
&lt;br /&gt;
Each configured labeller runs in its own background thread. All labellers poll and execute simultaneously. A site with six printers runs six independent threads, each managing its own TCP connection and input directory.&lt;br /&gt;
&lt;br /&gt;
See also: [[Overview LabelServer4j]], [[LabelServer4j Configuration]], [[LabelServer4j Dataset CSV]], [[LabelServer4j Folder Structure]], [[Production Lines &amp;amp; Labellers]]&lt;br /&gt;
&lt;br /&gt;
[[Category:LabelServer4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Overview_LabelServer4j&amp;diff=1788</id>
		<title>Overview LabelServer4j</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Overview_LabelServer4j&amp;diff=1788"/>
		<updated>2026-04-01T10:26:15Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;LabelServer4j is a background label printing service that acts as a bridge between Commander4j and physical label printer devices on a production line. It monitors for incoming label requests, processes them through configurable scripts, and communicates with printers over TCP/IP.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
When an operator assigns a [[Process Orders|Process Order]] to a production line in Commander4j, the system exports a CSV data file containing all the fields needed to print the label — product code, description, batch number, SSCC, expiry date, and so on. LabelServer4j detects this file, reads the data, executes a printer command script, and sends the appropriate commands to the labeller over the network.&lt;br /&gt;
&lt;br /&gt;
This separation means label printing is handled by a dedicated background service rather than by the Commander4j desktop application itself, allowing printers to be driven remotely without any operator interaction beyond assigning the order.&lt;br /&gt;
&lt;br /&gt;
== Difference from AutoLab4j ==&lt;br /&gt;
&lt;br /&gt;
LabelServer4j and AutoLab4j serve related but distinct purposes:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Feature !! LabelServer4j !! AutoLab4j&lt;br /&gt;
|-&lt;br /&gt;
| Typical use || Case labellers, secondary labellers || Pallet labellers&lt;br /&gt;
|-&lt;br /&gt;
| SSCC generation || No — SSCC is supplied in the CSV || Yes — generates unique SSCCs via Modbus signals from the line&lt;br /&gt;
|-&lt;br /&gt;
| User interface || None — background service only || Graphical window with printer status displays&lt;br /&gt;
|-&lt;br /&gt;
| Label trigger || CSV file from Commander4j || Modbus signal from production line equipment&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== How It Works ==&lt;br /&gt;
&lt;br /&gt;
# Commander4j writes a CSV file to the configured output directory when an order is assigned to a line.&lt;br /&gt;
# LabelServer4j polls that directory every 250 ms.&lt;br /&gt;
# When a CSV file is detected, it is locked (renamed to &amp;lt;code&amp;gt;.in&amp;lt;/code&amp;gt;), parsed, and its fields loaded as variables.&lt;br /&gt;
# A command script (a plain text file) is executed line by line. The script sends ZPL or proprietary printer commands to the labeller, substituting data fields from the CSV.&lt;br /&gt;
# The printer responds; LabelServer4j validates the response.&lt;br /&gt;
# On success, the CSV file is deleted. On failure, it is moved to an error directory.&lt;br /&gt;
&lt;br /&gt;
== Supported Printer Types ==&lt;br /&gt;
&lt;br /&gt;
LabelServer4j communicates with printers over raw TCP/IP sockets and supports two label command formats:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ZPL (Zebra Programming Language)&#039;&#039;&#039; — for Zebra and Videojet printers. Full ZPL commands with GS1 Code 128 barcode support via the built-in &amp;lt;code&amp;gt;CODE128SWITCHER()&amp;lt;/code&amp;gt; function.&lt;br /&gt;
* &#039;&#039;&#039;Logopak format&#039;&#039;&#039; — a proprietary command structure using lock/load/field data/end sequences, with binary file transfer using Intel Hex encoding for uploading label templates to the printer.&lt;br /&gt;
&lt;br /&gt;
Any printer that accepts raw TCP/IP text commands on a configurable port can be driven by LabelServer4j, provided an appropriate command script is written.&lt;br /&gt;
&lt;br /&gt;
== Multi-Site and Multi-Printer ==&lt;br /&gt;
&lt;br /&gt;
LabelServer4j supports multiple sites (each with its own &amp;lt;code&amp;gt;labellers.xml&amp;lt;/code&amp;gt;) and runs each configured printer in an independent background thread. Multiple printers operate simultaneously without interfering with one another.&lt;br /&gt;
&lt;br /&gt;
== Database Integration ==&lt;br /&gt;
&lt;br /&gt;
LabelServer4j can connect directly to the Commander4j database to perform SQL queries during script execution. This allows label content to be dynamically enriched with data that is not included in the CSV file — for example, querying the current status of an order or looking up a reference value.&lt;br /&gt;
&lt;br /&gt;
See also: [[LabelServer4j Configuration]], [[LabelServer4j Operation]], [[LabelServer4j Dataset CSV]], [[Production Lines &amp;amp; Labellers]]&lt;br /&gt;
&lt;br /&gt;
[[Category:LabelServer4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=ZPLRenderer&amp;diff=1787</id>
		<title>ZPLRenderer</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=ZPLRenderer&amp;diff=1787"/>
		<updated>2026-04-01T10:22:02Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ZPL Renderer is a desktop application that interprets ZPL (Zebra Programming Language) commands and renders them as a visual preview of what a label will look like when printed on a physical Zebra printer. It is a companion tool to Commander4j, LabelServer4j, and AutoLab4j.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
ZPL is a text-based command language used to define label layouts, text, graphics, and barcodes for Zebra label printers. The commands are sent directly to the printer as a stream of characters and are not human-readable. ZPL Renderer allows you to:&lt;br /&gt;
&lt;br /&gt;
* Load a ZPL file and see what the label will look like before sending it to a printer&lt;br /&gt;
* Listen on a network socket so that any application sending ZPL to that port renders the label on screen in real time&lt;br /&gt;
* Zoom in and out to examine label detail&lt;br /&gt;
* Preview multiple labels from a single ZPL stream&lt;br /&gt;
* Export the rendered label to PDF&lt;br /&gt;
* Print the rendered label directly from the application&lt;br /&gt;
&lt;br /&gt;
== Running ZPL Renderer ==&lt;br /&gt;
&lt;br /&gt;
ZPL Renderer is a Java 21 desktop (Swing) application:&lt;br /&gt;
&lt;br /&gt;
 java -jar zplrenderer.jar&lt;br /&gt;
&lt;br /&gt;
On first launch it reads its configuration from &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Loading a ZPL File ==&lt;br /&gt;
&lt;br /&gt;
Use the &#039;&#039;&#039;Open&#039;&#039;&#039; toolbar button to load a &amp;lt;code&amp;gt;.zpl&amp;lt;/code&amp;gt; text file from disk. The label is rendered immediately. Use &#039;&#039;&#039;Refresh&#039;&#039;&#039; to reload the file after editing it externally.&lt;br /&gt;
&lt;br /&gt;
Several example ZPL files are included in the &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! File !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| example1.zpl || Shipping label with QR code, text, and graphics&lt;br /&gt;
|-&lt;br /&gt;
| example2.zpl || Complex layout with boxes, barcodes, and logo&lt;br /&gt;
|-&lt;br /&gt;
| barcodes.zpl || Showcase of all supported barcode types&lt;br /&gt;
|-&lt;br /&gt;
| pallet_labels.zpl || Pallet label examples typical of Commander4j output&lt;br /&gt;
|-&lt;br /&gt;
| fonts.zpl || Font size and style demonstration&lt;br /&gt;
|-&lt;br /&gt;
| shipping.zpl || Shipping label sample&lt;br /&gt;
|-&lt;br /&gt;
| character.zpl || Character set reference&lt;br /&gt;
|-&lt;br /&gt;
| grid.zpl || Layout grid for alignment reference&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Network Socket Mode ==&lt;br /&gt;
&lt;br /&gt;
ZPL Renderer can listen on a TCP/IP port and render any ZPL label stream sent to it. This allows Commander4j, LabelServer4j, or any other application to use ZPL Renderer as a virtual printer — sending ZPL to the socket and seeing the result on screen instead of printing to paper.&lt;br /&gt;
&lt;br /&gt;
The default port is &#039;&#039;&#039;9100&#039;&#039;&#039; (the standard Zebra raw print port). The IP address and port are configured in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;. Enable listening using the &#039;&#039;&#039;Network&#039;&#039;&#039; button in the toolbar.&lt;br /&gt;
&lt;br /&gt;
ZPL Renderer extracts complete label blocks from the stream, identified by the standard &amp;lt;code&amp;gt;^XA&amp;lt;/code&amp;gt; (start of label) and &amp;lt;code&amp;gt;^XZ&amp;lt;/code&amp;gt; (end of label) delimiters.&lt;br /&gt;
&lt;br /&gt;
== Zoom ==&lt;br /&gt;
&lt;br /&gt;
Use the zoom controls in the toolbar to scale the rendered label between 0.10× and 2.00×. The default zoom is configured in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt; (default: 0.5×). This is useful for examining barcode detail or checking overall label proportions.&lt;br /&gt;
&lt;br /&gt;
== Multiple Labels ==&lt;br /&gt;
&lt;br /&gt;
When a ZPL file or network stream contains multiple labels, ZPL Renderer displays them as pages. Navigation controls allow stepping through each label. The maximum number of pages displayed is configurable (default: 3).&lt;br /&gt;
&lt;br /&gt;
== Export and Print ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PDF Export&#039;&#039;&#039; — saves the rendered label as a vector PDF using Apache PDFBox&lt;br /&gt;
* &#039;&#039;&#039;Print&#039;&#039;&#039; — sends the rendered label to a system printer&lt;br /&gt;
&lt;br /&gt;
== Supported ZPL Commands ==&lt;br /&gt;
&lt;br /&gt;
ZPL Renderer supports over 100 ZPL commands. Key categories:&lt;br /&gt;
&lt;br /&gt;
=== Label Setup ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^XA || Start of label&lt;br /&gt;
|-&lt;br /&gt;
| ^XZ || End of label&lt;br /&gt;
|-&lt;br /&gt;
| ^LL || Label length&lt;br /&gt;
|-&lt;br /&gt;
| ^LH || Label home (origin offset)&lt;br /&gt;
|-&lt;br /&gt;
| ^LT || Label top offset&lt;br /&gt;
|-&lt;br /&gt;
| ^PQ || Print quantity&lt;br /&gt;
|-&lt;br /&gt;
| ^CD || Change delimiter character&lt;br /&gt;
|-&lt;br /&gt;
| ^CC || Change caret character&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Text and Fields ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^FO || Field origin (X,Y position from top-left)&lt;br /&gt;
|-&lt;br /&gt;
| ^FT || Field typeset (X,Y position from bottom-left)&lt;br /&gt;
|-&lt;br /&gt;
| ^FD || Field data (the text content)&lt;br /&gt;
|-&lt;br /&gt;
| ^FS || Field separator&lt;br /&gt;
|-&lt;br /&gt;
| ^FR || Field reverse (inverted colours)&lt;br /&gt;
|-&lt;br /&gt;
| ^FW || Field orientation/rotation&lt;br /&gt;
|-&lt;br /&gt;
| ^FX || Comment (ignored in output)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Fonts ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^A0–^AZ || Select font by ID&lt;br /&gt;
|-&lt;br /&gt;
| ^CF || Change default alphanumeric font&lt;br /&gt;
|-&lt;br /&gt;
| ^CI || Change international character set/encoding&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Graphics ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^GB || Graphic box (rectangle)&lt;br /&gt;
|-&lt;br /&gt;
| ^GC || Graphic circle&lt;br /&gt;
|-&lt;br /&gt;
| ^GD || Graphic diagonal line&lt;br /&gt;
|-&lt;br /&gt;
| ^GE || Graphic ellipse&lt;br /&gt;
|-&lt;br /&gt;
| ^GF || Graphic field (embedded image data)&lt;br /&gt;
|-&lt;br /&gt;
| ^GS || Graphic symbol&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Barcodes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| ^BC || Code 128 / GS1-128 (EAN-128)&lt;br /&gt;
|-&lt;br /&gt;
| ^BE || EAN-13&lt;br /&gt;
|-&lt;br /&gt;
| ^B8 || EAN-8&lt;br /&gt;
|-&lt;br /&gt;
| ^B3 || Code 39&lt;br /&gt;
|-&lt;br /&gt;
| ^B2 || Interleaved 2 of 5&lt;br /&gt;
|-&lt;br /&gt;
| ^B1 || Code 11&lt;br /&gt;
|-&lt;br /&gt;
| ^BQ || QR Code&lt;br /&gt;
|-&lt;br /&gt;
| ^B7 || PDF417&lt;br /&gt;
|-&lt;br /&gt;
| ^B0 / ^BO || Aztec&lt;br /&gt;
|-&lt;br /&gt;
| ^BY || Bar code field defaults (width, ratio, height)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Barcode rendering uses the OkapiBarcode library. GS1 application identifiers are interpreted from &amp;lt;code&amp;gt;xml/config/gs1_app_defs.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== config.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/config/config.xml&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Input folder || Default directory for ZPL file loading (default: &amp;lt;code&amp;gt;./examples&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| Port || Network socket port to listen on (default: 9100)&lt;br /&gt;
|-&lt;br /&gt;
| Default magnification || Starting zoom level (default: 0.5)&lt;br /&gt;
|-&lt;br /&gt;
| Max pages || Maximum number of label pages to display (default: 3)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fonts.xml ===&lt;br /&gt;
&lt;br /&gt;
Located at &amp;lt;code&amp;gt;xml/config/fonts.xml&amp;lt;/code&amp;gt;, this file maps ZPL font IDs (0, A–Z) to TrueType font files and defines their pixel dimensions. This allows ZPL Renderer to simulate the fonts installed in a physical Zebra printer.&lt;br /&gt;
&lt;br /&gt;
Included fonts: Bitstream Vera, Anonymous Pro, ATTriumvirate.&lt;br /&gt;
&lt;br /&gt;
If your labels use fonts that differ from the defaults, edit &amp;lt;code&amp;gt;fonts.xml&amp;lt;/code&amp;gt; to match the font metrics of your target printer.&lt;br /&gt;
&lt;br /&gt;
== Relationship to Commander4j ==&lt;br /&gt;
&lt;br /&gt;
Commander4j generates ZPL label streams for pallet and case labels. ZPL Renderer allows you to preview these labels before deploying them to production printers, and to verify that label templates produce the correct output after making changes to the template syntax. See [[Label Template Syntax]] and [[Zebra ZPL Label]] for information on ZPL label authoring within Commander4j.&lt;br /&gt;
&lt;br /&gt;
See also: [[Zebra ZPL Label]], [[Label Template Syntax]], [[Printer Queues]], [[Production Lines &amp;amp; Labellers]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commander4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Middleware4j&amp;diff=1786</id>
		<title>Middleware4j</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Middleware4j&amp;diff=1786"/>
		<updated>2026-04-01T10:17:26Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Middleware4j&#039;&#039;&#039; is a file-based message transformation and routing engine developed as a companion to [[Commander4j]]. It has no dependencies on Commander4j and can be used independently for any system integration requirement.&lt;br /&gt;
&lt;br /&gt;
Its primary purpose is to link systems that use incompatible data formats. It monitors directories for incoming files, transforms them using configurable XSLT stylesheets, and delivers the results to one or more output destinations in the required format — running continuously in the background as a service.&lt;br /&gt;
&lt;br /&gt;
For a full explanation of how the application works, see [[Overview_Middleware4j]].&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [[Overview_Middleware4j]] || What Middleware4j does and how it works&lt;br /&gt;
|-&lt;br /&gt;
| [[Downloads]] || Download the latest release&lt;br /&gt;
|-&lt;br /&gt;
| [[Installation_Middleware4j]] || How to install and deploy as a Windows service&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== User Guide ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [[Maps]] || Configuring transformation pipelines (the core concept)&lt;br /&gt;
|-&lt;br /&gt;
| [[Connectors]] || Available input and output connector types&lt;br /&gt;
|-&lt;br /&gt;
| [[Middleware4j_Example_Configuration]] || Complete worked configuration example&lt;br /&gt;
|-&lt;br /&gt;
| [[EMAIL]] || Email connector and SMTP configuration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Connector Reference ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [[ASCII]] || Fixed-column flat file input and output&lt;br /&gt;
|-&lt;br /&gt;
| [[CSV]] || Delimiter-separated file input and output&lt;br /&gt;
|-&lt;br /&gt;
| [[XML]] || XML document input and output with XSLT transformation&lt;br /&gt;
|-&lt;br /&gt;
| [[RAW]] || Copy or move files without transformation&lt;br /&gt;
|-&lt;br /&gt;
| [[EMAIL]] || Send files as email attachments or receive via email&lt;br /&gt;
|-&lt;br /&gt;
| [[SOCKET]] || Transmit data to devices over TCP/IP&lt;br /&gt;
|-&lt;br /&gt;
| [[PDF_PRINT]] || Automatically print PDF files to a named printer queue&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:Middleware4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=PDF_PRINT&amp;diff=1785</id>
		<title>PDF PRINT</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=PDF_PRINT&amp;diff=1785"/>
		<updated>2026-04-01T10:17:25Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The PDF_PRINT connector monitors a directory for incoming PDF files and automatically sends them to a printer. It provides a simple way to automate printing of reports, labels, or documents that are generated as PDF files by Commander4j or any other application.&lt;br /&gt;
&lt;br /&gt;
== How It Works ==&lt;br /&gt;
&lt;br /&gt;
When a PDF file appears in the monitored input directory, Middleware4j reads it using Apache PDFBox and sends it to the configured print queue. The file is then moved out of the input directory. No transformation is applied — the PDF is printed as-is.&lt;br /&gt;
&lt;br /&gt;
== Input Configuration ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input&amp;gt;&lt;br /&gt;
  &amp;lt;id&amp;gt;in1&amp;lt;/id&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;PDF_PRINT&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;url&amp;gt;&lt;br /&gt;
    &amp;lt;path&amp;gt;./interface/input/Map06 PDF to PRINT&amp;lt;/path&amp;gt;&lt;br /&gt;
    &amp;lt;mask/&amp;gt;&lt;br /&gt;
    &amp;lt;pollingInterval&amp;gt;1000&amp;lt;/pollingInterval&amp;gt;&lt;br /&gt;
  &amp;lt;/url&amp;gt;&lt;br /&gt;
&amp;lt;/input&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Output Configuration ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;output&amp;gt;&lt;br /&gt;
  &amp;lt;id&amp;gt;out1&amp;lt;/id&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;PDF_PRINT&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;url&amp;gt;&lt;br /&gt;
    &amp;lt;path&amp;gt;./interface/output/Map06 PDF to PRINT&amp;lt;/path&amp;gt;&lt;br /&gt;
  &amp;lt;/url&amp;gt;&lt;br /&gt;
  &amp;lt;queueName&amp;gt;HP8600&amp;lt;/queueName&amp;gt;&lt;br /&gt;
&amp;lt;/output&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;queueName&#039;&#039;&#039; element specifies the name of the printer or print queue to use. This must match the printer name as it appears in the operating system&#039;s printer list. If &amp;lt;code&amp;gt;queueName&amp;lt;/code&amp;gt; is omitted, the system default printer is used.&lt;br /&gt;
&lt;br /&gt;
== Use Cases ==&lt;br /&gt;
&lt;br /&gt;
* Automatically printing JasperReports output from Commander4j as PDF is delivered to the input folder&lt;br /&gt;
* Printing documents generated by external systems without manual intervention&lt;br /&gt;
* Centralising print routing — other systems drop PDFs to a network share monitored by Middleware4j, which routes them to the correct printer&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* The printer must be accessible from the machine running Middleware4j. For network printers, ensure the service account running Middleware4j has permission to access the print queue.&lt;br /&gt;
* If Middleware4j is running as a Windows service under the System account, network printers may not be accessible. Configure the service to run under a domain account with the necessary permissions. See [[Installation Middleware4j]].&lt;br /&gt;
* No XSLT transformation is applied — the PDF is sent to the printer unchanged.&lt;br /&gt;
&lt;br /&gt;
See also: [[Connectors]], [[Maps]], [[Installation Middleware4j]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Middleware4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=RAW&amp;diff=1784</id>
		<title>RAW</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=RAW&amp;diff=1784"/>
		<updated>2026-04-01T10:17:24Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The RAW connector copies or moves files from one location to another without any format conversion, transformation, or interpretation of the file contents. Unlike other [[Connectors|connectors]], it does not convert the file into an internal XML representation — the bytes are passed through unchanged.&lt;br /&gt;
&lt;br /&gt;
== When to Use RAW ==&lt;br /&gt;
&lt;br /&gt;
Use the RAW connector when you need to:&lt;br /&gt;
&lt;br /&gt;
* Transfer files between directories or network shares without modifying them&lt;br /&gt;
* Monitor a remote file share and pull files to a local directory for processing by another application&lt;br /&gt;
* Replicate files to multiple destinations simultaneously&lt;br /&gt;
* Move large or binary files efficiently (no XML overhead)&lt;br /&gt;
&lt;br /&gt;
Because RAW bypasses the XML conversion step, it uses significantly less memory and CPU than other connector types — making it the right choice whenever transformation is not required.&lt;br /&gt;
&lt;br /&gt;
== Input Configuration ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input&amp;gt;&lt;br /&gt;
  &amp;lt;id&amp;gt;in1&amp;lt;/id&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;RAW&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;url&amp;gt;&lt;br /&gt;
    &amp;lt;path&amp;gt;./interface/input/Map07 RAW to RAW&amp;lt;/path&amp;gt;&lt;br /&gt;
    &amp;lt;mask/&amp;gt;&lt;br /&gt;
    &amp;lt;pollingInterval&amp;gt;5000&amp;lt;/pollingInterval&amp;gt;&lt;br /&gt;
  &amp;lt;/url&amp;gt;&lt;br /&gt;
&amp;lt;/input&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
No XSLT stylesheet can be applied to a RAW input, as the file is not converted to XML.&lt;br /&gt;
&lt;br /&gt;
== Output Configuration ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;output&amp;gt;&lt;br /&gt;
  &amp;lt;id&amp;gt;out1&amp;lt;/id&amp;gt;&lt;br /&gt;
  &amp;lt;type&amp;gt;RAW&amp;lt;/type&amp;gt;&lt;br /&gt;
  &amp;lt;url&amp;gt;&lt;br /&gt;
    &amp;lt;path&amp;gt;./interface/output/Map07 RAW to RAW&amp;lt;/path&amp;gt;&lt;br /&gt;
  &amp;lt;/url&amp;gt;&lt;br /&gt;
&amp;lt;/output&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multiple Output Paths ===&lt;br /&gt;
&lt;br /&gt;
The output path can include multiple destinations separated by semicolons. The file will be written to all specified paths:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;path&amp;gt;./interface/output/Map07 Path1;./interface/output/Map07 Path2;\\server\share\output&amp;lt;/path&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* No XSLT transformation is possible with RAW connectors — the data is not parsed.&lt;br /&gt;
* The RAW connector supports UNC network paths (&amp;lt;code&amp;gt;\\server\share\path&amp;lt;/code&amp;gt;) as well as local paths, making it suitable for file distribution across a network.&lt;br /&gt;
* Polling interval can be set longer than other connector types (e.g. 5000 ms) since RAW operations are lightweight.&lt;br /&gt;
&lt;br /&gt;
See also: [[Connectors]], [[Maps]], [[Overview_Middleware4j]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Middleware4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Connectors&amp;diff=1783</id>
		<title>Connectors</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Connectors&amp;diff=1783"/>
		<updated>2026-04-01T10:17:23Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Connectors are the components within Middleware4j responsible for reading from and writing to specific file formats and protocols. Each [[Maps|Map]] has one input connector and one or more output connectors. The connector type determines how the data is read, written, or transmitted.&lt;br /&gt;
&lt;br /&gt;
== How Connectors Work ==&lt;br /&gt;
&lt;br /&gt;
When a file arrives in an input directory, the input connector reads it and converts the data into an internal XML representation. This XML is then optionally transformed by an XSLT stylesheet before being passed to each output connector. The output connector converts the XML back into the required format and writes it to the destination.&lt;br /&gt;
&lt;br /&gt;
== Available Connectors ==&lt;br /&gt;
&lt;br /&gt;
=== [[ASCII]] ===&lt;br /&gt;
&lt;br /&gt;
Reads or writes fixed-column flat files. The key configuration is the &#039;&#039;&#039;pattern&#039;&#039;&#039; attribute, which specifies which column ranges to extract from (input) or write to (output). For example, &amp;lt;code&amp;gt;1-10,12-21,23-32&amp;lt;/code&amp;gt; extracts three fields from columns 1–10, 12–21, and 23–32.&lt;br /&gt;
&lt;br /&gt;
Use this connector when integrating with legacy systems that produce or consume fixed-width files.&lt;br /&gt;
&lt;br /&gt;
=== [[CSV]] ===&lt;br /&gt;
&lt;br /&gt;
Reads or writes delimiter-separated files using the Apache Commons CSV library. Configurable options include the delimiter character, quote character, and whether to handle 8.3 short filenames for legacy compatibility.&lt;br /&gt;
&lt;br /&gt;
Use this connector for comma- or caret-separated files, spreadsheet exports, and similar tabular data.&lt;br /&gt;
&lt;br /&gt;
=== [[XML]] ===&lt;br /&gt;
&lt;br /&gt;
Reads or writes XML files. Because Middleware4j processes all data internally as XML, this connector requires no intermediate conversion — the file is loaded directly as the working document. XSLT stylesheets transform the structure as required.&lt;br /&gt;
&lt;br /&gt;
Use this connector when the source or destination system uses XML, including Commander4j&#039;s own interface message format.&lt;br /&gt;
&lt;br /&gt;
=== IDOC ===&lt;br /&gt;
&lt;br /&gt;
Reads or writes SAP IDOC format files. IDOCs are fixed-format flat files used by SAP for data exchange. Middleware4j includes schema definitions for common IDOC types and converts them to XML for processing.&lt;br /&gt;
&lt;br /&gt;
Use this connector when integrating with SAP systems that produce or consume IDOC files.&lt;br /&gt;
&lt;br /&gt;
=== Excel ===&lt;br /&gt;
&lt;br /&gt;
Reads XLS and XLSX spreadsheet files using Apache POI, or writes data to Excel format. Useful for integrating with systems that exchange data via spreadsheet.&lt;br /&gt;
&lt;br /&gt;
=== [[EMAIL]] ===&lt;br /&gt;
&lt;br /&gt;
Sends files as email attachments via SMTP, or monitors an email inbox for incoming attachments. Email distribution lists and SMTP credentials are configured in the separate &amp;lt;code&amp;gt;email.xml&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
Use this connector to deliver reports or notifications by email, or to receive data files submitted via email.&lt;br /&gt;
&lt;br /&gt;
=== [[RAW]] ===&lt;br /&gt;
&lt;br /&gt;
Copies or moves files without any transformation or format conversion. Unlike other connectors, RAW does not convert the file to an XML representation — it passes the bytes through unchanged. This is significantly more efficient for large files or binary content.&lt;br /&gt;
&lt;br /&gt;
Use this connector when you simply need to move or replicate files between directories or file shares without modifying them.&lt;br /&gt;
&lt;br /&gt;
=== [[PDF_PRINT]] ===&lt;br /&gt;
&lt;br /&gt;
Monitors a directory for PDF files and automatically sends them to a named printer queue. The output connector configuration specifies the queue name.&lt;br /&gt;
&lt;br /&gt;
Use this connector to automate printing of reports, labels, or documents that are generated and dropped as PDF files by another system.&lt;br /&gt;
&lt;br /&gt;
=== [[SOCKET]] ===&lt;br /&gt;
&lt;br /&gt;
Transmits the transformed output to a device or service over a TCP/IP socket connection. The host IP address, port number, and optional repeat count are configured on the output connector. Useful for sending data directly to label printers, weighing systems, or other networked devices.&lt;br /&gt;
&lt;br /&gt;
=== MQTT ===&lt;br /&gt;
&lt;br /&gt;
Publishes the transformed output to an MQTT message broker. The broker address, topic, and quality of service level are configurable. Useful for IoT integration and event-driven architectures.&lt;br /&gt;
&lt;br /&gt;
== Connector Configuration Reference ==&lt;br /&gt;
&lt;br /&gt;
Each connector type has its own set of configuration elements within the map&#039;s &amp;lt;code&amp;gt;&amp;amp;lt;input&amp;amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;amp;lt;output&amp;amp;gt;&amp;lt;/code&amp;gt; block in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;. See the individual connector pages and [[Middleware4j Example Configuration]] for worked examples.&lt;br /&gt;
&lt;br /&gt;
== Error Handling ==&lt;br /&gt;
&lt;br /&gt;
If a connector fails to process a file (for example, because the format is invalid or the destination is unavailable), the input file is renamed with an &amp;lt;code&amp;gt;.error&amp;lt;/code&amp;gt; extension and left in the input directory. An email notification is sent if email notifications are enabled for that map.&lt;br /&gt;
&lt;br /&gt;
See also: [[Maps]], [[Middleware4j Example Configuration]], [[Overview_Middleware4j]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Middleware4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Maps&amp;diff=1782</id>
		<title>Maps</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Maps&amp;diff=1782"/>
		<updated>2026-04-01T10:17:22Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A Map is the core configuration unit in Middleware4j. Each map defines a complete message transformation pipeline: where to read data from, how to transform it, and where to send the result. Multiple maps can run simultaneously, each in its own background thread.&lt;br /&gt;
&lt;br /&gt;
== Structure ==&lt;br /&gt;
&lt;br /&gt;
Each map consists of:&lt;br /&gt;
&lt;br /&gt;
* One &#039;&#039;&#039;input connector&#039;&#039;&#039; — monitors a directory and reads incoming files&lt;br /&gt;
* One or more &#039;&#039;&#039;output connectors&#039;&#039;&#039; — writes the transformed result to one or more destinations&lt;br /&gt;
* Optional &#039;&#039;&#039;XSLT stylesheets&#039;&#039;&#039; on input and/or output for data transformation&lt;br /&gt;
* Optional &#039;&#039;&#039;conditions&#039;&#039;&#039; on each output for content-based routing&lt;br /&gt;
&lt;br /&gt;
== How a Map Processes a File ==&lt;br /&gt;
&lt;br /&gt;
# The input connector polls its configured directory at the set interval (default 1000 ms).&lt;br /&gt;
# When a file matching the file mask arrives, it is read and converted to an internal XML document by the input connector.&lt;br /&gt;
# If an input XSLT stylesheet is configured, it is applied to transform the XML.&lt;br /&gt;
# Each output connector is evaluated in turn:&lt;br /&gt;
## If a &#039;&#039;&#039;condition&#039;&#039;&#039; is configured, the output is only activated when the condition evaluates to true.&lt;br /&gt;
## If activated, an optional output XSLT stylesheet is applied.&lt;br /&gt;
## The result is written to the output destination by the output connector.&lt;br /&gt;
# The original input file is moved to a backup location.&lt;br /&gt;
# If any step fails, the file is renamed with an &amp;lt;code&amp;gt;.error&amp;lt;/code&amp;gt; extension and an email notification is sent (if email is configured).&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
Maps are defined in the main &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt; file. A minimal map looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;map&amp;gt;&lt;br /&gt;
  &amp;lt;id&amp;gt;Map01&amp;lt;/id&amp;gt;&lt;br /&gt;
  &amp;lt;enabled&amp;gt;true&amp;lt;/enabled&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;ASCII File to CSV&amp;lt;/description&amp;gt;&lt;br /&gt;
  &amp;lt;enableEmailNotifications&amp;gt;true&amp;lt;/enableEmailNotifications&amp;gt;&lt;br /&gt;
  &amp;lt;connectors&amp;gt;&lt;br /&gt;
    &amp;lt;input&amp;gt;&lt;br /&gt;
      &amp;lt;id&amp;gt;in1&amp;lt;/id&amp;gt;&lt;br /&gt;
      &amp;lt;type&amp;gt;ASCII&amp;lt;/type&amp;gt;&lt;br /&gt;
      &amp;lt;url&amp;gt;&lt;br /&gt;
        &amp;lt;path&amp;gt;./interface/input/Map01&amp;lt;/path&amp;gt;&lt;br /&gt;
        &amp;lt;mask/&amp;gt;&lt;br /&gt;
        &amp;lt;pollingInterval&amp;gt;1000&amp;lt;/pollingInterval&amp;gt;&lt;br /&gt;
      &amp;lt;/url&amp;gt;&lt;br /&gt;
      &amp;lt;xsl&amp;gt;&lt;br /&gt;
        &amp;lt;XSLT&amp;gt;Map01_ASCII_to_CSV.xsl&amp;lt;/XSLT&amp;gt;&lt;br /&gt;
      &amp;lt;/xsl&amp;gt;&lt;br /&gt;
      &amp;lt;ascii&amp;gt;&lt;br /&gt;
        &amp;lt;pattern&amp;gt;1-10,12-21,23-32&amp;lt;/pattern&amp;gt;&lt;br /&gt;
      &amp;lt;/ascii&amp;gt;&lt;br /&gt;
    &amp;lt;/input&amp;gt;&lt;br /&gt;
    &amp;lt;output&amp;gt;&lt;br /&gt;
      &amp;lt;id&amp;gt;out1&amp;lt;/id&amp;gt;&lt;br /&gt;
      &amp;lt;type&amp;gt;CSV&amp;lt;/type&amp;gt;&lt;br /&gt;
      &amp;lt;url&amp;gt;&lt;br /&gt;
        &amp;lt;path&amp;gt;./interface/output/Map01&amp;lt;/path&amp;gt;&lt;br /&gt;
      &amp;lt;/url&amp;gt;&lt;br /&gt;
    &amp;lt;/output&amp;gt;&lt;br /&gt;
  &amp;lt;/connectors&amp;gt;&lt;br /&gt;
&amp;lt;/map&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Key Settings ==&lt;br /&gt;
&lt;br /&gt;
=== Map Level ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;id&#039;&#039;&#039; || Unique identifier for this map (e.g. Map01)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;enabled&#039;&#039;&#039; || true/false — disabled maps are loaded but do not run&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;description&#039;&#039;&#039; || Human-readable description shown in the GUI&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;enableEmailNotifications&#039;&#039;&#039; || Whether to send error emails for this map&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Input Connector ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;type&#039;&#039;&#039; || The connector type: ASCII, CSV, XML, IDOC, Excel, EMAIL, RAW, PDF_PRINT&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;path&#039;&#039;&#039; || The directory to monitor for incoming files&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;mask&#039;&#039;&#039; || File extension filter (leave empty to process all files)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;pollingInterval&#039;&#039;&#039; || How often to check the directory, in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;xsl / XSLT&#039;&#039;&#039; || Optional XSLT stylesheet to apply after reading&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Output Connector ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;type&#039;&#039;&#039; || The connector type: ASCII, CSV, XML, SOCKET, MQTT, EMAIL, Excel, PDF_PRINT, RAW, IDOC&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;path&#039;&#039;&#039; || Output directory (multiple directories separated by semicolons)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;xsl / XSLT&#039;&#039;&#039; || Optional XSLT stylesheet to apply before writing&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;use83GUID&#039;&#039;&#039; || Use short (8.3) GUID filenames for legacy application compatibility&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;retainOriginalFilename&#039;&#039;&#039; || Keep the original input filename on the output file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Conditional Routing ==&lt;br /&gt;
&lt;br /&gt;
An output connector can be made conditional using an XPath expression evaluated against the internal XML document. This allows a single map to route different messages to different outputs based on their content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;condition&amp;gt;&lt;br /&gt;
  &amp;lt;param1&amp;gt;/message/messageData/storageBin&amp;lt;/param1&amp;gt;&lt;br /&gt;
  &amp;lt;param1_Type&amp;gt;xquery&amp;lt;/param1_Type&amp;gt;&lt;br /&gt;
  &amp;lt;param2&amp;gt;DESPATCH&amp;lt;/param2&amp;gt;&lt;br /&gt;
  &amp;lt;param2_Type&amp;gt;literal&amp;lt;/param2_Type&amp;gt;&lt;br /&gt;
  &amp;lt;comparitor&amp;gt;EQUAL&amp;lt;/comparitor&amp;gt;&lt;br /&gt;
&amp;lt;/condition&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Supported comparitors are &amp;lt;code&amp;gt;EQUAL&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;NOT EQUAL&amp;lt;/code&amp;gt;. Either or both parameters can be XPath expressions (&amp;lt;code&amp;gt;xquery&amp;lt;/code&amp;gt;) or fixed values (&amp;lt;code&amp;gt;literal&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== Multiple Outputs ==&lt;br /&gt;
&lt;br /&gt;
A single map can have any number of output connectors. All enabled outputs whose conditions are satisfied receive the transformed message. This allows one incoming file to simultaneously update multiple systems in different formats.&lt;br /&gt;
&lt;br /&gt;
== Global Settings ==&lt;br /&gt;
&lt;br /&gt;
Global settings that apply to all maps are defined at the top of &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;logPath&#039;&#039;&#039; || Directory for transformation log files&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;XSLTPath&#039;&#039;&#039; || Directory where XSLT stylesheets are stored&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;logArchiveRetentionDays&#039;&#039;&#039; || How many days to keep old log files&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;retryOpenFileCount&#039;&#039;&#039; || Number of times to retry reading a locked file&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;retryOpenFileDelay&#039;&#039;&#039; || Delay in milliseconds between retries&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;enableEmailNotifications&#039;&#039;&#039; || Global email notification toggle&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;statusReportTime&#039;&#039;&#039; || Time of day to send the daily status report email&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
See also: [[Connectors]], [[Middleware4j Example Configuration]], [[Overview_Middleware4j]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Middleware4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
	<entry>
		<id>https://wiki.commander4j.com/index.php?title=Overview_Middleware4j&amp;diff=1781</id>
		<title>Overview Middleware4j</title>
		<link rel="alternate" type="text/html" href="https://wiki.commander4j.com/index.php?title=Overview_Middleware4j&amp;diff=1781"/>
		<updated>2026-04-01T10:17:21Z</updated>

		<summary type="html">&lt;p&gt;Dgarratt: Updated by push_wiki.py&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Middleware4j is a file-based message transformation and routing engine. It was originally developed as a companion component to [[Commander4j]], but has no dependencies on it and can be used as a standalone middleware solution for any system integration requirement.&lt;br /&gt;
&lt;br /&gt;
== Purpose ==&lt;br /&gt;
&lt;br /&gt;
Many manufacturing and logistics sites need to exchange data between systems that use incompatible file formats — for example, sending production output data from Commander4j to an ERP system that expects CSV or fixed-column ASCII files, or receiving process orders from SAP in IDOC format and converting them to Commander4j&#039;s XML format. Middleware4j handles these conversions automatically, running continuously in the background as a service.&lt;br /&gt;
&lt;br /&gt;
== How It Works ==&lt;br /&gt;
&lt;br /&gt;
Middleware4j monitors a set of input directories for incoming files. When a file arrives, it is read by the appropriate &#039;&#039;&#039;connector&#039;&#039;&#039;, converted to an internal XML representation, optionally transformed by an XSLT stylesheet, and then written to one or more output destinations by one or more output connectors.&lt;br /&gt;
&lt;br /&gt;
This pipeline is defined by a &#039;&#039;&#039;[[Maps|Map]]&#039;&#039;&#039; — a configuration block that specifies:&lt;br /&gt;
* One input connector (how to read the incoming file)&lt;br /&gt;
* One or more output connectors (where to send the result and in what format)&lt;br /&gt;
* Optional XSLT stylesheets for transforming the data&lt;br /&gt;
* Optional conditions for routing to different outputs based on message content&lt;br /&gt;
&lt;br /&gt;
Multiple maps run simultaneously in background threads, each independently monitoring its own input directory.&lt;br /&gt;
&lt;br /&gt;
== Supported Formats ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Format !! Input !! Output&lt;br /&gt;
|-&lt;br /&gt;
| [[ASCII]] — fixed-column flat files || ✓ || ✓&lt;br /&gt;
|-&lt;br /&gt;
| [[CSV]] — delimited text files || ✓ || ✓&lt;br /&gt;
|-&lt;br /&gt;
| [[XML]] — structured XML documents || ✓ || ✓&lt;br /&gt;
|-&lt;br /&gt;
| IDOC — SAP IDOC format || ✓ || ✓&lt;br /&gt;
|-&lt;br /&gt;
| Excel — XLS/XLSX spreadsheets || ✓ || ✓&lt;br /&gt;
|-&lt;br /&gt;
| [[EMAIL]] — email with attachments || ✓ || ✓&lt;br /&gt;
|-&lt;br /&gt;
| [[RAW]] — unmodified file copy || ✓ || ✓&lt;br /&gt;
|-&lt;br /&gt;
| [[PDF_PRINT]] — print PDF to a named print queue || ✓ || ✓&lt;br /&gt;
|-&lt;br /&gt;
| [[SOCKET]] — TCP/IP socket transmission || || ✓&lt;br /&gt;
|-&lt;br /&gt;
| MQTT — publish to an MQTT broker || || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XSLT Transformation ==&lt;br /&gt;
&lt;br /&gt;
The transformation engine is built on &#039;&#039;&#039;Saxon 12&#039;&#039;&#039; (XSLT 2.0). Stylesheets can use standard XPath 2.0 expressions as well as a set of custom Middleware4j extension functions for string manipulation, date formatting, and reading from external reference data files.&lt;br /&gt;
&lt;br /&gt;
Over 60 sample XSLT stylesheets are included covering real-world integration scenarios between Commander4j and common ERP and MES systems (SAP, Sage, Tropos, B2MML S95, and others).&lt;br /&gt;
&lt;br /&gt;
== Deployment Modes ==&lt;br /&gt;
&lt;br /&gt;
Middleware4j can be run in two modes:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Mode !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Service&#039;&#039;&#039; || Runs as a background daemon (or Windows service) with no user interface. This is the normal production deployment.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;GUI&#039;&#039;&#039; || Launches a desktop window showing configured maps and real-time message counts. Useful for testing and monitoring.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
See [[Installation Middleware4j]] for how to deploy as a Windows service.&lt;br /&gt;
&lt;br /&gt;
== Relationship to Commander4j ==&lt;br /&gt;
&lt;br /&gt;
Middleware4j processes Commander4j&#039;s outbound XML messages (such as Production Declarations, Despatch Advice, and Equipment Tracking events) and converts them into whatever format an external system requires. It also handles inbound flows — receiving data from external systems (material masters, process orders, pallet status changes) in their native format and converting them to Commander4j&#039;s XML interface format for import.&lt;br /&gt;
&lt;br /&gt;
See also: [[Maps]], [[Connectors]], [[Middleware4j Example Configuration]], [[Installation Middleware4j]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Middleware4j]]&lt;/div&gt;</summary>
		<author><name>Dgarratt</name></author>
	</entry>
</feed>