簡體   English   中英

如何解決 MultiResourceItemReader Spring Batch 中的 NullPointerException

[英]How to resolve NullPointerException in MultiResourceItemReader Spring Batch

我正在使用MultiResourceItemReader從 S3 存儲桶中讀取多個文件,在執行myReader()方法之前我得到NullPointerException ,但是,在拋出異常后它會進入myReader()方法但itemProcessor方法沒有調用。 我相信由於NullPointerException itemProcessor沒有調用。 MultiResourceItemReader出了點問題,不確定這里出了什么問題。

請在下面找到我的代碼:

        @Bean
        public MultiResourceItemReader<String> multiResourceReader()
        {
            String bucket = "mybucket;
            String key = "/myfiles";
        
            List<InputStream> resourceList = s3Client.getFiles(bucket, key);
            List<InputStreamResource> inputStreamResourceList = new ArrayList<>();
            for (InputStream s: resourceList) {
                inputStreamResourceList.add(new InputStreamResource(s));
            }
    
    Resource[] resources = inputStreamResourceList.toArray(new InputStreamResource[inputStreamResourceList.size()]);
//InputStreamResource[] resources = inputStreamResourceList.toArray(new InputStreamResource[inputStreamResourceList.size()]);
    
    // I'm getting all the stream content - I verified my stream is not null
            for (int i = 0; i < resources.length; i++) {
                try {
                    InputStream s  = resources[i].getInputStream();
                    String result = IOUtils.toString(s, StandardCharsets.UTF_8);
                    System.out.println(result);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            MultiResourceItemReader<String> resourceItemReader = new MultiResourceItemReader<>();
            resourceItemReader.setResources(resources);
            resourceItemReader.setDelegate(myReader());
            return resourceItemReader;
        }


    @Bean
    @StepScope
    public FlatFileItemReader<String> myReader() {
    
        FlatFileItemReader reader = new FlatFileItemReader<>();
        reader.setLineMapper(new DefaultLineMapper());
        return reader;
    }

例外:

java.lang.NullPointerException: null
        at org.springframework.batch.item.file.MultiResourceItemReader$1.compare(MultiResourceItemReader.java:83)
        at org.springframework.batch.item.file.MultiResourceItemReader$1.compare(MultiResourceItemReader.java:76)
        at java.base/java.util.TimSort.countRunAndMakeAscending(TimSort.java:355)
        at java.base/java.util.TimSort.sort(TimSort.java:220)
        at java.base/java.util.Arrays.sort(Arrays.java:1441)
        at org.springframework.batch.item.file.MultiResourceItemReader.open(MultiResourceItemReader.java:186)
        at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:104)
        at org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:311)
        at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:205)
        at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:152)
        at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:68)
        at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:68)
        at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169)
        at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144)
        at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:137)
        at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:320)
        at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:149)
        at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
        at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:140)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:128)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
        at com.sun.proxy.$Proxy80.run(Unknown Source)
        at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.execute(JobLauncherApplicationRunner.java:199)
        at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.executeLocalJobs(JobLauncherApplicationRunner.java:173)
        at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.launchJobFromProperties(JobLauncherApplicationRunner.java:160)
        at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.run(JobLauncherApplicationRunner.java:155)
        at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.run(JobLauncherApplicationRunner.java:150)
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:782)
        at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:772)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:345)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332)
        at 
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)

有人可以幫我解決這個問題。 提前感謝您的幫助。 謝謝。

您看到 NullPointerException 的原因是由於 MultiResourceItemReader 使用默認比較器在加載資源后對資源進行排序。

默認比較行為調用 InputStreamResource 的getFilename()方法。

參考-https://github.com/spring-projects/spring-batch/blob/115c3022147692155d45e23cdd5cef84895bf9f5/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/MultiResourceItemReader.

但是 InputStreamResource 只是從其父AbstractResource繼承getFileName()方法,它只返回 null。 https://github.com/spring-projects/spring-framework/blob/316e84f04f3dbec3ea5ab8563cc920fb21f49749/spring-core/src/main/java/org/springframework/core/io/AbstractResource.java#L220

解決方案是為 MultiResourceItemReader 提供自定義比較器。 這是一個簡單的示例,假設您不想在處理之前以特定方式對資源進行排序:

public class CustomComparator implements Comparator<InputStream>{

        @Override
        public int compare(InputStream is1, InputStream is2) {
       //comparing based on last modified time
            return Long.compare(is1.hashCode(),is2.hashCode());
   }
}

MultiResourceItemReader<String> resourceItemReader = new MultiResourceItemReader<>();
resourceItemReader.setResources(resources);
resourceItemReader.setDelegate(myReader());
resourceItemReader.setDelegate(new CustomComparator());

請參閱此答案以了解 Spring Batch MultiResourceItemReader 如何使用比較器。

用 Spring 批量處理文件訂單

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM