1

I am trying to get the input files using @Value annotation and set it as a Resource array for MultiResourceItemReader as bellow;

@Value("classpath*:/input/userdata*.csv")
private Resource[] inputFiles;

It is working fine in IDE when I place input files folder in resources folder. The issues is when I run the jar file. It is also working fine if the files are within the jar as in IDE. But it is not picking up when I place the input folder in the same directory of jar file. Here is my Configuration;

        @Value("classpath*:/input/userdata*.csv")
        private Resource[] inputFiles;
        
        @Bean
        public MultiResourceItemReader<UserInfo> multiResourceItemreader() {
            MultiResourceItemReader<UserInfo> reader = new MultiResourceItemReader<>();
            reader.setDelegate(userDataItemReader());
            reader.setResources(inputFiles);
            return reader;
        }

It did not give any error but just the bellow message in console

2021-02-04 16:31:42.959  WARN 15772 --- [           main] o.s.b.item.file.MultiResourceItemReader  : No resources to read. Set strict=true if this should be an error condition.

I am not sure what I am missing here. Tried without classpath prefix in @Value but it gives me bellow exception

java.lang.IllegalArgumentException: Could not resolve resource location pattern [/input/userdata*.csv]

Not sure is there any other way to set the resources for MultiResourceItemReader other than @Value annotation. A help would be greatly appreciated!

Edit:- This is a Spring Boot batch application and here is the directory structure

            apps
            ├── input
            │   ├── userdata6.csv
            │   ├── userdata7.csv
            │   ├── userdata8.csv
            │   └── userdata9.csv
            └── multisource-batch.jar

I run the jar file as below from the same app directory

java -jar multisource-batch.jar

build.gradle

        plugins {
          id 'org.springframework.boot' version '2.4.2'
          id 'io.spring.dependency-management' version '1.0.11.RELEASE'
          id 'java'
        }

        group = 'com.thomsoncodes.batch'
        version = '0.0.1-SNAPSHOT'
        sourceCompatibility = '1.8'

        repositories {
            mavenCentral()
            maven { url 'https://repo.spring.io/milestone' }
        }

        ext {
            set('springCloudVersion', "2020.0.0")
        }

        dependencies {
            implementation 'org.springframework.boot:spring-boot-starter-batch'
            runtimeOnly 'mysql:mysql-connector-java'
            testImplementation 'org.springframework.boot:spring-boot-starter-test'
            testImplementation 'org.springframework.batch:spring-batch-test'
            
            implementation 'org.projectlombok:lombok:1.18.2'
        }

        dependencyManagement {
            imports {
                mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
            }
        }

        test {
            useJUnitPlatform()
        }

UPDATE:- Finally I got it working!. Even though I removed the Web dependency the spring was still considering this as web. Did a clean build and updated @Value("file:/input/userdata*.csv") as Mahmoud Ben Hassine suggested!

0

1 Answer 1

1

it is not picking up when I place the input folder in the same directory of jar

If you are you running your app with java -jar myapp.jar where the input directory is in the same directory of myapp.jar, then you need to use the file: prefix and not the classpath: prefix.

@Value("file:input/userdata*.csv") should work as it will resolve resources from the relative directory where you launched your JVM.

EDIT: You can find a complete example here.

Sign up to request clarification or add additional context in comments.

8 Comments

I tried but I am getting error - Caused by: java.lang.IllegalArgumentException: Could not resolve resource location pattern [input/userdata*.csv]: ServletContext resource [/input/] cannot be resolved to URL because it does not exist
ServletContext resource..: looks like your app is a web app, you should have mentioned that in your question. Please edit your question and layout your directory structure and how you are running your app to be able to help you in an efficient manner.
It should work. You did not mention how you run your app. Are you running it with java -jar multisource-batch.jar from the apps directory? Is your application a web app? If yes, is that required or packaging your job in its own non-webapp jar an option for you?
First of all thank you very much for your help. Yes its its running from the very app directory and run as you mentioned. I am little confused about Web application part. Its a Spring Boot Batch application I dont have any other dependency. Will update build.gradle as well. I use gradle build to build jar
Thank you for the update. Those details should have been added in the question from the beginning for more efficiency, see stackoverflow.com/help/minimal-reproducible-example. In this case, you need to use the file: prefix and not the classpath: prefix. I updated the question accordingly and added a link to a complete example. If you see ServletContext resource ... in your error message, this means you have web dependency being resolved and your app is running as a web application (a servlet container is being auto-configured somehow by Spring Boot).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.