Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

integrating org.apache.poi and the javax.xml.stream.* package (stax-api) in android - how to set the --core-library argument in Android Studio?

Tags:

I'm using Android studio 1.5.1

I'd like to include the org.apache.poi-ooxml library in my android project. To include that library I needed to include some other library dependencies, among which the stax-api library.

The problem with stax api is that it has all the packages in javax.* which is a "core library". Java jdk has all these libraries included, so if I were to use it in Java SE, I wouldn't need that stax-api library. Android, on the other hand, has a "partial" stax-api library. For android I only need the javax.xml.stream.* package. That means that I need to extract the stax-api, remove everything except the javax.xml.stram package, and repackage it again.

So I guess it is safe to use this modified library in Android. But, it has the javax.* package, which, according to Android studio is a core library, so Android Studio (or whatever component in Android Studio) gives me a warning:

trouble processing "javax/xml/stream/EventFilter.class":

Ill-advised or mistaken usage of a core class (java.* or javax.*) when not building a core library.

This is often due to inadvertently including a core library file in your application's project, when using an IDE (such as Eclipse). If you are sure you're not intentionally defining a core class, then this is the most likely explanation of what's going on.

However, you might actually be trying to define a class in a core namespace, the source of which you may have taken, for example, from a non-Android virtual machine project. This will most assuredly not work. At a minimum, it jeopardizes the compatibility of your app with future versions of the platform. It is also often of questionable legality.

If you really intend to build a core library -- which is only appropriate as part of creating a full virtual machine distribution, as opposed to compiling an application -- then use the "--core-library" option to suppress this error message.

If you go ahead and use "--core-library" but are in fact building an application, then be forewarned that your application will still fail to build or run, at some point. Please be prepared for angry customers who find, for example, that your application ceases to function once they upgrade their operating system. You will be to blame for this problem.

If you are legitimately using some code that happens to be in a core package, then the easiest safe alternative you have is to repackage that code. That is, move the classes in question into your own package namespace. This means that they will never be in conflict with core system classes. JarJar is a tool that may help you in this endeavor. If you find that you cannot do this, then that is an indication that the path you are on will ultimately lead to pain, suffering, grief, and lamentation.

So, I'd like to use this --core-library option. But where to set it?

I already looked at Android Studio ignore --core-library flag which didn't help me. I think those answers are outdated, and that's why I'm asking a new question.

What I did try:

  1. build.gradle:

    dexOptions {
      coreLibrary true;
    }
    
  2. build.gradle:

    dexOptions {
      preDexLibraries = false
    }
    
    project.tasks.withType(com.android.build.gradle.tasks.Dex) {
      additionalParameters=['--core-library']
    }
    
  3. File --> Other Settings --> Default Settings --> Compilers --> Android Compilers and check the 'Add --core-library flag'

None of these worked. Is there any way to set that option?


EDIT: Why do I need STAX: I'm doing some stuff with Workbook, Sheet, Columns, Cells for .xlsx files. When I include only poi-ooxml-3.14-beta1-20151223.jar I get an error in build time saying class file for org.apache.poi.ss.usermodel.Workbook not found.

Upon including poi-3.14-beta1-20151223.jar on runtime I get, among others, Could not find method org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook.isSetBookViews, referenced from method org.apache.poi.xssf.usermodel.XSSFWorkbook.

Upon including poi-ooxml-schemas-3.14-beta1-20151223.jar during runtime I get , among others, Failed resolving Lorg/openxmlformats/schemas/spreadsheetml/x2006/main/CTWorkbook; interface 59 'Lorg/apache/xmlbeans/XmlObject; and java.lang.VerifyError: org/apache/poi/xssf/usermodel/XSSFWorkbook

Upon including xmlbeans-2.6.0.jar during runtime I get, among others, Could not find method javax.xml.stream.events.Namespace.getPrefix, referenced from method org.apache.poi.openxml4j.opc.internal.marshallers.PackagePropertiesMarshaller.getQName and java.lang.NoClassDefFoundError: javax.xml.stream.XMLEventFactory at org.apache.poi.openxml4j.opc.internal.marshallers.PackagePropertiesMarshaller.<clinit>(PackagePropertiesMarshaller.java:41)

UPDATE So, from http://poi.apache.org/faq.html#faq-N1017E

18. Why do I get a java.lang.NoClassDefFoundError: javax/xml/stream/XMLEventFactory.newFactory()

This error indicates that the class XMLEventFactory does not provide functionality which POI is depending upon. There can be a number of different reasons for this:

Outdated xml-apis.jar, stax-apis.jar or xercesImpl.jar:

  • These libraries were required with Java 5 and lower, but are not actually required with spec-compliant Java 6 implementations, so try removing those libraries from your classpath. If this is not possible, try upgrading to a newer version of those jar files.
  • Running IBM Java 6 (potentially as part of WebSphere Application Server): IBM Java 6 does not provide all the interfaces required by the XML standards, only IBM Java 7 seems to provide the correct interfaces, so try upgrading your JDK.
  • Sun/Oracle Java 6 with outdated patchlevel: Some of the interfaces were only included/fixed in some of the patchlevels for Java 6. Try running with the latest available patchlevel or even better use Java 7/8 where this functionality should be available in all cases.

So, if I read this correctly, in Android, I do need a "truncated" STAX api.

like image 365
SlumpA Avatar asked Jan 05 '16 12:01

SlumpA


2 Answers

There are a number of problems when you try to use Apache POI and it's depending libraries in an Android Application. Among others there are duplicate classes in xmlbeans.jar, the "javax.*" packages are prohibited by the Android compiler and a few others.

There are currently two projects which try to fix those issues:

  • https://github.com/andruhon/android5xlsx
  • https://github.com/centic9/poi-on-android/ (which I maintain)

android5xlsx provides ready-made jar-files to include in your application, but currently uses a somewhat outdated version of POI. poi-on-android is based on POI 3.15-beta1 and can be recompiled for newer versions of POI fairly easily. Both projects are for Android 5+ and come with sample code and should allow basic usage of Apache POI on Android.

like image 93
centic Avatar answered Oct 01 '22 00:10

centic


Add implementation 'javax.xml.stream:stax-api:1.0' in you app build.gradle, as some core class missed

like image 31
Rama Shankar Rao Avatar answered Sep 30 '22 23:09

Rama Shankar Rao