When a shop installs a Java stored procedure, Db2 does not keep the JAR on a random HFS path that operators must remember. It stores the archive in the catalog, lists every class inside it, and ties the JAR identifier to rows in SYSIBM.SYSROUTINES. Generated routines (the older DSNTPSMP path) keep a second set of build-option rows. This page covers SYSIBM.SYSJAROBJECTS, SYSIBM.SYSJARCONTENTS, SYSIBM.SYSROUTINES_OPTS (often called SYSROUTINEOPTS), and the catalog queries you use to find routines on DB2 for z/OS.
A routine is a stored procedure or a user-defined function. The master inventory is always SYSIBM.SYSROUTINES. JAR tables are supporting objects: they exist so LANGUAGE JAVA routines can resolve classes without each developer shipping a private jar on the WLM address-space STEPLIB. Parameter details live in SYSIBM.SYSPARMS. EXECUTE privileges live in SYSIBM.SYSROUTINEAUTH. Native SQL procedure text lives on the routine row (TEXT / TEXT_ROWID) rather than in a JAR.
Think of the catalog as three layers for Java work:
If you skip the join and only look at SYSROUTINES, you can see that a procedure is JAVA but you cannot prove the JAR is still installed. If you only look at SYSJAROBJECTS, you see archives that nobody might be calling. Always join when you are diagnosing SQLCODE -430 or class-not-found failures after a REPLACE_JAR.
SYSJAROBJECTS contains one row for each JAR that has been installed into the subsystem with the SQLJ JAR procedures. The schema is SYSIBM. IBM describes the table as holding the binary large object that represents the installed JAR. Related auxiliary storage for the BLOB may appear as SYSIBM.SYSJARDATA in the catalog (the LOB auxiliary table behind JAR_DATA). You query SYSJAROBJECTS; you do not CREATE the auxiliary table yourself.
| Column | What it tells you |
|---|---|
| JARSCHEMA | Schema that owns the JAR identifier |
| JAR_ID | JAR name used on INSTALL_JAR and in CREATE PROCEDURE JAVA |
| OWNER | Authorization ID (or role) that owns the JAR object |
| JAR_DATA | BLOB of the installed archive (with JAR_DATA_ROWID) |
| PATH | Java class-resolution path associated with the JAR |
| CREATEDTS / ALTEREDTS | When the JAR was installed and last replaced |
JARSCHEMA plus JAR_ID is the qualified JAR name you pass to SQLJ.INSTALL_JAR and later to CREATE PROCEDURE ... JAVA. JAR_ID is not a z/OS data set name. PATH is the Java resolution path Db2 associates with that JAR so dependent classes in other JARs can be found. CREATEDTS versus ALTEREDTS tells you whether someone replaced the archive after the original install—vital when production still runs an old class file that developers thought they refreshed.
1234SELECT JARSCHEMA, JAR_ID, OWNER, PATH, CREATEDTS, ALTEREDTS FROM SYSIBM.SYSJAROBJECTS ORDER BY JARSCHEMA, JAR_ID;
Selecting JAR_DATA in SPUFI is rarely useful: it is a BLOB up to 100 MB. Use the identity columns for inventory. To change contents, call SQLJ.REPLACE_JAR with the new HFS or z/OS UNIX file. INSTALL_JAR fails if the JAR_ID already exists; REPLACE_JAR updates JAR_DATA and refreshes SYSJARCONTENTS. REMOVE_JAR deletes the catalog rows after you drop or alter routines that still reference the JAR.
Typical flow on z/OS:
After step 2, SYSJAROBJECTS has a row even if no procedure exists yet. That is normal: shops often install a shared utility JAR once, then create many procedures against it.
SYSJARCONTENTS contains information about the Java classes inside each installed JAR. IBM documents one row per class. Columns include JARSCHEMA, JAR_ID, CLASS (the fully qualified class name), CLASS_SOURCE (a CLOB of source when present), CLASS_SOURCE_ROWID, and IBMREQD.
CLASS is the column you search when a Java exception names a missing class. If com.shop.payroll.BonusCalc is not in SYSJARCONTENTS for the JAR_ID named on the procedure, REPLACE_JAR never contained that class—or you pointed the procedure at the wrong JAR_ID. CLASS_SOURCE is optional metadata; many production JARs are compiled-only and the CLOB is empty. Do not treat an empty CLASS_SOURCE as proof the class is missing; look at CLASS.
12345SELECT C.JARSCHEMA, C.JAR_ID, C.CLASS FROM SYSIBM.SYSJARCONTENTS C WHERE C.JARSCHEMA = 'PAYROLL' AND C.JAR_ID = 'PAYUTIL' ORDER BY C.CLASS;
Join to routines when you need “which procedure uses this class name”:
123456789SELECT R.SCHEMA, R.NAME, R.SPECIFICNAME, R.LANGUAGE, R.EXTERNAL_NAME, R.JARSCHEMA, R.JAR_ID, C.CLASS FROM SYSIBM.SYSROUTINES R INNER JOIN SYSIBM.SYSJARCONTENTS C ON C.JARSCHEMA = R.JARSCHEMA AND C.JAR_ID = R.JAR_ID WHERE R.LANGUAGE = 'JAVA' AND C.CLASS LIKE '%BonusCalc%';
EXTERNAL_NAME on SYSROUTINES is the Java method descriptor Db2 invokes. It must match a class that actually appears in SYSJARCONTENTS. Mismatches are a common cause of failures that look like WLM problems but are really catalog drift after a partial REPLACE_JAR.
Topic lists often say SYSIBM.SYSROUTINEOPTS. The IBM SQL Reference name is SYSIBM.SYSROUTINES_OPTS. The table contains one row for each generated routine—historically routines built by the Db2 for z/OS Procedure Processor DSNTPSMP—and records the build options used for that routine. IBM marks the external SQL procedure model as deprecated. Prefer native SQL procedures created with CREATE PROCEDURE and LANGUAGE SQL.
Rows can be inserted, updated, and deleted (unlike most catalog tables) because the procedure processor treated them as a build worksheet. Columns you will see in documentation include:
How each option group affects runtime:
12345SELECT SCHEMA, ROUTINENAME, BUILDSTATUS, BUILDDATE, SOURCEDSN, DEBUG_MODE FROM SYSIBM.SYSROUTINES_OPTS WHERE SCHEMA = 'PAYROLL' ORDER BY ROUTINENAME, BUILDDATE;
If this query returns no rows, that is expected for native SQL procedures and for ordinary COBOL EXTERNAL procedures that were compiled outside DSNTPSMP. Those objects never needed SYSROUTINES_OPTS. Do not invent rows to “document” a native procedure.
“Finding routines” is everyday catalog work: who owns PAY_CALC, is it JAVA or SQL, which WLM environment does it need, and who may CALL it. Start with SYSROUTINES, then fan out.
| You need | Look in |
|---|---|
| All procedures in a schema | SYSROUTINES ROUTINETYPE = 'P' |
| User-defined functions | SYSROUTINES ROUTINETYPE = 'F' |
| Java routines and their JAR | LANGUAGE = 'JAVA' plus JARSCHEMA / JAR_ID |
| Parameter list | SYSPARMS keyed by SCHEMA, NAME (or SPECIFICNAME) |
| EXECUTE privilege | SYSROUTINEAUTH for GRANTOR / GRANTEE / EXECUTEAUTH |
ROUTINETYPE on SYSROUTINES is the first filter. P means stored procedure. F means function. LANGUAGE tells you SQL, JAVA, COBOL, C, ASSEMBLE, and so on. ORIGIN distinguishes native SQL, external, sourced functions, and other implementation styles. WLM_ENVIRONMENT is blank for native SQL procedures that run in the Db2 engine; it is required for most external procedures because they run in a WLM-established address space.
123456SELECT SCHEMA, NAME, SPECIFICNAME, ROUTINETYPE, LANGUAGE, ORIGIN, WLM_ENVIRONMENT, JARSCHEMA, JAR_ID, CREATEDTS FROM SYSIBM.SYSROUTINES WHERE SCHEMA NOT LIKE 'SYS%' ORDER BY ROUTINETYPE, SCHEMA, NAME;
SYSPARMS has one row per parameter (and result columns for some function types). ORDINAL is the position. ROWTYPE (or equivalent parameter-mode column on your release) distinguishes IN, OUT, and INOUT for procedures. Join on schema and specific name so overloaded names do not mix signatures.
123456SELECT P.ORDINAL, P.PARMNAME, P.TYPENAME, P.LENGTH, P.SCALE, P.ROWTYPE FROM SYSIBM.SYSPARMS P WHERE P.SCHEMA = 'PAYROLL' AND P.SPECIFICNAME = 'PAY_CALC_SP' ORDER BY P.ORDINAL;
After a REMOVE_JAR or a failed REPLACE, SYSROUTINES can still name a JAR_ID that is gone from SYSJAROBJECTS. That left-join pattern is a standard health check:
1234567SELECT R.SCHEMA, R.NAME, R.JARSCHEMA, R.JAR_ID FROM SYSIBM.SYSROUTINES R LEFT OUTER JOIN SYSIBM.SYSJAROBJECTS J ON J.JARSCHEMA = R.JARSCHEMA AND J.JAR_ID = R.JAR_ID WHERE R.LANGUAGE = 'JAVA' AND J.JAR_ID IS NULL;
Rows returned here will fail at CALL time. Fix by reinstalling the JAR or altering the procedure to a JAR that exists. Also confirm the WLM application environment is started (-DISPLAY PROCEDURE and -DISPLAY WLM, plus SDSF for the stored-procedure address space). Catalog health does not start WLM for you.
SYSROUTINEAUTH records EXECUTE. EXECUTEAUTH values follow the usual catalog privilege encoding (granted, with grant option, or not held). Installation SYSADM can always manage routines; application IDs need an explicit GRANT EXECUTE unless PUBLIC holds it. When CALL fails with authorization SQLCODEs, query SYSROUTINEAUTH before rewriting Java.
SYSJAVAPATHS describes the complete JAR class-resolution path for a JAR_ID. SYSJARCLASS_SOURCE may hold class source associated with contents. SYSROUTINES_SRC held generated SQL source for older external SQL procedures (also deprecated). None of those replace SYSROUTINES as the inventory. When you document a subsystem, export SYSROUTINES plus SYSJAROBJECTS as a pair so disaster recovery can reinstall JARs in the same schema names the procedures expect.
IBMREQD on these tables marks rows that Db2 itself requires. Do not DELETE IBMREQD = Y rows. User JARs have IBMREQD = N and are removable with REMOVE_JAR after dependents are dropped.
Imagine a toy workshop. SYSROUTINES is the list of toy machines (procedures and functions) and which room they run in. A Java machine needs a box of LEGO instructions. SYSJAROBJECTS is the box (the whole JAR). SYSJARCONTENTS is the paper listing every instruction sheet inside the box (each class). SYSROUTINES_OPTS is an old recipe card from when Db2 used to build a machine for you with a special builder (DSNTPSMP). New machines are built with CREATE PROCEDURE and do not need that recipe card. If you throw away the LEGO box but leave the machine on the list, the machine cannot play.
1. What does SYSIBM.SYSJAROBJECTS store?
2. How do you list Java classes inside an installed JAR?
3. What is SYSIBM.SYSROUTINES_OPTS used for?
4. Which catalog table is the starting point for finding stored procedures and functions?
5. How do you install a JAR into Db2 for z/OS?