Vaisakh PS
Vaisakh PS

Reputation: 1201

Getting Error while Reading Excel Using Spring-batch-excel

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.

Upvotes: 4

Views: 4712

Answers (5)

Jose Quijada
Jose Quijada

Reputation: 692

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.

Upvotes: 0

Shoun
Shoun

Reputation: 181

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.

Upvotes: 4

MARWAN AMEEN
MARWAN AMEEN

Reputation: 469

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

Upvotes: 1

Andy Sampson
Andy Sampson

Reputation: 291

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.

Upvotes: 8

Thrax
Thrax

Reputation: 1964

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.

Upvotes: 1

Related Questions