简体   繁体   English

Spring 批处理 - 未关闭 - 由于 Static 方法调用

[英]Spring Batch - Not Shutting down - Due to Static Method call

I have completed a spring batch (Standalone Jar) in Spring Boot + CommandLineRunner.我已经在 Spring Boot + CommandLineRunner 中完成了一个 spring 批处理(独立 Jar)。 But the JVM is not getting shutdown after completion.但是 JVM 完成后没有关机。 After doing some research initially I thought its not shutting down because of below reasons.在最初做了一些研究之后,我认为它没有因为以下原因而关闭。

1. I am not closing the spring application context at the end ofcommandline runner. 1. 我没有在命令行运行器末尾关闭 spring 应用程序上下文。
2. Executor service is not shutdown properly which might have caused the JVM from shutting down. 2. Executor服务没有正常关闭,可能导致JVM无法关闭。

I dont want to call system.exit which is a forceful shutdown.我不想调用 system.exit 这是一个强制关闭。

I tried closing the application context and also verified executor service is shutdown using isShutdown method (returns true).我尝试关闭应用程序上下文,并且还使用 isShutdown 方法验证了执行程序服务已关闭(返回 true)。

Then I found out the root cause, it is because I am calling a static method which is the culprit.然后我找到了根本原因,这是因为我正在调用 static 方法,这是罪魁祸首。 When I commented the static method call, the job was shutting down gracefully even if I dont close the application context explicitly.当我评论 static 方法调用时,即使我没有明确关闭应用程序上下文,作业也会正常关闭。

I am not sure why this behavior and do I need to convert everything to objects or is there something else I am missing here.我不确定为什么会出现这种行为,我是否需要将所有内容都转换为对象,或者我在这里还缺少其他东西。 Can someone please throw some light.有人可以请放一些光。

Main Class主Class

    @SpringBootApplication
@ComponentScan(basePackages = "com.acn.abp.printbatch")
@EnableTransactionManagement
@ImportResource({ "ABPBatchInfrastructure.xml", "financeBillPayAppConfig.xml" })
public class financeBillPayFileUploadApplication extends PrintBatchConstants implements CommandLineRunner {

    @Autowired
    private NotifyConfig notify;

    @Autowired
    private ApplicationContext ctx;

    static final Logger logger = LoggerFactory.getLogger(financeBillPayFileUploadApplication.class);

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(financeBillPayFileUploadApplication.class);

        application.setBannerMode(Banner.Mode.OFF);
        application.run(args);

    }

    @Override
    public void run(String... args) throws Exception {

        logger.info(notify.getEnvironment());

        JobLauncher jobLauncher = ctx.getBean(JobLauncher.class);
        Job job = ctx.getBean(Job.class);

        jobLauncher.run(job,
                new JobParametersBuilder()
                .addString(batchDocumentClass, "InvoiceStatementDocumentation")
                .addString(batchType, "2020-06-04")
                .addString(batchEmailID, notify.getSupportEmailId())
                .addString(batchEnvironment, notify.getEnvironment())
                .toJobParameters());
        
System.out.println("Here cxf");

((ConfigurableApplicationContext)ctx).close();


    }

}

Below Class which is causing the problem.在导致问题的 Class 下面。 If I comment out below code then everything works perfectly.如果我在下面的代码中注释掉,那么一切都会完美运行。

          populateItemDocuments(job, printConfig.geteCMObjectStore(), printConfig.geteCMUserId());

Class file where this method is called调用此方法的 Class 文件

@Component
public class DuplexWorker implements Callable {

    static final Logger logger = LoggerFactory.getLogger(DuplexWorker.class);
    @Autowired
    private ManageFormService formgmtClient;
    @Autowired
    private PostScriptService postScriptService;
    @Autowired
    private BarcodeService barcodeService;

    private static CfBatchPrintConfiguration printConfig;
    
    private static CfPersistenceUtil dbUtilService;
    private static FilenetDocumentRetrieval docmgmtClient;

       @Autowired
       public DuplexWorker(CfPersistenceUtil dbUtilService,CfBatchPrintConfiguration printConfig,FilenetDocumentRetrieval docmgmtClient) {
           DuplexWorker.dbUtilService = dbUtilService;
           DuplexWorker.printConfig = printConfig;
           DuplexWorker.docmgmtClient=docmgmtClient;
       }

    
    private MailUtil mailUtil;
    
    private NotifyConfig notify;
    
    private List<PrintJobItem> printJobItems;
    
