How to get Step Name and Step Execution ID in ItemReadListener? - spring

My Spring Batch job uses a FlatFileItemReader to read .csv files. To implement error handling, I created a custom ItemReadListener and provided an overridden onReadError implementation.
Here, I'd like access to the StepName and StepExecutionId from which the error was thrown (i.e. at the reader level). Can I access the StepExecution in the my custom listener? When I try to inject it into any method or constructor, I get a "No beans of type StepExecution found" error.
Thanks.

Try with the following in your ItemReadListener.
#Value("#{stepExecution}")
private StepExecution stepExecution;
This should work if the scope is step. Also your ItemReadListener should be a spring bean.

Related

Trying to pass data from step1's processor to step2's processor (Spring Batch)

I have followed this documentation: https://docs.spring.io/spring-batch/docs/current/reference/html/common-patterns.html#passingDataToFutureSteps
I'm trying to retrieve the information that I received from step1's processor in step2's processor.
Everything works If I have my #BeforeStep function in the writer class of step2.
But I want to get the information in the processor class of step2. But in the processor class, #BeforeStep function doesn't even run.
Is this suppose to happen?? #BeforeStep only get hit in the writer class? or there is a way to get it in the processor class as well??
If you want the method annotated with #BeforeStep to be called, you need to declare your component as a Spring bean. Otherwise, you need to register it explicitly as a listener in your step.

In the Spring boot, when I fetch data from DB, error popping List is null, but data available in db table

data not fetching, error thrown list is empty but data available in DB
service class code,
Service class code block
Controller class
Controller code block
error msg
Error msg
You must add #Autowired to have a dependency injected:
#Autowired
private country gocount;
Bean wiring is missing here hence null pointer exception is being thrown.
You need to do one of the following.
Autowire the dependency
#Autowired
private Country repocount;
Make a constructor and set this dependency.
Using a Lombok annotation may also help.
By seeing the error it is cleared that You haven't Autowired the Bean In controller this will surely solve the problem

spring cron4j scheduling method invoked before bean initialization

I have build a web application and scheduled cron job using cron4j. While executing the cron the run() method is calling and in the run() method all other bean objects are showing null. Hence, I am getting NullPointerException. Below is my sample code.
class Employee{
#autowired
IEmployeeService employeeService;
public void run() {
employeeService.getEmployeeDetails();
}
}
The above example employeeService object getting null and all other bean objects inside getEmployeeDetails(); are getting null and getJdbcTemplate() is also null.
How to initialize bean objects in spring while executing cron using cron4j.
You can use #BeanFactoryPostProcessor annotation to order creation of beans and create/run your job at the end of bean initialization.
The definition of BeanFactoryPostProcessor to bean (configuration metadata) processing. That is to say, the Spring IoC container allows configuration of BeanFactoryPostProcessor metadata in the container before the actual read instantiate any other bean, and may modify it. If you want, you can configure multiple BeanFactoryPostProcessor. You can control the BeanFactoryPostProcessor by setting the'order'attribute of the execution order.
From Spring documentation:
The next extension point that we will look at is the org.springframework.beans.factory.config.BeanFactoryPostProcessor. The semantics of this interface are similar to those of the BeanPostProcessor, with one major difference: BeanFactoryPostProcessor operates on the bean configuration metadata; that is, the Spring IoC container allows a BeanFactoryPostProcessor to read the configuration metadata and potentially change it before the container instantiates any beans other than BeanFactoryPostProcessors.
Please find more information on Spring docs: http://docs.spring.io/spring/docs/4.1.3.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/#beans-factory-extension-factory-postprocessors

Use JSON deserializer for Batch job execution context

I'm trying to get a list of job executions which have been stored in Spring batch related tables in the database using:
List<JobExecution> jobExecutions = jobExplorer.getJobExecutions(jobInstance);
The above method call seems to invoke ExecutionContextRowMapper.mapRow method in JdbcExecutionContextDao class.
The ExecutionContextRowMapper uses com.thoughtworks.xstream.Xstream.fromXML method to deserialize the JSON string of JobExecutionContext stored in DB.
It looks like an incorrect or default xml deserializer is used for unmarshalling JSONified JobExecutionContext.
Is there any configuration to use a JSON deserializer in this scenario.
The serializer/deserializer for the ExecutionContext is configurable in 2.2.x. We use the ExecutionContextSerializer interface (providing two implementations, one using java serialization and one using the XStream impl you mention). To configure your own serializer, you'll need to implement the org.springframework.batch.core.repository.ExecutionContextSerializer and inject it into the JobRepositoryFactoryBean (so that the contexts are serialized/deserialized correctly) and the JobExplorerFactoryBean (to reserialize the previously saved contexts).
It is important to note that changing the serialization method will prevent Spring Batch from deserializing previously saved ExecutionContexts.

How to know if the wiring for a bean is complete with autowiring?

I have a bean with autowired beans.
So something like:
class A
{
#Autowired
B b;
#Autowired
C c;
void function()
{
// here I would like to do something when I an sure the wiring has been done
// being sure that I won't wait forever
...
Something has to exist, but I can't find it.
Thanks for your help!
You can annotate your 'function' method with #PostConstruct and specify <context:annotation-config/> in your spring config XML. Then, function will only be invoked after autowiring, so you could check in function whether your beans have been injected successfully.
A classic way to achieve this is to implement InitializingBean:
Interface to be implemented by beans that need to react once all their properties have been set by a BeanFactory: for example, to perform custom initialization, or merely to check that all mandatory properties have been set.
An alternative to implementing InitializingBean is specifying a custom init-method, for example in an XML bean definition. For a list of all bean lifecycle methods, see the BeanFactory javadocs.
I also suggest reading other answers:
How to call a method after bean initialization is complete?
What is the difference between BeanPostProcessor and init/destroy method in Spring?
If you are using default scope for beans that is singleton, then autowiring will always be done at the application startup only. If wiring for any field fails, then spring container will throw an exception and the application will not start properly. So, if the control of code is in your method , it means wiring has already been done.

Resources