DEV Community

Cover image for Libraries, objects, library list, IFS and jobs: the IBM i mental model web developers lack
Rainierio.dev
Rainierio.dev

Posted on Originally published at rainierio.dev

Libraries, objects, library list, IFS and jobs: the IBM i mental model web developers lack

Libraries, objects, library list, IFS and jobs: the IBM i mental model web developers lack

When I first sat in front of a 5250 screen, I kept looking for a file tree. There isn't one in the place where most of your work lives. IBM i is object-based, not file-based, and almost every confusing moment for a web developer comes from that one difference.

This article maps each IBM i concept to its nearest Linux or web equivalent. The maps are approximate. I'll flag where they break.

The big picture in one table

IBM i Nearest Linux / web idea Where the analogy breaks
Library (*LIB) A flat directory / schema Libraries can't nest. One level only.
Object A typed file The OS knows the type and enforces what you can do with it.
Library list $PATH plus a search path for everything It resolves data files and programs, not just executables.
IFS Ordinary POSIX filesystem Lives alongside the library system, not instead of it.
Job A process with its own environment Carries its own library list, user, and message log.
Subsystem A systemd slice / worker pool config Defines memory pools and job routing.
Job log stderr plus an audit trail per process Kept per job, queryable after it ends.

Libraries and objects

A library is a container of objects. Think "schema" more than "folder". You can't put a library inside a library, so names carry meaning: PAYROLL, PAYROLLDEV, QGPL.

An object has a name, a library, and a type. The type decides which commands work on it. You don't "open" a program the way you open a file; you CALL it.

The types you'll meet in the first month:

Type What it is Web/Linux analogue
*PGM Compiled program A compiled binary
*SRVPGM Service program: shared procedures A shared library (.so)
*FILE Database table, view, source file, display file, printer file A table, plus UI and print definitions
*DTAARA Data area: one small value, like a config flag or counter A single-row config table or env var
*MSGQ Message queue A mailbox / log destination you can read and reply to
*JOBQ Job queue: batch jobs waiting to run A work queue (think Sidekiq or a cron backlog)
*OUTQ Output queue: holds spooled output A print spool

Notice that *FILE covers a lot. A DB2 table is a *FILE of attribute PF. A source member lives in a *FILE of attribute PF-SRC. Same type, different use.

Fully qualified, an object is LIBRARY/OBJECT, for example MYLIB/CUSTMAST. Try it:

