Parameter zum Jobkontext aus dem Jobschritt hinzufügen und in späteren Schritten in Spring Batch @ verwend

Im Moment benutze ich jobParameters, um die Dateinamen für meinen FlatFileItemReader und FlatFileItemWriter abzurufen. Es ist in Ordnung, meinen Stapel zu testen, aber mein Ziel ist es, eine Datei in einem Verzeichnis zu lesen (es gibt nur diese Datei in diesem Verzeichnis), und der Dateiname könnte sich ändern. Der Ausgabedateiname sollte vom Eingabedateinamen abhängen.

Aus diesem Grund habe ich überlegt, meinem Job einen neuen Schritt hinzuzufügen. In diesem Schritt werden sowohl die Ausgabe- als auch die Eingabedateinamen festgelegt, indem das gute Verzeichnis durchsucht und die Datei darin gesucht wird. Ich leseDaten an zukünftige Schritte weiterleiten von Spring Doc unddieser Thread von SO, aber ich kann es nicht zum Laufen bringen, die Dateien sind immer "null".

Zunächst habe ich das folgende Tasklet definiert

public class SettingFilenamesTasklet implements Tasklet {

    private StepExecution stepExecution;

    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
        // TODO Search folder and set real filenames
        String inputFilename = "D:/TestInputFolder/dataFile.csv";
        String outputFilename = "D:/TestOutputFolder/dataFile-processed.csv";
        ExecutionContext stepContext = stepExecution.getExecutionContext();
        stepContext.put("inputFile", inputFilename);
        stepContext.put("outputFile", outputFilename);
        return RepeatStatus.FINISHED;
    }

    @BeforeStep
    public void saveStepExecution(StepExecution stepExec) {
        stepExecution = stepExec;
    }
}

Dann habe ich die promotionListener Bean hinzugefügt

@Bean
public ExecutionContextPromotionListener promotionListener() {
    ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
    listener.setKeys(new String[]{
            "inputFile", "outputFile"
    });
    return listener;
}

Ich habe die jobParameters durch einen jobExecutionContext in meiner FlatFileItemWriter-Definition geändert (ich habe keine einzige Zeile in den Code selbst geändert)

@Bean
@StepScope
public FlatFileItemWriter<RedevableCRE> flatFileWriter(@Value("#{jobExecutionContext[outputFile]}") String outputFile) {
    FlatFileItemWriter<Employee> flatWriter = new FlatFileItemWriter<Employee>();
    FileSystemResource isr;
    isr = new FileSystemResource(new File(outputFile));
    flatWriter.setResource(isr);
    DelimitedLineAggregator<RedevableCRE> aggregator = new DelimitedLineAggregator<RedevableCRE>();
    aggregator.setDelimiter(";");
    BeanWrapperFieldExtractor<RedevableCRE> beanWrapper = new BeanWrapperFieldExtractor<RedevableCRE>();
    beanWrapper.setNames(new String[]{
        "id", "firstName", "lastName", "phone", "address"
    });
    aggregator.setFieldExtractor(beanWrapper);
    flatWriter.setLineAggregator(aggregator);
    flatWriter.setEncoding("ISO-8859-1");
    return flatWriter;
}

Ich habe meine Tasklet Bean hinzugefügt

@Bean
public SettingFilenamesTasklet settingFilenames() {
    return new SettingFilenamesTasklet();
}

Und ich habe einen neuen Schritt erstellt, um ihn in meine Joberklärung aufzunehmen

@Bean
public Step stepSettings(StepBuilderFactory stepBuilderFactory, SettingFilenamesTasklet tasklet, ExecutionContextPromotionListener listener) {
    return stepBuilderFactory.get("stepSettings").tasklet(tasklet).listener(listener).build();
}

Zur Zeit verwendet der FlatFileItemReader immer noch den Wert jobParameters. Ich möchte, dass mein FlatFileItemWriter zuerst funktioniert. Ich erhalte den folgenden Fehler:

[...]    
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.item.file.FlatFileItemWriter]: Factory method 'flatFileWriter' threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:591)
    ... 87 common frames omitted
Caused by: java.lang.NullPointerException: null
    at java.io.File.<init>(Unknown Source)
    at batchTest.BatchConfiguration.flatFileWriter(BatchConfiguration.java:165)
    at batchTest.BatchConfiguration$EnhancerBySpringCGLIB$5d415889.CGLIB$flatFileWriter$1(<generated>)
    at batchTest.BatchConfiguration$EnhancerBySpringCGLIB$5d415889$FastClassBySpringCGLIB$969a8527.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312)
    at batchTest.BatchConfiguration$EnhancerBySpringCGLIB$5d415889.flatFileWriter(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    ... 88 common frames omitted

Ich habe versucht, die @StepScope-Annotation durch @JobScope zu ersetzen. meine Parameter direkt in jobExecutionContext (+ JobExecutionListener) einfügen, anstatt StepContext + promotionListener zu verwenden ... Es funktioniert nichts. Die Ressourcendatei ist immer null, wenn ich versuche, den FlatFileItemWriter zu erstellen.

Was vermisse ich

Danke für Ihre Hilfe

Antworten auf die Frage(2)

Ihre Antwort auf die Frage