如果我在 JZOS 启动器中设置环境变量
EXPORT JZOS_ABEND_EXIT=50
然后在 Java 代码中调用 System.exit(51)
程序将像这样终止:
IEF450I MYPROG JAVAJVM CREATE - ABEND=S000 U3333 REASON=00000010
是否可以指定异常结束代码,例如将其设为 U999 而不是 U3333。我在 How to trigger a user ABEND? 中发现了对 LE 异常终止例程“CEE3ABD”的神秘引用,但如果有人能指出如何从 Java 调用此例程,我将不胜感激。我需要编写JNI代码并从C语言调用它吗?或者有更简单的方法吗?
最佳答案
我玩了一下,发现对于 31 位 JZOS,您还可以通过 LE-runtime-options 注册用户编写的条件处理程序,并使用它来捕获 U3333 异常结束并将其更改为其他内容。
不幸的是(从 z/OS 2.3 开始)似乎无法通过 64 位 LE 中的运行时选项注册条件处理程序。
在 JCL 中,您可以通过 CEEOPTS DD 语句添加选项:
//CEEOPTS DD *
ENVAR("JZOS_ABEND_EXIT=50")
USRHDLR(MYHDLR)
/*
在处理程序中,您可以分析消息 CEE3250(用户启动的异常结束)的 LE-condition.token。在这种情况下,您可以调用 CEEGQDT 来获取包含异常结束代码和原因代码的特定于异常结束的 q_data,以便您可以识别 U3333。
如果您想发出不同的异常终止,您可以调用 CEE3ABD。请注意,我只能通过使用 CLEANUP = 0
调用 CEE3ABD 来禁用任何进一步的 LE 条件处理,才能使其正常工作。我猜想否则会出现问题,因为在当前处理程序尚未退出时引发了另一个条件。
这是我用 PL/I 编写的示例处理程序,但也可以用 COBOL 或 C(或汇编程序,如果您愿意的话......)来完成
MYHDLR: PROC(P1,P2,P3,P4) OPTIONS(BYVALUE FETCHABLE);
DCL(P1,P2,P3,P4) POINTER;
/* DCL CUR_COND CHAR(12); */ /*P1->*/
DCL TOKEN BIN FIXED(31) BASED(P2);
DCL RESULT BIN FIXED(31) BASED(P3);
/* DCL NEW_COND CHAR(12); */ /*P4->*/
DCL COND_PTR POINTER;
DCL 1 COND_STRU BASED(COND_PTR),
2 SEVERITY BIN FIXED(15),
2 MESSAGE BIN FIXED(15),
2 FLAGS BIT(8),
2 FACILITY CHAR(3),
2 ISI BIN FIXED(31);
DCL QDATA_PTR POINTER;
DCL 1 QDATA BASED(QDATA_PTR),
2 QCOUNT_PTR POINTER,
2 ABCODE_PTR POINTER,
2 REASON_PTR POINTER;
DCL ABCODE BIN FIXED(31) BASED(ABCODE_PTR);
DCL REASON BIN FIXED(31) BASED(REASON_PTR);
DCL MYABCODE BIN FIXED(31);
DCL CLEANUP BIN FIXED(31);
DCL FEEDBACK CHAR(12);
DCL SYSPRINT FILE;
DCL (CEEGQDT,CEE3ABD) ENTRY OPTIONS(ASM);
PUT SKIP LIST('HANDLER CALLED');
/* ANALYZE CONDITION */
COND_PTR = P1;
PUT SKIP EDIT(FACILITY,MESSAGE,SEVERITY)(A,F(4),F(4));
IF FACILITY = 'CEE' & MESSAGE = 3250 THEN DO;
PUT SKIP LIST('ABEND ISSUED');
CALL CEEGQDT(COND_STRU,QDATA_PTR,FEEDBACK);
COND_PTR = ADDR(FEEDBACK); /* REUSE TOKEN STRUCTURE */
PUT SKIP EDIT(SEVERITY,ABCODE)(F(6),F(6));
IF SEVERITY = 0 & /* CEEGQDT CALL SUCCESSFUL */
ABCODE = 3333 /* ONLY HANDLE USER-ABEND U3333 */
THEN DO;
CLEANUP = 0; /* NO LE-CLEANUP */
MYABCODE = 100;
IF REASON = 51 THEN MYABCODE = 999;
CALL CEE3ABD(MYABCODE,CLEANUP);
END;
END;
ELSE DO;
PUT SKIP LIST('NO ABEND');
RESULT = 20; /* PERCOLATE CONDITION */
END;
END;
关于java - 用户为 z/OS 上的 Java 程序指定的 ABEND 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61263154/