WRKOBJ OBJ(MYLIB/*ALL) OBJTYPE(*ALL)
Enter fullscreen mode Exit fullscreen mode

That lists every object in MYLIB with its type. It's the closest thing to ls -l.

QSYS.LIB versus the IFS

There are really two filesystems.

  • QSYS.LIB: the native library system. Objects, libraries, members. Names are limited and traditionally uppercase.
  • IFS (Integrated File System): a normal hierarchical tree under /, with /home/YOURUSER, stream files, and permissions. It is POSIX-like and case-sensitive in the /root file system.

The two are connected. The IFS exposes libraries as a path:

/QSYS.LIB/MYLIB.LIB/CUSTMAST.FILE
Enter fullscreen mode Exit fullscreen mode

That's the same object as MYLIB/CUSTMAST, seen through the IFS. Git, Node.js, Python, and your .profile all live in the IFS side. RPG programs and database tables live on the QSYS.LIB side.

Library list resolution

You almost never write MYLIB/CUSTMAST in real code. You write CUSTMAST and the system finds it by walking the library list.

DSPLIBL
Enter fullscreen mode Exit fullscreen mode

The list has four parts, searched in this order:

  1. System portion: IBM libraries like QSYS, QSYS2.
  2. Product portion: libraries added by licensed products.
  3. Current library: a single library, where new objects get created by default.
  4. User portion: your own libraries.

The first match wins. If two libraries both contain a program called CALCTAX, whichever comes first in the list runs. This is $PATH behavior, with the same bugs: "works in test, breaks in prod" is very often a different library list.

Change it for your job:

ADDLIBLE LIB(MYLIB)
CHGCURLIB CURLIB(MYLIB)
Enter fullscreen mode Exit fullscreen mode

These affect only the current job. Other users keep their own lists.

Jobs, subsystems and job logs

Everything that runs is a job. Your 5250 sign-on is a job. A nightly batch run is a job. A web server request through an IBM i service can be a job too.

A job has:

  • a user profile and its authorities,
  • its own library list,
  • its own job log,
  • a place it runs, a subsystem.

A subsystem is a runtime environment. QINTER handles interactive sessions, QBATCH runs batch work from job queues, QUSRWRK hosts a lot of server jobs. A subsystem defines the memory pool and how jobs are routed in.

To see what's running:

WRKACTJOB
Enter fullscreen mode Exit fullscreen mode

You'll see columns for subsystem, user, job type, CPU, and status (RUN, MSGW for waiting on a message, DEQW for waiting on a queue). MSGW is the one to learn first. It means the job stopped and asked a human a question.

When a job fails, the job log tells you why. It's the first place I look.

DSPJOBLOG
Enter fullscreen mode Exit fullscreen mode

Run it right after a failed command in your own session. To find another job's log, use WRKACTJOB, take option 5 on the job, then option 10 to display the job log.

Submitting batch work and finding its output:

SBMJOB CMD(CALL PGM(MYLIB/NIGHTLY)) JOB(NIGHTLY) JOBQ(QBATCH)
WRKSPLF
Enter fullscreen mode Exit fullscreen mode

SBMJOB puts the command on a job queue. Printed output and job logs end up as spooled files in an output queue. WRKSPLF lists yours. It's the equivalent of looking in a log directory, except the OS manages the files.

Where source code lives

This trips up web developers hardest. Traditionally, RPG source is not a file. It is a member inside a source physical file:

MYLIB/QRPGLESRC(HELLO) reads as library / source file / member:

  1. Library MYLIB: The container
  2. Source file QRPGLESRC: A *FILE object that holds source members
  3. Member HELLO: One piece of source inside the source file
  • QRPGLESRC holds RPG source members, QCLSRC holds CL source, QDDSSRC holds DDS.
  • Records are fixed length (often 112 characters: 12 for sequence and date, 100 for text). That's one reason older RPG is column-bound.
  • You edit with STRSEU (old), RDi, or VS Code with Code for IBM i.

Modern practice puts source in the IFS as ordinary .rpgle, .clle, .sqlrpgle files, tracked in Git, and compiles from there using the SRCSTMF parameter. New projects should do this. Most legacy shops still keep source in source PFs, and you will have to read both.

A quick check of how many members exist in a source file:

SELECT SYSTEM_TABLE_MEMBER, LAST_SOURCE_UPDATE_TIMESTAMP
FROM QSYS2.SYSPARTITIONSTAT
WHERE SYSTEM_TABLE_SCHEMA = 'MYLIB'
  AND SYSTEM_TABLE_NAME = 'QRPGLESRC';
Enter fullscreen mode Exit fullscreen mode

This model underpins everything else: the roadmap puts it at stage 1, and AS400 vs iSeries vs IBM i covers the platform naming. Job logs and SBMJOB get a full treatment in CL programming essentials, and service programs (*SRVPGM) are explained in ILE modules, service programs and the binder.

Try it on PUB400

If you haven't got an account yet, start with Your free IBM i lab in 30 minutes: PUB400 + VS Code + Code for IBM i. Then, signed on to PUB400 in a 5250 session:

  1. Run DSPLIBL and note what's in the user portion.
  2. Run WRKOBJ OBJ(YOURUSERLIB/*ALL) OBJTYPE(*ALL) (PUB400 creates a personal library for your user; check DSPLIBL or WRKLIB for its exact name) and identify which entries are *FILE, *PGM, *DTAARA.
  3. Create a data area and read it back:
   CRTDTAARA DTAARA(YOURUSERLIB/MYFLAG) TYPE(*CHAR) LEN(10) VALUE('HELLO')
   DSPDTAARA DTAARA(YOURUSERLIB/MYFLAG)
Enter fullscreen mode Exit fullscreen mode
  1. Run WRKACTJOB, find your own interactive job, and press 5 then 10 to see its job log.
  2. In a terminal or VS Code, list /home/YOURUSER in the IFS and compare it to your library.

Resource limits on PUB400 are shared and some commands are restricted, so if one fails, read the message rather than assuming you broke it. DSPJOBLOG will tell you which authority was missing.

Best resources

  • IBM Docs, IBM i documentation: authoritative reference for every command and object type; search by command name
  • Code for IBM i docs: setting up VS Code, the Object Browser and IFS Browser to see both filesystems side by side
  • Barrett Otte, IBMi-Book: a free community-written book covering the system from a developer's angle
  • RPGPGM.com: Simon Hutchinson's long-running blog with practical IBM i and RPG how-tos
  • PUB400: free public IBM i to practice every command above

Next

Your first free-format RPG program

Related


Originally published on rainierio.dev. The full Learn IBM i track, with an Indonesian version, is at rainierio.dev/learn.

Top comments (0)