4

I am using Spring-batch-excel for reading a excel file in my new application. It is configured as a batch job and triggered using JobManager. Now i getting this error. InputStream MUST either support mark/reset, or be wrapped as a PushbackInputStream

Caused by: java.lang.IllegalStateException: InputStream MUST either support mark/reset, or be wrapped as a PushbackInputStream
at org.springframework.batch.item.excel.poi.PoiItemReader.openExcelFile(PoiItemReader.java:82) ~[spring-batch-excel-0.5.0-SNAPSHOT.jar:?]
at org.springframework.batch.item.excel.AbstractExcelItemReader.doOpen(AbstractExcelItemReader.java:111) ~[spring-batch-excel-0.5.0-SNAPSHOT.jar:?]
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:144) ~[spring-batch-infrastructure-3.0.5.RELEASE.jar:3.0.5.RELEASE].

Any please help me.

5 Answers 5

8

Old question and I'm sure you figured it out, but I find the current answer to be unhelpful,sooo...

The Resource you're using could be an issue. Most spring-batch-excel examples utilize ClassPathResource. When you try to productionalize your code, you'll likely need to reach for files outside of your classpath. The obvious choice is FileSystemResource, but that will result in this Exception. Instead, look at UrlResource.

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

1 Comment

public PoiItemReader excelReader() { PoiItemReader reader = new PoiItemReader(); reader.setResource(new UrlResource("file:///path/to/your/excel/file")); reader.setRowMapper(rowMapper()); return reader; }
4

As @Thrax mentioned, spring-batch-excel expect to find a PushbackInputStream within the Resource. Here my solution to this problem when working with file on the filesystem:

I create my reader using input file from command line --input.file

@Bean
public PoiItemReader excelReader(@Value("${input.file}") String inputFile) throws FileNotFoundException {
    PoiItemReader reader = new PoiItemReader();
    PushbackInputStream input = new PushbackInputStream(new FileInputStream(inputFile));
    InputStreamResource resource = new InputStreamResource(input);
    reader.setResource(resource);
    reader.setRowMapper(rowMapper());
    return reader;
}

I hope it may helps you.

Comments

1

From looking at spring-batch-excel sources :

@Override
protected void openExcelFile(final Resource resource) throws Exception {
    workbookStream = resource.getInputStream();
    if (!workbookStream.markSupported() && !(workbookStream instanceof PushbackInputStream)) {
        throw new IllegalStateException("InputStream MUST either support mark/reset, or be wrapped as a PushbackInputStream");
    }

    [...]
}

This exception is thrown if the InputStream does not support back reading. The InputStream depends of your Resource, so my conclusion would be that your resource is not a valid XLS/XLSX file.

Comments

1

I know this is an old issue , but i faced this issue, yet for those who have the same issue like me, i commented out this code of block and it worked

if (!workbookStream.markSupported() && !(workbookStream instanceof PushbackInputStream)) {
        throw new IllegalStateException("InputStream MUST either support mark/reset, or be wrapped as a PushbackInputStream");
    }

to understand why please refer to this code : https://github.com/spring-projects/spring-batch-extensions/issues/34

Comments

0

I faced this issue today. The solution was to load the file from disk and not from the classpath. The interesting part is that on our local Windows environments loading from classpath worked fine, but not on a Unix environment. I suspect there might be some corruption going on in the excel file when packaged ina JAR. At any rate, we specify in a URL query parameter the location of the excel file to load, prefixed with classpath: to load it from the Java CLASSPATH, or file: to load it from disk. So all we had to do was put the file in some path on the same server as the running app, then update the URL query parameter to its location like this:

http://some.host.com?location=file:/absolute/path/to/excel/file

and voila. Internally we use Spring's ResourceLoader, which is nothing more than the Spring ApplicationContext. The ResourceLoader understands classpath: and file: prefixes and interprets each accordingly (read the documentation on the ResourceLoader.getResource() method for more details). We got a reference to the Spring's ResourceLoader simply by having our @Service component implement Spring's ResourceLoaderAware.

Comments

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.