簡體   English   中英

Spring 批處理 - 未關閉 - 由於 Static 方法調用

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

我已經在 Spring Boot + CommandLineRunner 中完成了一個 spring 批處理(獨立 Jar)。 但是 JVM 完成后沒有關機。 在最初做了一些研究之后,我認為它沒有因為以下原因而關閉。

1. 我沒有在命令行運行器末尾關閉 spring 應用程序上下文。
2. Executor服務沒有正常關閉,可能導致JVM無法關閉。

我不想調用 system.exit 這是一個強制關閉。

我嘗試關閉應用程序上下文,並且還使用 isShutdown 方法驗證了執行程序服務已關閉(返回 true)。

然后我找到了根本原因,這是因為我正在調用 static 方法,這是罪魁禍首。 當我評論 static 方法調用時,即使我沒有明確關閉應用程序上下文,作業也會正常關閉。

我不確定為什么會出現這種行為,我是否需要將所有內容都轉換為對象,或者我在這里還缺少其他東西。 有人可以請放一些光。

主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();


    }

}

在導致問題的 Class 下面。 如果我在下面的代碼中注釋掉,那么一切都會完美運行。

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

調用此方法的 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");
              }
              

首先,您使用的是運行應用程序的 Tomcat 服務器。 如果您想制作獨立的 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 在完成后沒有關閉。' 是 Tomcat 服務器的正常行為,因為它等待請求處理。

你可以像下面這樣給出基本包

new AnnotationConfigApplicationContext("com.example");

它將為您掃描 package

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM