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