2016-08-09 2 views
2

У меня есть следующие ItemReader:Может Spring Retry использоваться с Spring Batch FlatFileItemReader

import org.springframework.batch.item.ExecutionContext; 
import org.springframework.batch.item.ItemStreamException; 
import org.springframework.batch.item.file.FlatFileItemReader; 
import org.springframework.batch.item.file.LineMapper; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.core.io.FileSystemResource; 
import org.springframework.retry.annotation.Retryable; 
import org.springframework.stereotype.Service; 

@Service 
public class MyReader extends FlatFileItemReader<Holding> { 

    @Autowired 
    public MyReader(LineMapper<Holding> lineMapper, File loadFile) { 
     setResource(new FileSystemResource(loadFile)); 
     final int NUMBER_OF_HEADER_LINES = 1; 
     setLinesToSkip(NUMBER_OF_HEADER_LINES); 
     setLineMapper(lineMapper); 
    } 

    @Override 
    @Retryable(value=ItemStreamException.class, maxAttempts=5, [email protected](delay=1800000)) 
    public void open(ExecutionContext executionContext) throws ItemStreamException { 
       super.open(executionContext); 
    } 
} 

Файл для чтения (т.е. loadFile) могут или не могут быть доступны при выполнении задания. Если файл недоступен, я хочу, чтобы читатель спал ~ 30 минут, а затем повторите попытку открытия файла. Если после пяти попыток файл не найден, он может выйти из строя, как обычно, выбрасывая ItemStreamException.

К сожалению, приведенный выше код не пытается повторно открыть файл. Он выдает ItemStreamException при первом открытии вызова и не запускает его повторно.

Может кто-нибудь объяснить, как это сделать? Примечание: У меня есть @EnableRetry на классе SpringBootApplication.

ответ

0

Перемещение с весны Версия для загрузки 1.3.1.RELEASE to 1.4.0.RELEASE (и соответствующие автозависимые версии, такие как spring-boot-starter-batch) разрешили проблему. Retry работает в 1.4.0.RELEASE, как реализовано в OP. Не работает в 1.3.1.RELEASE. Вот Gradle файл, который в настоящее время используется:

buildscript { 
    ext { 
     // Previously using 1.3.1.RELEASE where retry functionality does not work 
     springBootVersion = '1.4.0.RELEASE' 
    } 
    repositories { 
     mavenCentral() 
     mavenLocal() 
    } 
    dependencies { 
     classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 
    } 
} 

apply plugin: 'java' 
apply plugin: 'eclipse' 
apply plugin: 'spring-boot' 

configurations { 
    provided 
} 

sourceSets { 
    main { 
     compileClasspath += configurations.provided 
    } 
} 

jar { 
    baseName = 'load' 
    version = '1.0' 
} 
sourceCompatibility = 1.8 
targetCompatibility = 1.8 

repositories { 
    mavenCentral() 
    mavenLocal() 
} 

dependencies { 
    compile('org.springframework.boot:spring-boot-starter-batch') 
    compile('org.springframework.boot:spring-boot-configuration-processor') 
    compile('org.springframework.boot:spring-boot-starter-data-jpa') 
    compile('org.springframework.boot:spring-boot-starter-mail') 
    compile('org.springframework.boot:spring-boot-starter-aop') 
    compile('org.projectlombok:lombok:1.16.6') 
    compile('org.hibernate:hibernate-validator:5.2.4.Final') 
    compile('org.quartz-scheduler:quartz:2.2.3') 
    runtime('javax.el:javax.el-api:2.2.4') 
    runtime('org.glassfish.web:javax.el:2.2.4') 
    runtime('net.sourceforge.jtds:jtds:1.3.1') 
    testCompile('org.springframework.boot:spring-boot-starter-test') 
    testCompile('org.springframework.batch:spring-batch-test') 
} 



eclipse { 
    classpath { 
     containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER') 
     containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8' 
    } 
} 

task wrapper(type: Wrapper) { 
    gradleVersion = '2.11' 
} 

Примечание: Рассмотренный с помощью JobExecutionDecider повторить шаг, используя FlatFileItemReader. Тем не менее, ItemStreamException заставляет все задание и приложение заканчиваться без принятия решающим фактором возможности выполнить.

0

Этот продукт работает. Я сделал небольшие изменения, потому что не знаю ваших классов.

build.gradle

buildscript { 
    repositories { 
     mavenCentral() 
    } 
    dependencies { 
     classpath(
       "org.springframework.boot:spring-boot-gradle-plugin:1.4.0.RELEASE", 
     ) 
    } 
} 

apply plugin: 'java' 
apply plugin: 'spring-boot' 

tasks.withType(JavaCompile) { 
    sourceCompatibility = JavaVersion.VERSION_1_8 
    targetCompatibility = JavaVersion.VERSION_1_8 
} 

repositories { 
    mavenCentral() 
} 

springBoot { 
    mainClass = "test.MyReader" 
} 

dependencies { 
    compile(
      'org.springframework.boot:spring-boot-starter', 
      'org.springframework.boot:spring-boot-starter-aop', 
      'org.springframework.retry:spring-retry', 
    ) 
} 

MyApplication.java

@EnableRetry 
@SpringBootApplication 
public class MyApplication implements CommandLineRunner { 
    private final MyReader myReader; 

    @Autowired 
    public MyApplication(MyReader myReader) { 
     this.myReader = myReader; 
    } 

    public static void main(String[] args) { 
     SpringApplication.run(MyApplication.class, args); 
    } 

    @Override 
    public void run(String... args) throws Exception { 
     myReader.read(); 
    } 
} 

MyReader.java

@Service 
public class MyReader { 
    private static final String PATH = "a2"; 
    private final Logger logger = LoggerFactory.getLogger(MyReader.class); 

    public MyReader() { 

    } 

    @Retryable(value = IOException.class, maxAttempts = 5, backoff = @Backoff(delay = 5000)) 
    public void read() throws IOException { 
     final Resource resource = new FileSystemResource(PATH); 
     logger.info("\n\nRead attempt: {}\n", resource); 
     try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))) { 
      final String content = reader.lines().collect(Collectors.joining(" ")); 
      logger.info("\n\nFile content: {}\n", content); 
     } 
    } 
} 

Когда вы ехе милый и файл есть, вы видите в журналах одно сообщение «Прочитать попытку» и одно сообщение «Содержание файла». Я даже добавил в него пустые строки, поэтому сейчас трудно упускать из виду.

Когда файл не существует, вы увидите пять сообщений «Прочитайте попытку», а затем создайте исключение.

Я изменил время повтора до 5 секунд. Если вы достаточно быстр, вы можете начать без файла, а затем сделать там какой-нибудь файл, и вы увидите, что он работает. Вы должны увидеть пару попыток чтения и, наконец, содержимое файла.

Я вижу, что вы уже несколько дней пытаетесь справиться с этой проблемой. Пожалуйста, не создавайте ненужные вопросы, так как они не помогают сообществу. Для будущей ссылки попытайтесь придерживаться своего одного вопроса, изменив его, если возникнет необходимость.

+0

Я также могу получить Spring Retry для работы за пределами «FlatFileItemReader» Spring Batch. В OP я спрашиваю, как заставить это работать в SpringFileItemReader от Spring Batch. – James

Смежные вопросы