簡體   English   中英

如何在OSGI中使用Spring Batch

[英]How can I use Spring Batch with OSGI

我想將osgi與Spring批處理結合使用,以每天運行一份工作。 在這里我做了什么:

@Component
@EnableBatchProcessing
public class BatchConfiguration {


private JobBuilderFactory jobs;
public JobBuilderFactory getJobs() {
    return jobs;
}

public void setJobs(JobBuilderFactory jobs) {
    this.jobs = jobs;
}


private StepBuilderFactory steps;

private EmployeeRepository employeeRepository; //spring data repository

public EmployeeRepository getEmployeeRepository() {
    return employeeRepository;
}

@Reference
public void setEmployeeRepository(EmployeeRepository employeeRepository) {
    employeeRepository= employeeRepository;
}





public Step syncEmployeesStep() throws Exception{
    RepositoryItemWriter writer = new RepositoryItemWriter();
    writer.setRepository(employeeRepository);
    writer.setMethodName("save");
    return steps.get("syncEmployeesStep")
            .<Employee, Employee> chunk(10)
            .reader(reader())
            .writer(writer)
            .build();
}


public Job importEmpJob()throws Exception {
    return jobs.get("importEmpJob")
            .incrementer(new RunIdIncrementer())
            .start(syncEmployeesStep())
            .next(syncEmployeesStep())
            .build();
}


public ItemReader<Employee> reader() throws Exception {
    String jpqlQuery = "select a from Employee a";
        ServerEMF entityManager = new ServerEMF();
        JpaPagingItemReader<Employee> reader = new JpaPagingItemReader<Tariff>();
        reader.setQueryString(jpqlQuery);
        reader.setEntityManagerFactory(entityManager.getEntityManagerFactory());
        reader.setPageSize(3);
        reader.afterPropertiesSet();
        reader.setSaveState(true);

        return reader;
}
}

在這里我要運行此作業以在兩個數據庫之間進行同步,我的問題是如何在osgi中運行此作業。

@EnableScheduling
@Component
public class JobRunner {