    private List<String> groupIds;
    
    
    private ArrayList duplexJobs;
    private String groupId;
    private CountDownLatch latch;

    
    public DuplexWorker(ArrayList duplexJobs, String groupId,CountDownLatch latch) {
        super();
        this.latch=latch;
        this.duplexJobs = duplexJobs;
        this.groupId = groupId;
    }
    public DuplexWorker(CountDownLatch latch, MailUtil mailUtil,NotifyConfig notify,List<PrintJobItem> findByPrintStatusEquals,List<String>groupIds) {
        this.latch=latch;
        this.mailUtil=mailUtil;
        this.notify=notify;
        this.printJobItems=findByPrintStatusEquals;
        this.groupIds=groupIds;

    }
    @Override
    public Object call() throws Exception {
        
        try {
        
        if ((duplexJobs != null) && (!duplexJobs.isEmpty())) {
            
              String prevJobId = null;
              int docCount = 0;
              CvPrintJob consolidatedPrintJob = (CvPrintJob)duplexJobs.get(0);

            
              ArrayList printItems = new ArrayList();
              
              if (consolidatedPrintJob != null)
              { 
                  
                  ArrayList items = consolidatedPrintJob.getPrintJobItems();
                  int numPages = 0;
                  if ((items != null) && (!items.isEmpty()))
                  {

                      CvPrintJobItem firstItem = (CvPrintJobItem)items.get(0);
                      
                      numPages = CfBatchPrintUtil.getItemTotalPages(firstItem);
                      logger.info("Item Total Pages == " + numPages);
                      logger.info("Job Item Page Limit == " + 
                        printConfig.getJobItemPageLimit());
                      consolidatedPrintJob.setSequence(firstItem.getSequence());

                  
                }
                  if (numPages <= printConfig.getJobItemPageLimit())
                  {
                    consolidatedPrintJob.setHasLargeItems(false);
                    logger.info("Item setHasLargeItems == false");
                  }
                  else
                  {
                    consolidatedPrintJob.setHasLargeItems(true);
                    logger.info("Item setHasLargeItems == true");
                  }

              }
              
              ArrayList startBannerDataList = new ArrayList();
              ArrayList barcodeList = new ArrayList();
              ArrayList barcodeCorresPageCount = new ArrayList();
              ArrayList statementNumberList = new ArrayList();
              for (int i = 0; i < duplexJobs.size(); i++)
              {
                CvPrintJob job = (CvPrintJob)duplexJobs.get(i);
                if ((prevJobId == null) || 
                  (!prevJobId.equalsIgnoreCase(job.getJobId()))) {
                  docCount = 0;
                }
                
                  populateItemDocuments(job, printConfig.geteCMObjectStore(), printConfig.geteCMUserId());
              }
              
              consolidatedPrintJob.setPrintJobItems(printItems);
              
   }
            else
            {
              logger.info("====================================================================");
              
              logger.info("=================>> No DUPLEX jobs to process <<===================");
              
              logger.info("====================================================================");
            }
            duplexJobs = null;
          
             
            this.latch.countDown();
            System.gc();
                return null;
                
        }catch(Exception e) {
            e.printStackTrace();
            return null;
        }
        
    }
    
      public static void populateItemDocuments(CvPrintJob job, String objectStore, String userid)
                throws CfException
              {
                
                logger.info("Enters populateItemDocuments");
                try
                {
                  ArrayList items = job.getPrintJobItems();
                  job.setIsProcess(true);
                  ArrayList modelDocList = null;
                  logger.info("Items size::::::" + items.size());
                  for (int i = 0; i < items.size(); i++)
                  {
                    modelDocList = new ArrayList();
                    CvPrintJobItem x = (CvPrintJobItem)items.get(i);
                    ArrayList guidList = x.getGuidList();
                    if ((guidList != null) && (!guidList.isEmpty())) {
                      modelDocList.addAll(guidList);
                    }
                    logger.info("guidList size::::::" + guidList.size());
                    
                    CvRenderPayloadRequest cvRenderPayloadRequest = null;
                    if ((modelDocList != null) && (!modelDocList.isEmpty()))
                    {
                      cvRenderPayloadRequest = new CvRenderPayloadRequest();
                      logger.info("Before creating CvRenderPayloadRequest");
                      logger.info("Document Class::: " + 
                        x.getDocumentClass());
                      cvRenderPayloadRequest.setDocumentClass(
                        x.getDocumentClass());
                      cvRenderPayloadRequest.setGuid(modelDocList);
                      cvRenderPayloadRequest.setUserId(userid);
                      logger.info("After creating the CvRenderPayloadRequest");
                      try
                      {
                        if (cvRenderPayloadRequest != null)
                        {
                          List pdfContents = docmgmtClient.retrieveDocument(cvRenderPayloadRequest.getGuid());
                          if ((pdfContents != null) && 
                            (!pdfContents.isEmpty()))
                          {
                            logger.info(
                              "PDF contents sizenew::::::::::::::" + pdfContents.size());
                            Iterator pdfItr = pdfContents.iterator();
                            while (pdfItr.hasNext())
                            {
                              byte[] contents = (byte[])pdfItr.next();
                              
                              CvPrintJobItem item = (CvPrintJobItem)items.get(i);
                              item.addDocumentList(contents);
                              
                              int filenetpagecount = 100;
                              item.setPageCountFromFileNet(filenetpagecount);
                              

                              logger.info("PageCOunt from Filenet " + filenetpagecount);
                            }
                          }
                        }
                      }
                      catch (Exception e)
                      {
                        e.printStackTrace();
                        throw new CfException(" Error populating documents" + e);
                      }
                    }
                  }
                }
                catch (Exception e)
                {
                  e.printStackTrace();
                  throw new CfException(" Error populating documents" + e);
                }
                logger.info("Exits populateItemDocuments");
              }
              

First of all you are using Tomcat server that runs the application.首先,您使用的是运行应用程序的 Tomcat 服务器。 If you want to make standalone spring application you can configure like below如果您想制作独立的 spring 应用程序,您可以配置如下

@Configuration
public class ApplicationMain {

    @Bean
    public Stackoverflow stackoverflow() {
        return new Stackoverflow ();
    }

    public static void main(String[] args) {
        ConfigurableApplicationContext configurableApplicationContext = new AnnotationConfigApplicationContext(ApplicationMain.class);
        System.out.println(configurableApplicationContext.getBean("stackoverflow"));
    }
}

'JVM is not getting shutdown after completion.' 'JVM 在完成后没有关闭。' is normal behavior for Tomcat server because it waits for request to handle.是 Tomcat 服务器的正常行为,因为它等待请求处理。

You can give basepackage like below你可以像下面这样给出基本包

new AnnotationConfigApplicationContext("com.example");

it will scan the package for you它将为您扫描 package

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM