After rpgc compiles an RPG source file, the output directory (default ./out) contains one or more .class files. These are standard JVM class files and run with java, like any Java program - no special launcher is needed.
This chapter covers the classpath you need, the runtime options available, and what to expect when the program ends.
Classpath Layout
Every compiled program requires the Triton RPG runtime library (triton-rpg.jar) on the classpath at run time. Beyond that, only the jars your program actually uses need to be present:
| Jar | When required |
|---|---|
triton-rpg.jar |
Always |
A JDBC driver (e.g. jt400.jar) |
Programs that use EXEC SQL, disk file I/O, or data queues |
| JLine 3.25.1 | Programs that use the terminal screen handler (interactive display files) |
The classpath must include both the runtime jar and the directory containing the compiled .class files. A minimal invocation:
java -cp out:triton-rpg.jar HELLO
On Windows, use semicolons instead of colons:
java -cp out;triton-rpg.jar HELLO
When the program uses a JDBC driver, add the driver jar:
java -cp out:triton-rpg.jar:jt400.jar INVOICES
When a program uses the terminal screen handler, JLine must also be on the classpath:
java -cp out:triton-rpg.jar:jline-3.25.1.jar MYAPP
Service modules compiled with --lib produce .class files the same way. Place them in the same output directory (or on the same classpath) as the calling program:
rpgc --lib empdet.rpgle
rpgc --bnddir APP=out employees.rpgle
java -cp out:triton-rpg.jar EMPLOYEES
The class name is derived from the source filename (upper-cased, extension stripped) unless --class-name was specified at compile time. See Class Name Derivation for the full rules.
Programs That Need No Database
A program that uses only DSPLY, performs calculations, or works with in-memory data needs no JDBC driver and no environment variables. Compile and run it with just the runtime library:
rpgc hello.rpgle
java -cp out:triton-rpg.jar HELLO
DSPLY Hello from rpgc!
This is the simplest case - no database, no display file, no JLine. It works in any environment where Java 17 is installed.
Screen Handler Selection
Programs that declare a WORKSTN display file need a screen handler to render the 5250 screen and capture input. The handler is selected at compile time with the --screen flag and baked into the generated main():
rpgc --screen ltd.whitehorn.rpg.handler.TerminalScreenHandler source.rpgle # default
rpgc --screen ltd.whitehorn.rpg.handler.GuiScreenHandler source.rpgle # Swing GUI
| Handler | Description | Requires |
|---|---|---|
TerminalScreenHandler |
Renders in a TTY terminal using ANSI escape sequences. This is the default. | JLine on the classpath; an interactive terminal (stdin must be a TTY) |
GuiScreenHandler |
Renders in a Swing desktop window. Works without a TTY. | A graphical desktop environment |
HeadlessScreenHandler |
No-UI handler for embedded use, driven at the raw character-grid level. | Nothing beyond the runtime library |
Run a terminal program:
java -cp out:triton-rpg.jar:jline-3.25.1.jar MYAPP
Run the same program with the Swing GUI handler (if compiled with GuiScreenHandler):
java -cp out:triton-rpg.jar MYAPP
A program that declares no WORKSTN display file has no screen handler at all, regardless of the --screen flag. DSPLY messages go to standard output without requiring a TTY or JLine. The --screen flag only affects programs with display file I/O.
For the full details on screen handlers - function keys, subfile support, INFDS population, and the headless bridge - see Screen Handlers.
JDBC Connection at Runtime
Programs that use embedded SQL (EXEC SQL), disk file I/O (F-spec DISK files), or data queues need a JDBC connection. The generated main() bootstraps the connection from environment variables before the program runs.
Required Environment Variables
| Variable | Default name | Required | Description |
|---|---|---|---|
| JDBC URL | JDBC_URL |
Yes | Connection URL (e.g. jdbc:as400://myhost/MYLIB) |
| JDBC Driver | JDBC_DRIVER |
Yes | Fully-qualified driver class (e.g. com.ibm.as400.access.AS400JDBCDriver) |
| JDBC User | JDBC_USER |
No | Database username |
| JDBC Password | JDBC_PASSWORD |
No | Database password |
Both JDBC_URL and JDBC_DRIVER must be set, or the program fails at startup with a clear error message. If JDBC_USER and JDBC_PASSWORD are both unset, the connection is opened without credentials.
Example: Running with Db2 for i
export JDBC_URL="jdbc:as400://myhost/MYLIB"
export JDBC_DRIVER="com.ibm.as400.access.AS400JDBCDriver"
export JDBC_USER="MYUSER"
export JDBC_PASSWORD="MYPASS"
java -cp out:triton-rpg.jar:jt400.jar INVOICES
Example: Running with SQL Server
export JDBC_URL="jdbc:sqlserver://localhost:1433;databaseName=MYDB;encrypt=false"
export JDBC_DRIVER="com.microsoft.sqlserver.jdbc.SQLServerDriver"
export JDBC_USER="sa"
export JDBC_PASSWORD="MyPassword"
java -cp out:triton-rpg.jar:mssql-jdbc.jar INVOICES
The same compiled program runs against any supported backend - the database is selected at runtime from the connection, not fixed at compile time. See Database Backends for the full list.
Custom Environment Variable Names
If the default variable names conflict with your deployment, override them at compile time:
rpgc --jdbc-url-env MY_DB_URL \
--jdbc-user-env MY_DB_USER \
--jdbc-password-env MY_DB_PASS \
--jdbc-driver-env MY_DB_DRIVER \
MYPROGRAM.rpgle
The overridden names are baked into the compiled class. At runtime, set the variables you named:
export MY_DB_URL="jdbc:as400://myhost/MYLIB"
export MY_DB_DRIVER="com.ibm.as400.access.AS400JDBCDriver"
java -cp out:triton-rpg.jar:jt400.jar MYPROGRAM
See Overriding Environment Variable Names for details.
Putting It All Together
Here are complete examples for common scenarios, from simplest to most involved.
Batch calculation (no database, no display):
rpgc payroll.rpgle
java -cp out:triton-rpg.jar PAYROLL
Interactive program with terminal display (Db2 for i):
rpgc --dds-path qddssrc ordentry.rpgle
export JDBC_URL="jdbc:as400://myhost/MYLIB"
export JDBC_DRIVER="com.ibm.as400.access.AS400JDBCDriver"
export JDBC_USER="MYUSER"
export JDBC_PASSWORD="MYPASS"
java -cp out:triton-rpg.jar:jt400.jar:jline-3.25.1.jar ORDENTRY
Multi-program application with a service module:
rpgc --lib empdet.sqlrpgle
rpgc --include-path . --dds-path qddssrc --bnddir APP=out employees.sqlrpgle
export JDBC_URL="jdbc:as400://myhost/MYLIB"
export JDBC_DRIVER="com.ibm.as400.access.AS400JDBCDriver"
export JDBC_USER="MYUSER"
export JDBC_PASSWORD="MYPASS"
java -cp out:triton-rpg.jar:jt400.jar:jline-3.25.1.jar EMPLOYEES
Exit Codes
The generated main() translates the program's RPG-level outcome into a process exit code:
| Exit code | Meaning |
|---|---|
0 |
The program completed normally - it set on *INLR and returned, or executed RETURN without *INLR. |
2 |
A halt indicator (H1 - H9) ended the program. A message identifying the indicator is written to standard error before exit. |
1 |
An unhandled exception terminated the program - a runtime error with no MONITOR, (E) extender, or error indicator to catch it. A stack trace is written to standard error. |
A build script or process supervisor should treat any non-zero exit as a failure. Exit code 2 distinguishes an orderly halt (operator cancel, end-of-job) from a crash (1).
DSPLY output and program results go to standard output. Halt messages, exception traces, and the JDBC bootstrap's own error messages go to standard error. The two streams are separate, so redirecting stdout captures the program's output without the diagnostics mixed in:
java -cp out:triton-rpg.jar REPORT > report.txt