Spring Batch - How to keep job running when exception occur? - spring-batch

I try to write example app using spring batch:
#Bean
public Step testStep() {
return steps.get("testStep").<String,String>chunk(1)
.reader(testReader())
.processor(testProcessor())
.writer(testWriter())
.listener(testListener())
.build();
}
When I throw exception in reader or processor or writer, the job stopped with status FAILED. How can I make job ignore exception and keep running.
I'm not use any xml config, just annotation and class. Please give me a hint or link.
Thanks for any support!
Edit: Can we add skip dynamically, like I post in answer below.

Related

getting error in Spring Batch, Job builder and step builder. get function not working with it

#Bean
public Step step1() {
return this.stepBuilder.get("step1")
I'm getting this error:
The method get(String) is undefined for the type StepBuilder please
assist
Solution for the mentioned, i'm getting error in spring batch.

is it possible to skip logging stacktrace by SeekToCurrentErrorHandler?

I just configured SeekToCurrentErrorHandler in spring cloud stream with kafka project and I see tons of logs (one stacktrace per each delivery attempt) which I would like to silence. Is it possible?
PS. I do not know if it is relevant (and whether I do it right. Comments are welcome ;)), but I am throwing an exception from my #StreamListener which is handled by #ServiceActivator and inside it I am rethrowing wrapped exception in order to run error handler.
Starting with spring-kafka version 2.5 (comes with Boot 2.3) you can set the log level.
/**
* Set the level at which the exception thrown by this handler is logged.
* #param logLevel the level (default ERROR).
*/
public void setLogLevel(KafkaException.Level logLevel) {
Assert.notNull(logLevel, "'logLevel' cannot be null");
this.logLevel = logLevel;
}

how to identify the exception if file is not found while Reading (Spring Batch)

I have just started working on Spring Batch (version 3.0.6). I have a job and inside step I'm having Reader->Processor->Writer.
How we can catch or identify the exception is thrown if file is not found while reading. In this case I want to trigger email.
You can use the StepExecutionListener to process the exception that is thrown by the ItemStream#open (as the opening of a file in the FlatFileItemReader is), sending your email from there. To get the exception that caused the failure, you can look at StepExecution#getFailureExceptions which will contain the exception that caused the step to fail.
You can read more about the StepExecutionListener in the javadoc here: https://docs.spring.io/spring-batch/apidocs/org/springframework/batch/core/StepExecutionListener.html

Spring Batch - Call as webservice

I have a Spring Batch job. I am new to Spring Batch and have always been called via the CommandLineJobRunner.
This is what my call looks like:
org.springframework.batch.core.launch.support.CommandLineJobRunner spring-batch-myProject.xml SpringJobBean.MyProjectImportDataJob
Now I have to call my batch job from within a webservice (Spring MVC). In my endpoint this is the invoke call. I need to call the batch job in the if statement. How would I do this? I read about JobLauncher...but not sure how to tell it what to launch?
protected Object invokeInternal(Object aObj) throws Exception {
RunDataProcessingImportRequest request = (RunDataProcessingImportRequest) aObj;
RunDataProcessingImportResponse response = new RunDataProcessingImportResponse();
if (request.getDataProcessingType().equals(PROJECT_TYPE)){
response.setResultCd(1);
} else {
response.setResultCd(0);
response.setErrorCode(1l);
response.setErrorMessage("Incorrect process type");
}
return response;
}
The answer to this really depends on the version of Spring Batch you're using.
If you're using 2.0.x or older you can use Spring Batch Admin to provide REST endpoints for starting/stopping/etc jobs. All you need to do is add the jars to your app and provide a small amount of configuration.
If you're using 2.2.x or newer and are allowed to use the snapshot versions of Spring Batch Admin, the same applies as mentioned above.
If you're not interested in using Spring Batch Admin, you'll need to write your own endpoint and launch the job from there. However, it should be fairly trivial (I haven't tested the code below):
#Controller
public class JobLaunchingController {
#Autowire
JobLauncher jobLauncher;
#Autowire
JobRegistry jobRegistry;
#RequestMapping("/launch")
public #ResponseBody JobExecution launch(
#RequestParam(value="name", required=true) String name,
#RequestParam(value="params", required=false) String params) {
Job job = jobRegistry.getJob(name);
JobParametersBuilder paramsBuilder = new JobParametersBuilder();
if(params != null) {
// parse job parameters
}
return jobLauncher.run(job, paramsBuilder.toJobParameters());
}
}
The above code assumes you have more than one job to provide the ability to execute. If not, you could just #Autowire the Job itself into your controller if you wanted (instead of the JobRegistry).
You can read more about REST services in Spring here: https://spring.io/guides/gs/rest-service/
You can read more about the JobLauncher here: http://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/core/launch/JobLauncher.html
Finally, you can read more about the JobRegistry in section 4.6.2 here: http://docs.spring.io/spring-batch/reference/html/configureJob.html

Log4j Initialization error JBoss RestEasy

I am using JBoss 6.0. I am running a simple webserver using the jboss.resteasy library to provide simple XML responses to HTTP requests.
I have:
- A server
- A simple Java Client that creates a GET request
Now the thing is, if I use the browser to access the URL, I get the wanted XML. But if I use my Java client, which has the following code:
//Register the fake instrument
GetMethod get = new GetMethod("http:/localhost:8080/"+PROJECT_NAME+"/webserver/registerInstrument/?name=FakeClient&value=0");
HttpClient client = new HttpClient();
try {
int status = client.executeMethod(get);
} catch (HttpException e) {
System.out.println("[FakeClient] HttpException executing AddInstrument GET request: "+e);
} catch (IOException e) {
System.out.println("[FakeClient] IOException executing AddInstrument GET request: "+e);
}
Then I get the following exception:
log4j:WARN No appenders could be found for logger (org.apache.commons.httpclient.params.DefaultHttpParams).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" java.lang.IllegalArgumentException: Host name may not be null
at org.apache.commons.httpclient.HttpHost.<init>(HttpHost.java:68)
at org.apache.commons.httpclient.HttpHost.<init>(HttpHost.java:107)
at org.apache.commons.httpclient.HttpMethodBase.setURI(HttpMethodBase.java:280)
at org.apache.commons.httpclient.HttpMethodBase.<init>(HttpMethodBase.java:220)
at org.apache.commons.httpclient.methods.GetMethod.<init>(GetMethod.java:89)
at client.FakeClient.<init>(FakeClient.java:30)
at client.FakeClient.main(FakeClient.java:22)
At first I thought this could be a problem with the JBoss logging, but if I access the URL through the browser, I obtain the desired XML with no problems.
Is this a problem with the Java client application?
Thank you
The 'log4j:WARN' is just a warning. It has nothing do to with the actual exception being thrown.
The exception message states that 'Host name may not be null'. This clearly indicates that there is something wrong the the hostname. And looking at you code, I can spot one error.
You need to add an extra forward slash:
GetMethod get = new GetMethod("http://localhost:8080/" ...