andruhon/AndroidReadXLSX

NoClassDefError while running the application on v4.4

Closed this issue · 4 comments

Hi @andruhon

Can you please tell why this particular error is coming while making the application to write .xlsx file in the application. It is throwing Caused by: java.lang.NoClassDefFoundError: org/apache/poi/xssf/usermodel/XSSFWorkbook. when I browsed through the jar files it was there in the package.

PS: The error is coming for version 4.4 and below. It is working fine in android 5.0 and above.

Please find the stacktrace attached below: -

07-03 13:25:08.571 5190-6608/com.vel.barcodetosheet E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2 java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:278) at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) at java.util.concurrent.FutureTask.setException(FutureTask.java:124) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) at java.util.concurrent.FutureTask.run(FutureTask.java:137) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) at java.lang.Thread.run(Thread.java:856) Caused by: java.lang.NoClassDefFoundError: org/apache/poi/xssf/usermodel/XSSFWorkbook at com.vel.barcodetosheet.classes.CommonMethods.createDataToExportXLSX(CommonMethods.java:727) at com.vel.barcodetosheet.classes.CommonMethods.exportXLSXFile(CommonMethods.java:677) at com.vel.barcodetosheet.fragments.StandardPlusFragment$ExportListXLSX.doInBackground(StandardPlusFragment.java:971) at com.vel.barcodetosheet.fragments.StandardPlusFragment$ExportListXLSX.doInBackground(StandardPlusFragment.java:955) at android.os.AsyncTask$2.call(AsyncTask.java:264) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) at java.util.concurrent.FutureTask.run(FutureTask.java:137)  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)  at java.lang.Thread.run(Thread.java:856)  Caused by: java.lang.ClassNotFoundException: org.apache.poi.xssf.usermodel.XSSFWorkbook at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61) at java.lang.ClassLoader.loadClass(ClassLoader.java:501) at java.lang.ClassLoader.loadClass(ClassLoader.java:461) at com.vel.barcodetosheet.classes.CommonMethods.createDataToExportXLSX(CommonMethods.java:727)  at com.vel.barcodetosheet.classes.CommonMethods.exportXLSXFile(CommonMethods.java:677)  at com.vel.barcodetosheet.fragments.StandardPlusFragment$ExportListXLSX.doInBackground(StandardPlusFragment.java:971)  at com.vel.barcodetosheet.fragments.StandardPlusFragment$ExportListXLSX.doInBackground(StandardPlusFragment.java:955)  at android.os.AsyncTask$2.call(AsyncTask.java:264)  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)  at java.util.concurrent.FutureTask.run(FutureTask.java:137)  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)  at java.lang.Thread.run(Thread.java:856) 

Can this happen that proguard chopping the class out?

How do you create a new sheet? Approach like this is not going work:
XSSFWorkbook workbook = new XSSFWorkbook(); XSSFSheet sheet = workbook.createSheet(WorkbookUtil.createSafeSheetName("mysheet"));

What you can do is to keep a resource with a blank xlsx file and use this existing file as a blank to populate it with your data.

HI @andruhon ,

Thanks for such a timely reply. I am using the workaround of keeping a sample xlsx in the application's assets folder rather than creating using the WorkbookUtil class. Also, the reason for NoClassDefErrror and solution that can be implemented is mentioned below: -

The problem was android's 65K limit that was chopping off the classes even in the debug mode let alone in the release build with proguard config.

I had to use android support multidex and it is now working fine as of version 14 and above. It is comparatively slow than the libs in Android 5 XLSX.

Using support multidex has to remove the application's Global Class which extends the Application Class in android, but the support of XLSX was worth it in the application.
`android {
.
.
.

defaultConfig {
    ... 
    ...

    // Enabling multidex support.
    multiDexEnabled true
}
...

}

dependencies {
compile 'com.android.support:multidex:1.0.0'
}`

and the in the manifest has to incorporate this class instead of GlobalClass: -

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.multidex.myapplication"> <application ... android:name="android.support.multidex.MultiDexApplication"> ... </application> </manifest>

More details can be found here.

Hopefully, it helps others too.

Note: - You can use it with app compat support library too without any problem

Thank you @palVikas9. Does it work if you use full version from https://github.com/andruhon/android5xlsx on android 4 making this hacked version useless or POI still has to remain in one dex? Is the POI in primary dex, distributed around dexes or in installed dex?

Hi @andruhon ,No, I didn't tried that. As I was running short of time regarding the delivery of the system, so time was one of the concerns that I had. Will try it in few days and let you know whether we can use the full version from Android 5 XLSX on Android 4.

It will be very useful as Android 5 hack if quite fast as compared to this one.