当前位置: 首页 > 知识库问答 >
问题:

Spring Batch-未关闭-由于静态方法调用

姜森
2023-03-14

我已经在Spring Boot CommandLineRunner中完成了一个spring批处理(独立的Jar)。但是JVM不会在完成后关闭。在做了一些调查后,我认为它没有关闭是因为以下原因。

1.我没有在命令行运行器的末尾关闭spring应用程序上下文
2.执行器服务未正确关闭,这可能导致JVM关闭。

我不想调用system.exit,这是一个强制关闭。

我尝试关闭应用程序上下文,并使用isShutdown方法验证了executor服务是否已关闭(返回true)。

然后我发现了根本原因,这是因为我调用的静态方法是罪魁祸首。当我对静态方法调用进行注释时,即使我没有显式关闭应用程序上下文,作业也会正常关闭。

我不知道为什么会有这种行为,我是否需要将所有内容转换为对象,或者我还缺少其他东西。有人能扔些光吗?

主要类别

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


    }

}

下面导致问题的类。如果我在下面的代码中注释掉,那么一切都可以完美运行。

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

调用此方法的类文件

@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");
              }
              

共有1个答案

易琛
2023-03-14

首先,您使用运行应用程序的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");

它将为您扫描包裹

 类似资料:
  • 我最近对 PHP 5.4 进行了更新,但收到有关静态和非静态代码的错误。 这是错误: 这是第371行: 我希望有人能帮忙。

  • 问题内容: 尝试在静态类中调用非静态方法时遇到错误。 无法从类型播放中静态引用非静态方法methodName() 我不能使该方法静态,因为这也给我一个错误。 此静态方法无法从xInterface隐藏实例方法 有什么办法可以在另一个静态方法中轮回调用非静态方法?(这两种方法位于单独的包和单独的类中)。 问题答案: 从静态方法中调用非静态方法的唯一方法是使类的实例包含非静态方法。根据定义,非静态方法是

  • 我正在使用存储库模式并尝试建立模型之间的关系。当我尝试运行存储()方法(在控制器中),该方法试图使用用户()方法(与方模型建立关系)时,我收到以下错误消息: 非静态方法不应该静态调用::user(),假设$this来自不兼容的上下文 我不明白为什么在尝试运行user()relationship方法时会出现此错误,但所有其他方法(包括$this- 以下是相关代码:

  • 问题内容: 我正在尝试使用此功能,但正在收到消息。 我可以简单地使其静态化,从而解决了我的问题,但是如果不走那条路线怎么办。我想保持方法非静态。 以下是一些代码,可让您了解发生了什么: 问题答案: 创建您的课程的实例 这是一个实例方法,它需要一个实例来访问它。请阅读有关类和对象的官方教程。

  • 问题内容: 我遇到了一个涉及静态泛型方法的奇怪情况。这是代码: 我为什么不必在表达式中指定任何类型参数?这是某种类型推断吗?如果我想对此进行明确说明,如何指定类型参数? 问题答案: 是的,根据JLS第15.12.2.8节,这是基于分配目标的类型推断。明确地说,您可以这样称呼:

  • 我一直试图用我的验证代码进行php pear验证,但我收到的都是严格标准错误--问题是什么?我如何修复它? 电子邮件验证.php