Bug 59048

Summary: ClassCastException when opening Excelfile in Android 5 with POI 3.13/3.14
Product: POI Reporter: Mats Forsen <mats>
Component: XSSFAssignee: POI Developers List <dev>
Status: RESOLVED WORKSFORME    
Severity: major    
Priority: P2    
Version: 3.13-FINAL   
Target Milestone: ---   
Hardware: Other   
OS: other   

Description Mats Forsen 2016-02-22 22:40:12 UTC
POI version 3.12 works OK. 
But 3.13 and 3.14-beta1 gives the same failure

java.lang.ClassCastException: org.apache.poi.openxml4j.util.ZipSecureFile$ThresholdInputStream cannot be cast to java.util.zip.ZipFile$RAFStream


---- 
The error occurs every time we try to open simple excel files (xlsx, created with MS Excel)
The app runs on Android 5.1.1, Samsung Galaxy Note (SM-P605).
Developed with Android Studio 2.0, beta 5, targetSdkVersion 22, minSdkVersion 21.

It is a little bit tricky to get POI to run on Android since Android lacks the package javax.xml.stream/**
The following project is very similar to how we have succeeded. https://github.com/andruhon/android5xlsx


We have been using POI 3.11 with the same excel files for a while on Android 4 as well without problems.
----
The class org.apache.poi.openxml4j.util.ZipSecureFile seems to have been introduced for bugfix 50090 - 'zip' bomb prevention.
---
The row number mentioned in the Android Studio logcat window, does not seem to indicate correct line numbers in ZipSecureFile.java compared to 
https://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java?view=markup&pathrev=1687148

It's in a read statement that the exception occurs, but the latest test (with POI 3.14-beta1 indicates ZipSecureFile.java:208 and earlier tests with 3.13 indicates ZipSecureFile.java:162. 
See the logs below.


/Mats

----
Logs (when testing with POI version 3.14-beta1)
java.lang.RuntimeException: An error occured while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:304)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:818)
 Caused by: java.lang.ClassCastException: org.apache.poi.openxml4j.util.ZipSecureFile$ThresholdInputStream cannot be cast to java.util.zip.ZipFile$RAFStream
    at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:191)
    at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:153)
    at java.util.zip.ZipFile$ZipInflaterInputStream.read(ZipFile.java:538)
    at libcore.io.Streams.readSingleByte(Streams.java:41)
    at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:130)
    at org.apache.poi.openxml4j.util.ZipSecureFile$ThresholdInputStream.read(ZipSecureFile.java:208)
    at org.kxml2.io.KXmlParser.setInput(KXmlParser.java:1642)
    at org.apache.harmony.xml.parsers.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:111)
    at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:107)
    at org.apache.poi.util.DocumentHelper.readDocument(DocumentHelper.java:96)
    at org.apache.poi.openxml4j.opc.internal.ContentTypeManager.parseContentTypesFile(ContentTypeManager.java:377)
    at org.apache.poi.openxml4j.opc.internal.ContentTypeManager.<init>(ContentTypeManager.java:103)
    at org.apache.poi.openxml4j.opc.internal.ZipContentTypeManager.<init>(ZipContentTypeManager.java:54)
    at org.apache.poi.openxml4j.opc.ZipPackage.getPartsImpl(ZipPackage.java:190)
    at org.apache.poi.openxml4j.opc.OPCPackage.getParts(OPCPackage.java:696)
    at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:259)
    at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:284)
    at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:252)
    at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:231)

-----
Logs with POI 3.13.
  java.lang.RuntimeException: An error occured while executing doInBackground()
      at android.os.AsyncTask$3.done(AsyncTask.java:304)
      at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
      at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
      at java.util.concurrent.FutureTask.run(FutureTask.java:242)
      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
      at java.lang.Thread.run(Thread.java:818)
   Caused by: java.lang.ClassCastException: org.apache.poi.openxml4j.util.ZipSecureFile$ThresholdInputStream cannot be cast to java.util.zip.ZipFile$RAFStream
      at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:191)
      at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:153)
      at java.util.zip.ZipFile$ZipInflaterInputStream.read(ZipFile.java:538)
      at libcore.io.Streams.readSingleByte(Streams.java:41)
      at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:130)
      at org.apache.poi.openxml4j.util.ZipSecureFile$ThresholdInputStream.read(ZipSecureFile.java:162)
      at org.kxml2.io.KXmlParser.setInput(KXmlParser.java:1642)
      at org.apache.harmony.xml.parsers.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:111)
      at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:107)
      at org.apache.poi.util.DocumentHelper.readDocument(DocumentHelper.java:96)
      at org.apache.poi.openxml4j.opc.internal.ContentTypeManager.parseContentTypesFile(ContentTypeManager.java:377)
      at org.apache.poi.openxml4j.opc.internal.ContentTypeManager.<init>(ContentTypeManager.java:103)
      at org.apache.poi.openxml4j.opc.internal.ZipContentTypeManager.<init>(ZipContentTypeManager.java:54)
      at org.apache.poi.openxml4j.opc.ZipPackage.getPartsImpl(ZipPackage.java:190)
      at org.apache.poi.openxml4j.opc.OPCPackage.getParts(OPCPackage.java:684)
      at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:254)
      at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:282)
      at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:250)
      at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:229)
Comment 1 Dominik Stadler 2016-06-01 19:57:14 UTC
In order to test how POI can be used successfully on Android, I have created a sample project poi-on-android at https://github.com/centic9/poi-on-android which uses a different approach than https://github.com/andruhon/android5xlsx. It works by first building a shaded jar from a specific version of POI with all required dependencies included and some relocations being done to avoid errors because of javax....

I then use this in an Android sample application to show that it can be used to do work on Excel documents. Basic creating, writing and reading .xlsx files works for me. 

Can you try this approach to see if this allows your use-case as well?

You can probably run the Gradle target "shadowJar" and then use the resulting file "poishadow/build/libs/poishadow-all.jar" in your application instead of your own built jars of POI.
Comment 2 Dominik Stadler 2016-10-11 19:36:57 UTC
No update for several months, therefore I am closing this as WORKSFORME now with the links to the sample project which provides a shadow-jar of POI which should be suitable for most actions an Android. Please report new bugs if it still does not work for you.