z/OS上Java程序的用户指定异常终止代码

z/OS上Java程序的用户指定异常终止代码,java,java-native-interface,zos,Java,Java Native Interface,Zos,如果我在JZOS启动器中设置了一个环境变量 导出JZOS\u ABEND\u出口=50 然后在Java代码中调用System.exit51,程序将按如下方式终止: IEF450I MYPROG JAVAJVM CREATE-ABEND=S000 U3333原因=00000010 是否可以指定异常终止代码,例如将其改为U999而不是U3333。我在中找到了一个对leabend例程“CEE3ABD”的隐晦引用,但如果有人能指出如何从Java调用此例程,我将不胜感激。我是否需要编写JNI代码并从C语言

如果我在JZOS启动器中设置了一个环境变量

导出JZOS\u ABEND\u出口=50

然后在Java代码中调用System.exit51,程序将按如下方式终止:

IEF450I MYPROG JAVAJVM CREATE-ABEND=S000 U3333原因=00000010


是否可以指定异常终止代码,例如将其改为U999而不是U3333。我在中找到了一个对leabend例程“CEE3ABD”的隐晦引用,但如果有人能指出如何从Java调用此例程,我将不胜感激。我是否需要编写JNI代码并从C语言调用它?或者有更简单的方法吗?

我研究了一下,发现对于31位JZO,您还可以通过LE运行时选项注册用户编写的条件处理程序,并使用它捕获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_数据,以便识别U3333

如果您想发出不同的ABEND,那么可以调用CEE3ABD。请注意,我只通过调用CEE3ABD(CLEANUP=0)来禁用任何进一步的LE条件处理,从而使其工作。我猜在其他情况下会出现问题,因为当当前处理程序尚未退出时,会引发另一个条件

这里是我用PL/I编写的hanlder示例,但如果您喜欢,也可以用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;                                                               

我仔细研究了一下,发现对于31位JZO,您还可以通过LE运行时选项注册用户编写的条件处理程序,并使用它捕获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_数据,以便识别U3333

如果您想发出不同的ABEND,那么可以调用CEE3ABD。请注意,我只通过调用CEE3ABD(CLEANUP=0)来禁用任何进一步的LE条件处理,从而使其工作。我猜在其他情况下会出现问题,因为当当前处理程序尚未退出时,会引发另一个条件

这里是我用PL/I编写的hanlder示例,但如果您喜欢,也可以用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;                                                               

我通过使用JNI调用解决了这个问题。我不依赖用户编写的退出处理程序,而是直接从Java调用方法Abend.Abend

public class Abend {
    public static native void abend(int abcode, int reasoncode, int cleanup);
}
和实施:

#include <stdio.h>
#include <ctest.h>
#include "Abend.h"

#define _POSIX_SOURCE
#include <unistd.h>

JNIEXPORT void JNICALL Java_Abend_abend
  (JNIEnv * end, jclass class, jint code, jint reasoncode, jint timing) {
   /* fprintf(stderr, "values %d %d %d\n", code, reasoncode, timing);*/
   __cabend(code, reasoncode, timing);
}

我通过使用JNI调用解决了这个问题。我不依赖用户编写的退出处理程序,而是直接从Java调用方法Abend.Abend

public class Abend {
    public static native void abend(int abcode, int reasoncode, int cleanup);
}
和实施:

#include <stdio.h>
#include <ctest.h>
#include "Abend.h"

#define _POSIX_SOURCE
#include <unistd.h>

JNIEXPORT void JNICALL Java_Abend_abend
  (JNIEnv * end, jclass class, jint code, jint reasoncode, jint timing) {
   /* fprintf(stderr, "values %d %d %d\n", code, reasoncode, timing);*/
   __cabend(code, reasoncode, timing);
}

我已经很长时间没有在zos上做任何事情了,但是在你的链接上的链接似乎是相关的。还有,你不应该用50吗?基本上,我认为建议使用JCL作业控制语言来监视退出代码并生成适当的异常终止代码。如果有这样一个C库,您应该能够使用JNI或JNA调用它。但我认为链接的批处理解决方案可能更简单。当我说很长一段时间后,zos在Mini上被称为OS/390和OS/400。。。。它总是那么漂亮。292-293页是我想你想要的部分。但是,我不知道第4页、第26页和第54页是否故意空白。因此,至少与我对它们的记忆相比,它们似乎滑倒了一些。答案可能在某个地方的文档中。至于为什么它能像它那样工作,他们仍然有50-70年代的软件,运行银行、社会保障和失业等,而这些东西当时必须通过穿孔卡片来运行。IBM通常不得不去发明一些方法来实现它。@ElliottFrisch 51是正确的-任何大于JZOS_ABEND_EXIT的值都会触发异常终止。@ElliottFrisch您可能会发现IBM文档的版本比PDF更友好。我已经很久没有在zos上做过任何事情了,但您的链接似乎很相关。还有,你不应该用50吗?基本上,我认为建议使用JCL作业控制语言来监视退出代码并生成适当的异常终止代码。如果有这样一个C库,您应该能够使用JNI或JNA调用它。但我认为链接的批处理解决方案可能更简单。当我说很长一段时间后,zos在Mini上被称为OS/390和OS/400。。。。它总是那么漂亮。292-293页是我想你想要的部分。但是,我不知道第4页、第26页和第54页是否正确
故意空白。因此,至少与我对它们的记忆相比,它们似乎滑倒了一些。答案可能在某个地方的文档中。至于为什么它能像它那样工作,他们仍然有50-70年代的软件,运行银行、社会保障和失业等,而这些东西当时必须通过穿孔卡片来运行。IBM通常不得不去发明一些方法来实现它。@ElliottFrisch 51是正确的-任何大于JZOS_ABEND_EXIT的值都会触发异常终止。@ElliottFrisch您可能会发现IBM文档的版本比PDF更友好。