 private JobLauncher jobLauncher;  
 private Job job ; 
 private BatchConfiguration batchConfig;
//private  JobBuilderFactory jobs;
//private JobRepository jobrepo;



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

BundleContext ctx;
@SuppressWarnings("rawtypes")
ServiceTracker servicetracker;



@Activate
public void start(BundleContext context) {
    batchConfig = new BatchConfiguration();
    //jobs = new JobBuilderFactory(jobRepository)
    try {
    job = batchConfig.importEmpJob(); //job is null because i don't know how to use it
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    ctx = context;

    servicetracker= new ServiceTracker(ctx, BatchConfiguration.class, null);
    servicetracker.open();

    new Thread() {
        public void run() { findAndRunJob(); }
    }.start();
}



@Deactivate
public void stop() {
    configAdminTracker.close();

}


 @Scheduled(fixedRate = 5000)
protected void findAndRunJob() {

     logger.info("job created.");
      try {  
           String dateParam = new Date().toString();  
           JobParameters param = new JobParametersBuilder().addString("date", dateParam).toJobParameters();  
           System.out.println(dateParam);  
           JobExecution execution = jobLauncher.run(job, param);  
           System.out.println("Exit Status : " + execution.getStatus());  
             } catch (Exception e) {  
              //e.printStackTrace();  
             }  


}

當然,我得到了一個java.lang.NullPointerException因為作業為空。 有人可以幫我嗎?

更新后

@Component
    @EnableBatchProcessing
    public class BatchConfiguration {




  private EmployeeRepository employeeRepository; //spring data repository

   public EmployeeRepository getEmployeeRepository() {
    return employeeRepository;
  }

    @Reference
   public void setEmployeeRepository(EmployeeRepository employeeRepository) {
    employeeRepository= employeeRepository;
     }





       public Step syncEmployeesStep() throws Exception{
    RepositoryItemWriter writer = new RepositoryItemWriter();
    writer.setRepository(employeeRepository);
    writer.setMethodName("save");
    return steps.get("syncEmployeesStep")
            .<Employee, Employee> chunk(10)
            .reader(reader())
            .writer(writer)
            .build();
}


public Job importEmpJob(JobRepository jobRepository, PlatformTransactionManager transactionManager)throws Exception  {
   JobBuilderFactory jobs= new JobBuilderFactory(jobRepository);
     StepBuilderFactory stepBuilderFactory = new StepBuilderFactory(jobRepository, transactionManager);
    return jobs.get("importEmpJob")
            .incrementer(new RunIdIncrementer())
            .start(syncEmployeesStep())
            .next(syncEmployeesStep())
            .build();
}


public ItemReader<Employee> reader() throws Exception {
    String jpqlQuery = "select a from Employee a";
        ServerEMF entityManager = new ServerEMF();
        JpaPagingItemReader<Employee> reader = new JpaPagingItemReader<Tariff>();
        reader.setQueryString(jpqlQuery);
        reader.setEntityManagerFactory(entityManager.getEntityManagerFactory());
        reader.setPageSize(3);
        reader.afterPropertiesSet();
        reader.setSaveState(true);

        return reader;
}
}

跑步者班

private JobLauncher jobLauncher;
        private PlatformTransactionManager transactionManager;
        private JobRepository jobRepository;

        Job importEmpJob;

        private BatchConfiguration batchConfig;
@SuppressWarnings("deprecation")
    @Activate
    public void start(BundleContext context) {

            try {
    batchConfig = new BatchConfiguration();

              this.transactionManager = new ResourcelessTransactionManager();
                MapJobRepositoryFactoryBean repositorybean = new MapJobRepositoryFactoryBean();
                repositorybean.setTransactionManager(transactionManager);
                this.jobRepository = repositorybean.getJobRepository(); //error after executing this statement
                // setup job launcher
                SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
                simpleJobLauncher.setTaskExecutor(new SyncTaskExecutor());
                simpleJobLauncher.setJobRepository(jobRepository);

                this.jobLauncher = simpleJobLauncher;
        //System.out.println(job);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        ctx = context;

        configAdminTracker = new ServiceTracker(ctx, BatchConfiguration.class.getName(), null);
        configAdminTracker.open();

        new Thread() {
            public void run() { findAndRunJob(); }
        }.start();
    }



    @Deactivate
    public void stop() {
        configAdminTracker.close();

    }
    protected void findAndRunJob() {

         logger.info("job created.");
          try {  

               String dateParam = new Date().toString();  

                 // creating the job
                Job job = batchConfig.importEmpJob(jobRepository, transactionManager);

                // running the job
                JobExecution execution = this.jobLauncher.run(job, new JobParameters());

               System.out.println("Exit Status : " + execution.getStatus());  
                 } catch (Exception e) {
                  //e.printStackTrace();  
                 }


    }

運行后,我得到的是“ java.lang.IllegalArgumentException:接口org.springframework.batch.core.repository.JobRepository從類加載器中不可見”。有人可以幫助我解決該錯誤嗎?

簡而言之

如果您只是想開始一些簡單的事情,而不需要所有Spring Batch優點,那么我會考慮使用Apache Sling Commons Scheduler,它在Quartz之上具有一個簡單的作業處理器,可以進行調度[1]。

一般來說

根據您要執行的操作,這里有一些注意事項。 您是否在假設為作業(步驟,任務等)編寫的代碼將存在於單獨的捆綁軟件中的前提下,將Spring Batch Jars部署到OSGi容器? OSGi的目的是開發模塊化代碼,因此我的回答是假設這是您的最終目標。 Pivotal的人員已經放棄了對其工件上的OSGi的支持,因此要使其正常工作,您需要確定需要從Batch jar文件中導出的內容。 可以使用BND來完成。 我建議您檢查新的BND Maven插件[2]。 我將配置Export-Package來導出編寫作業所需的接口,以便可以將作業編寫在單獨的模塊化包中。 然后,我可能會將彈簧批罐子捆綁成一捆,並在JobLauncher周圍寫一個小的包裝紙。 它應該包含單個類加載器的所有實際批處理代碼,因此您不必擔心OSGi嘗試動態引入類。 不利的一面是,這將阻止您在創建的Spring批處理包之外使用許多批處理批注,但會通過使用OSGi實現此類解決方案來提供所需的模塊化。

[1] https://sling.apache.org/documentation/bundles/apache-sling-eventing-and-job-handling.html

[2] http://njbartlett.name/2015/03/27/announcing-bnd-maven-plugin.html

暫無
暫無

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

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