Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XMLParser problem when using poi-on-android and SODS at the same time #39

Open
Moonglasses opened this issue Feb 10, 2022 · 7 comments
Open

Comments

@Moonglasses
Copy link

Hi there,
I was recently looking for a solution that'd help me with processing spreadsheet files, which wasn't an easy task.
For processing xls/xlsx files I settled wtih using a "poi-on-android" library, which puts together all the pieces and libraries necessary to "just work".
Now when I try to use SODS as a complementary library to parse ODS files, I run into couple of problems:

Running SODS completely standalone throws following error:
java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/xml/stream/XMLInputFactory;
Which I'm able to solve like so and SODS is running just fine then:
implementation group: 'stax', name: 'stax', version: '1.2.0'

Running SODS side by side with poi-on-android without previous import throws the exact same error.

Running SODS side by side with poi-on-android, which is what I'd like to achieve, with the inclusion of stax library throws following error:
Process: com.moonglasses.odsimporttest, PID: 31140 java.lang.ExceptionInInitializerError at com.github.miachm.sods.OdsReader.<init>(OdsReader.java:19) at com.github.miachm.sods.OdsReader.load(OdsReader.java:37) at com.github.miachm.sods.SpreadSheet.<init>(SpreadSheet.java:52) at com.moonglasses.odsimporttest.ODSReader.read(ODSReader.java:35) at com.moonglasses.odsimporttest.MainActivity.lambda$initActivityLauncher$1$com-moonglasses-odsimporttest-MainActivity(MainActivity.java:65) at com.moonglasses.odsimporttest.MainActivity$$ExternalSyntheticLambda1.run(Unknown Source:6) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:923) Caused by: java.lang.ClassCastException: com.fasterxml.aalto.stax.InputFactoryImpl cannot be cast to javax.xml.stream.XMLInputFactory at javax.xml.stream.XMLInputFactory.newInstance(XMLInputFactory.java:136) at com.github.miachm.sods.XmlReaderEventImpl.<clinit>(XmlReaderEventImpl.java:10) at com.github.miachm.sods.OdsReader.<init>(OdsReader.java:19)  at com.github.miachm.sods.OdsReader.load(OdsReader.java:37)  at com.github.miachm.sods.SpreadSheet.<init>(SpreadSheet.java:52)  at com.moonglasses.odsimporttest.ODSReader.read(ODSReader.java:35)  at com.moonglasses.odsimporttest.MainActivity.lambda$initActivityLauncher$1$com-moonglasses-odsimporttest-MainActivity(MainActivity.java:65)  at com.moonglasses.odsimporttest.MainActivity$$ExternalSyntheticLambda1.run(Unknown Source:6)  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)  at java.lang.Thread.run(Thread.java:923) 

The poi-on-android library itself requires a certain hack to make it find a suitable XML Parser, the recomedation is to use following code:
System.setProperty("org.apache.poi.javax.xml.stream.XMLInputFactory", "com.fasterxml.aalto.stax.InputFactoryImpl");
System.setProperty("org.apache.poi.javax.xml.stream.XMLOutputFactory", "com.fasterxml.aalto.stax.OutputFactoryImpl");
System.setProperty("org.apache.poi.javax.xml.stream.XMLEventFactory", "com.fasterxml.aalto.stax.EventFactoryImpl");

Using or not using this doesn't change the way SODS behaves. I was guessing I could maybe use this hack separately for poi and for SODS to convince both to use the XML Parser of their liking before I use them, but I'm just lost in all the stuff surrounding the topic of processing spreadsheet files on android in general.

Would someone more knowledgeable in the topic be so kind to maybe suggest some solutions please?

@github-actions
Copy link

Thanks for your report! Please ensure you have provided enough info in order to recreate the issue, including the problematic ODS File.' first issue

@miachm
Copy link
Owner

miachm commented Feb 10, 2022

This look really interesting.

SODS wasn't designed to run in Android but I suppose it could work. The problem is to find a suitable XML parser which replaces javax.

Do you have a XML parser in Android which API is similar to the javax.xml.stream?

@Moonglasses
Copy link
Author

It actually does work just fine if I use it alone without the poi and resolve the XML parser error by importing the stax library which I mentioned:
https://mvnrepository.com/artifact/stax

The problem is, my priority is parsing xls files, therefore I need to have the xls processing working. And after a day of work only working solution on Android I found was the poi-on-android library, which does some voodoo to make the XML parser work, because it runs into the same problems if you want to use just the apache poi libraries. I'm not a super skilled developer, but even all the smart ppl had a hard time making these work on Android.

But back to the issue, I think the stax library should be more than suitable if it works alone, it does contain a XML parser. But I can't figure out why poi library suddenly interferes with this even if I don't set the system properties and therefore not making it look in the wrong places for the parser.
I thought maybe setting the property to the stax library instead of the "com.fasterxml.." would work, but no luck so far.

@miachm
Copy link
Owner

miachm commented Feb 10, 2022

Probably you could fork SODS and change the code in order to use stax instead of javax. Since the XML API is the same, you only need to change the import name and it should just work.

@Moonglasses
Copy link
Author

Sounds reasonable, gonna give it a try perhaps later tomorrow and get back here with the result. Thank you for you time so far.

@Moonglasses
Copy link
Author

Hi Miguel, I managed to make your code work in my project, but with a big questionmark in the air.

After some time of trying I realized I really lack the knowledge and mostly time right now to figure out how to compile the possible changes I'd make to your project and use this new lib in my project, so I went the easy way just to try if I can even make it work.
I copied the necessary classes from your project into mine and tried to play with the XML parsers. There seems to be some serious fight for resources between the poi lib and yours, because even when using the proper XML parser libs I mentioned work standalone with your lib, I wasn't able to make it work side by side with poi.
Last thing I tried was using the poi XML parser in your code and miraculously it works! The problem though is, like I said I just gutted your lib for the source files and didn't use it as a proper lib. Which obviously is fine by me as long as it works, but even though you present your project as unlicenced, I'd rather avoid any licencing or intellectual property problems and if you wish for me to not use the code this way, I can totally abandon this. Being able to parse an ODS content is just a bonus for me in my project.

Maybe I can use the forked project as a module in the project of mine side by side, but again, that's out of my knowledge scope and I'm close to few deadlines.

@miachm
Copy link
Owner

miachm commented Feb 14, 2022

Thanks for heading back!

It's a shame Java is not entirely compatible with Android. Thanks for trying and sharing the experience.

Even though Android is not a supported platform for SODS. I could try to add a feature in the API which allows to set a custom XML parser, something like:

Spreadsheet.internals.setXmlParser(new MyCustomXMLParser());

Maybe this could allow a way to work in Android. It's worth to study.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants