2

I am using Spring Batch to implement a batch job, but for some reasons my job is allways null, when I am trying to start my job. It seems to me that my job isn't injected when needed by the Spring framework. Can somebody tell me what I am doing wrong please?! I am a little bit tired of try and error...

This is my spring config (batch config):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch" xmlns:task="http://www.springframework.org/schema/task"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.2.xsd
http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch-2.2.xsd">

<bean id="batchTransactionManager"
    class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<bean id="recordItemReader" class="com.blang.court.exports.RecordItemReader" />

<batch:job id="recordReadJob" job-repository="jobRepository">
    <batch:step id="recordReadStep">
        <batch:tasklet ref="recordItemReader"
            transaction-manager="batchTransactionManager" />
    </batch:step>
</batch:job>

<bean id="batchLauncher" class="com.blang.court.exports.BatchLauncher">
    <property name="jobLauncher" ref="jobLauncher" />
    <property name="job" ref="recordReadJob" />
</bean>

And here comes another Spring config (application-context):

 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ws="http://jax-ws.dev.java.net/spring/core"
xmlns:wss="http://jax-ws.dev.java.net/spring/servlet" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"

xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://jax-ws.dev.java.net/spring/core
http://jax-ws.dev.java.net/spring/core.xsd
http://jax-ws.dev.java.net/spring/servlet
http://jax-ws.dev.java.net/spring/servlet.xsd
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd"
default-autowire="byName">

<context:annotation-config />

<tx:annotation-driven transaction-manager="applicationTransactionManager" />


<!-- Mail -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="localhost" />
</bean>


<!-- JPA -->
<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="appPersistenceUnit" />
</bean>

<bean id="applicationTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>


<!-- Spring Batch -->
<!-- <bean id="batchTransactionManager" 
    class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />-->

<bean id="jobRepository"
    class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
    <property name="transactionManager" ref="applicationTransactionManager" />
</bean>

<bean id="jobLauncher"
    class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    <property name="jobRepository" ref="jobRepository" />
</bean>

That's about the configuration. in the next step I implemented the batch launcher class. Which looks like that:

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRestartException;

public class BatchLauncher
{
  private Job job;
  private JobLauncher jobLauncher;

  public void launch()
  {
  JobParametersBuilder builder = new JobParametersBuilder();

  try
  {
    JobExecution execution = jobLauncher.run(job, builder.toJobParameters());
  }
  catch (JobExecutionAlreadyRunningException | JobRestartException
          | JobInstanceAlreadyCompleteException
          | JobParametersInvalidException e)
  {
    e.printStackTrace();
  }

 }

 public Job getJob()
 {
   return job;
 }

 public void setJob(Job job)
 {
   this.job = job;
 }

 public JobLauncher getJobLauncher()
 {
    return jobLauncher;
 }

 public void setJobLauncher(JobLauncher jobLauncher)
 {
   this.jobLauncher = jobLauncher;
 }
}

And finally my job:

import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;

import com.blang.court.RecordForm;
import com.blang.court.interfaces.IRecordService;

public class RecordItemReader implements Tasklet
{
   @Autowired
   IRecordService recordService;

   @Override
   public RepeatStatus execute(StepContribution arg0, ChunkContext arg1)
      throws Exception
   {
      recordService.filterRecords(new RecordForm());
      System.out.println("Hi, the job is running! Yeah, finally got it!");
      return RepeatStatus.FINISHED;
   }
 }

I am allways getting a nullPointerException on this line in the batchlauncher class:

JobExecution execution = jobLauncher.run(job, builder.toJobParameters());

Which tells me that my jo is null. I have debugged it to proof it and ... yes the job is null for some reason ....

Please help me... :-(

Kind regards

Aacini
  • 65,180
  • 12
  • 72
  • 108
F4k3d
  • 653
  • 1
  • 10
  • 29

1 Answers1

3

In your configuration the property job refers a Tasklet and non a Job..

Try this configuration

<bean id="batchLauncher" class="com.blang.court.exports.BatchLauncher">
    <property name="jobLauncher" ref="jobLauncher" />
    <property name="job" ref="recordReadJob" />
</bean>

I hope will help you


When you create an object by new, autowire\inject don't work...

Example class

public class Test {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("app-context.xml");
        BatchLauncher batchLauncher = (BatchLauncher ) context.getBean("batchLauncher");
        batchLauncher.launch();
    }
} 

the same issue is solved in this link

Community
  • 1
  • 1
Xstian
  • 8,184
  • 10
  • 42
  • 72
  • Thank you again! I corrected it but this isn't fixing the NPE also... :-( I recognized that the jobRepository in the batchlauncher class is null, too.... – F4k3d Sep 05 '14 at 08:43
  • When i use spring-batch .. i use this bean for jobRepository .. – Xstian Sep 05 '14 at 08:46
  • I have this repository from several tutorials I raed before implementing. They are all using the repository I used in my code... So, I don't think that will solve my problem. ;-) Anyway thank you for that hint. ;-) – F4k3d Sep 05 '14 at 08:49
  • Correction: I wanted to write that the jobLauncher is null instead of jobRepository. I am not using the jobRepository in the Batchlauncher class. Just for the protocol! :-) – F4k3d Sep 05 '14 at 08:56
  • @user2519837 how do you create and use this bean "batchLauncher" ? you retrieve this bean from the context? or you perform a new statement? – Xstian Sep 05 '14 at 08:58
  • I creat and use it in a MVC controller method like that: BatchLauncher launcher = new BatchLauncher(); launcher.launch(); – F4k3d Sep 05 '14 at 09:04
  • 1
    The problem is this.. :) .. you should retrive this bean from the spring context else the inject does not work – Xstian Sep 05 '14 at 09:05
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/60677/discussion-between-user2519837-and-xstian). – F4k3d Sep 05 '14 at 09:09