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

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:
build.gradle:
dexOptions {
coreLibrary true;
}
build.gradle:
dexOptions {
preDexLibraries = false
}
project.tasks.withType(com.android.build.gradle.tasks.Dex) {
additionalParameters=['--core-library']
}
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.

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.

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

Related

How best to provide JAXB components in an RCP application

My RCP application makes calls to SOAP web services and has been using the built-in JAXB/JEE components in Java 1.8. I have set up the build process to force the use of Java 1.8 and this had been working well.
Recently, the build stopped working because the builder (Tycho) now has a component which only works with later Java versions. If I compile with the later version I get 100's of JEE-related errors such as JaxbElement not found or #WebMethod not found.
At some point we will have to move away from Java 1.8 and use a Java version which does not provide those JEE components, so forcing the use of 1.8 can only be a short-term solution.
Is there an eclipse plugin which already provides those missing components? (I have searched but not found anything) Or do I need to create my own helper plugin which contains the necessary libraries? Is there perhaps a JAXB alternative which I could use for the SOAP calls?
The JAXB plugins/bundles are available on Eclipse Orbit: the plugins/bundles starting with javax..
In the plugins/bundles where they are needed, add the dependency in the MANIFEST.MF file via Import-Package (using Require-Bundle would require that these plugins/bundles are available even when using Java 8).
See also this answer.

Java types cannot be resolved to a type in Eclipse with JRE System Library included

We have a legacy Java project which we are trying to get compiled within Eclipse. The project has been extracted from a live environment where it is working. A .JAR file within the lib folder has been reverse engineered using JD Decompiler and opened in Eclipse.
This has imported all the source code however it doesn’t build. The errors are related to what seems to be missing primitive types. The kind of thing you would expect to find in the base Java System Library which we have included, for example:
AbstractButton cannot be resolved to a type
AbstractTableModel cannot be resolved to a type
ActionEvent cannot be resolved to a type
etc. with over 3000 errors of differing types.
The solution was written some decades ago against Java SE 1.1. We have therefore attempted to import both historical system libraries around that time as well as more recent ones too including the latest Java SE 14.
We are importing these through the Configure Build Path window as a Library. I have added an ** allow all wildcard access rule to prevent any access errors which we were previously seeing.
We have also tried different libraries as both the Execution environment and Alternative JRE as well as trying the fix suggested in this YouTube video HERE
Can anyone suggest anything that we may be missing?
Thanks

Upgrading existing Java Project from Java 1.6 to 1.8

Recently I was assigned to a task wherein I have to upgrade the existing standalone java application from Java 1.6 to Java 1.8.
I'm yet to go through the code and I have no idea about this project.
They were using
ANT 1.6.1,
AXIS 1.5.1,
ABINITIO 2.15,
ORACLE 11.1.0.7,
AUTOSYS R11,
Java 1.6.
I got to know that first I need to identify whether the above mentioned Tools/Frameworks are compatible with Java 1.8.
Please suggest what are the other challenges I might encounter while compiling and building the application?
Although Java is supposed to be backward compatible between versions, it's also known that backward compatibility in any language isn't aways as straight forward as the name suggests. Some (most) projects release it's libs versions compiled specifically targeting one or another development kit, to take advantage of new features and enhancements added to the language.
That being said, I believe the smarter way to go would be: first, update the project's JDK and rebuild it targeting the new bytecode's version. There's a chance you'll have to upgrade both Ant and (if that's your IDE of choice) Eclipse (see here why).
Second, you'll have to check for compilation errors, which will most likely lead you to update libraries conditionally to get them fixed. With those solved, you MUST run your app and see if it's running as intended; remember that compilation problems are just the top of the iceberg when the subject are dependencies.
Carefully check the app's logs looking for exceptions of any kind but mainly the ones related to class loading exceptions such as ClassCastException, ClassNotFoundException, NoClassDefFoundException, UnsatisfiedLinkError and others. If any apear, you'll have to pinpoint one by one and search for the specific solution of the specific troublemaker library.
With all that covered, you should have your app running healthily again.
One last hint, if this project of yours is still being developed, it would be a very good practice to keep the tools you use updated to their very last release. Keep also the development tools updated, like build (such as Ant, Maven, Gradle and others), JDK's and IDE's. It way easier to upgrade the pieces as they are release than to handle a mass scale upgrade :)

Can't compile the Gallery2 project

I downloaded the project folder from :
https://android.googlesource.com/platform/packages/apps/Gallery2/
For some reason, when I opened it into my Eclipse environment, it is not compiling and it shows a lot of broken references. I am attaching screenshot for your reference:
Any ideas if I am doing something wrong or the code itself has issues?
This is a platform package, not a stand alone 3rd party package. It uses classes which are part of the platform, but not the Android SDK. It's built with the platform as a whole using make rather than Eclipse and ultimately is in the ROM (i.e. flash image.) You won't be able to build it with Eclipse and try to deploy it.
Many of Android's core apps depend on internal system APIs that are not available in the standard SDK that developers compile against. You can find some more information from this question.

Java compilation problem, Linux, project from Eclipse re-compile on Linux

I am trying to recompile an existing Java project exported from Eclipse. It is necessary to recompile this because I am running simulations remotely on other machines where a different (older) version of Java is installed. I have tried recompiling my .java file which specifies the simulation in question. However, it appears that it is necessary to recompile all other classes etc as well. Has anyone got an idea how to do this WITHOUT using Eclipse (I am not the Admin on the other machines and thus Eclipse is unavailable to me) and not manually because the project is quite huge?
Thanks a lot for any suggestions!
I recommend you to always have an command line way to build an application. The usual way to do this in Java is using ANT (or Maven).
As #Santiago Lezica says, Eclipse can generate an Ant file.
I believe that Eclipse allows you to build for an older target platform than the one you are currently running. That way you can do all of your builds locally.
The second approach has the advantage that you can fix any problems arising from compiling for the older platforms (e.g. use of new language features, use of new classes / methods) from the comfort of your own ... workstation.
There is another option that you should consider: Tell Eclipse to generate code for the old Java version (see the compiler options). That way, you can create code that runs on Java 1.3, even if Eclipse uses Java 5.
Not sure what your requirements are, but you could set the compiler level for your projects at the (older) level of your Linux installs. This would cause Eclipse to recompile it at that version, instead of a newer version.
At my company we use IBM's Rational Application Developer (instead of pure Eclipse), but I am assuming the option is in the same spot. If you right-click on your project, you can go to the Java Compiler options and then set the compatibility to the level of that on Linux (1.3, 1.4, etc.).
Since compile Java byte-code is supposed to be portable (for the most part), this should get you past most of your problems.
Otherwise, the other option is to use something like Ant or Maven scripts (which can be kicked off by Eclipse) and then just use a property to set the compiler right before you run it. This way you don't have to switch properties on your projects all the time, if you truly do need "newer" compiled code and can't live with "older" code on both systems.

Categories