[ 
https://issues.apache.org/jira/browse/XMLBEANS-612?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Dominik Stadler updated XMLBEANS-612:
-------------------------------------
    Description: 
The project [https://github.com/centic9/poi-on-android] allows to run Apache 
POI as part of Android Apps and thus also uses XMLBeans.

When trying to update to Apache POI 5.2.2 and XMLBeans 5.1.0, I saw that there 
is a problem with the Class-loading.

XMLBeans tries to do the following
{noformat}
cl.getResource("xyz.class") {noformat}
However on Android you cannot get class-resources this way.

It seems this is only done to prevent a ClassNotFoundException in the call to 
{{Class.forName}} which follows.

 

Therefore I propose to change the code as follows so that we simply expect a 
ClassNotFoundException instead of doing this separate lookup via getResource()
{noformat}
// BEGIN CHANGES 
=========================================================================
//
// Simply remove this pre-check and handle ClassNotFoundException below
// as Android does not find .class-files in getResource()
//
// See 
https://stackoverflow.com/questions/72616517/looking-up-class-files-via-classloader-getresource-on-android
// for a related question
//
/*if (cl.getResource(clName.replace(".", "/") + ".class") == null) {
    // if the first class isn't found in the package, continue with the next 
package
    break;
}*/

try {
    @SuppressWarnings("unchecked")
    Class<? extends SchemaTypeLoader> cls = (Class<? extends SchemaTypeLoader>) 
Class.forName(clName, true, cl);
    list.add((SchemaTypeLoader) cls.getDeclaredField("typeSystem").get(null));
} catch (ClassNotFoundException e) {
    // if the first class isn't found in the package, continue with the next 
package
    // this can happen and thus is ignored here
} catch (Exception e) {
    throw new XmlRuntimeException(e);
}
// END-CHANGES 
========================================================================={noformat}
 

Applying this change locally makes the project work on Android with Apache POI 
5.2.2 and XMLBeans 5.1.0.

  was:
The project [https://github.com/centic9/poi-on-android] allows to run Apache 
POI as part of Android Apps and thus also uses XMLBeans.

When trying to update to Apache POI 5.2.0, I saw that there is a problem with 
the SAX parser on Android as it fails when both features "namespaces" and 
"namespace-prefix" are set to true.

XMLBeans currently does this in the class {{Locale.SaxLoader}} and thus an 
Android Application crashes with an error "The 'namespace-prefix' feature is 
not supported while the 'namespaces' feature is enabled."

 

Therefore I  will introduce a system property which can be used to control the 
SAX feature "namespace-prefixes" to be able to set it to "false" if required.

 

The full stacktrace is:

 
{noformat}
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: org.dstadler.poiandroidtest.poitest, PID: 26552
    java.lang.RuntimeException: Unable to start activity 
ComponentInfo{org.dstadler.poiandroidtest.poitest/org.dstadler.poiandroidtest.poitest.DocumentListActivity}:
 java.lang.IllegalStateException: org.apache.poi.ooxml.POIXMLException: unable 
to parse shared strings table
        at 
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
        at 
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at 
com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
     Caused by: java.lang.IllegalStateException: 
org.apache.poi.ooxml.POIXMLException: unable to parse shared strings table
        at 
org.dstadler.poiandroidtest.poitest.DocumentListActivity.onCreate(DocumentListActivity.java:191)
        at android.app.Activity.performCreate(Activity.java:6975)
        at 
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
        at 
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
        at 
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6541) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at 
com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 
     Caused by: org.apache.poi.ooxml.POIXMLException: unable to parse shared 
strings table
        at 
org.apache.poi.ooxml.POIXMLFactory.createDocumentPart(POIXMLFactory.java:68)
        at 
org.apache.poi.ooxml.POIXMLDocumentPart.read(POIXMLDocumentPart.java:661)
        at org.apache.poi.ooxml.POIXMLDocument.load(POIXMLDocument.java:165)
        at 
org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:274)
        at 
org.apache.poi.xssf.usermodel.XSSFWorkbookFactory.createWorkbook(XSSFWorkbookFactory.java:118)
        at 
org.apache.poi.xssf.usermodel.XSSFWorkbookFactory.create(XSSFWorkbookFactory.java:98)
        at 
org.apache.poi.xssf.usermodel.XSSFWorkbookFactory.create(XSSFWorkbookFactory.java:36)
        at 
org.apache.poi.ss.usermodel.WorkbookFactory.lambda$create$2(WorkbookFactory.java:224)
        at 
org.apache.poi.ss.usermodel.WorkbookFactory$$ExternalSyntheticLambda4.create(Unknown
 Source:2)
        at 
org.apache.poi.ss.usermodel.WorkbookFactory.wp(WorkbookFactory.java:329)
        at 
org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:224)
        at 
org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:185)
        at 
org.dstadler.poiandroidtest.poitest.DocumentListActivity.onCreate(DocumentListActivity.java:81)
        at android.app.Activity.performCreate(Activity.java:6975) 
        at 
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213) 
        at 
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770) 
        at 
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6541) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at 
com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 
     Caused by: java.io.IOException: unable to parse shared strings table
        at 
org.apache.poi.xssf.model.SharedStringsTable.readFrom(SharedStringsTable.java:136)
        at 
org.apache.poi.xssf.model.SharedStringsTable.<init>(SharedStringsTable.java:112)
        at 
org.apache.poi.xssf.usermodel.XSSFRelation$$ExternalSyntheticLambda14.init(Unknown
 Source:2)
        at 
org.apache.poi.ooxml.POIXMLFactory.createDocumentPart(POIXMLFactory.java:61)
        at 
org.apache.poi.ooxml.POIXMLDocumentPart.read(POIXMLDocumentPart.java:661) 
        at org.apache.poi.ooxml.POIXMLDocument.load(POIXMLDocument.java:165) 
        at 
org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:274) 
        at 
org.apache.poi.xssf.usermodel.XSSFWorkbookFactory.createWorkbook(XSSFWorkbookFactory.java:118)
 
        at 
org.apache.poi.xssf.usermodel.XSSFWorkbookFactory.create(XSSFWorkbookFactory.java:98)
 
        at 
org.apache.poi.xssf.usermodel.XSSFWorkbookFactory.create(XSSFWorkbookFactory.java:36)
 
        at 
org.apache.poi.ss.usermodel.WorkbookFactory.lambda$create$2(WorkbookFactory.java:224)
 
        at 
org.apache.poi.ss.usermodel.WorkbookFactory$$ExternalSyntheticLambda4.create(Unknown
 Source:2) 
        at 
org.apache.poi.ss.usermodel.WorkbookFactory.wp(WorkbookFactory.java:329) 
        at 
org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:224) 
        at 
org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:185) 
        at 
org.dstadler.poiandroidtest.poitest.DocumentListActivity.onCreate(DocumentListActivity.java:81)
 
        at android.app.Activity.performCreate(Activity.java:6975) 
        at 
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213) 
        at 
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770) 
        at 
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6541) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at 
com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 
     Caused by: org.apache.xmlbeans.XmlException: error: The 'namespace-prefix' 
feature is not supported while the 'namespaces' feature is enabled.
        at 
org.apache.xmlbeans.impl.store.Locale$SaxLoader.load(Locale.java:2565)
        at 
org.apache.xmlbeans.impl.store.Locale.lambda$parseToXmlObject$3(Locale.java:725)
        at 
org.apache.xmlbeans.impl.store.Locale$$ExternalSyntheticLambda4.parse(Unknown 
Source:6)
        at org.apache.xmlbeans.impl.store.Locale.syncWrap(Locale.java:498)
        at 
org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:724)
        at 
org.apache.xmlbeans.impl.schema.SchemaTypeLoaderBase.parse(SchemaTypeLoaderBase.java:233)
        at 
org.apache.xmlbeans.impl.schema.AbstractDocumentFactory.parse(AbstractDocumentFactory.java:71)
        at 
org.apache.poi.xssf.model.SharedStringsTable.readFrom(SharedStringsTable.java:125)
        at 
org.apache.poi.xssf.model.SharedStringsTable.<init>(SharedStringsTable.java:112)
 
        at 
org.apache.poi.xssf.usermodel.XSSFRelation$$ExternalSyntheticLambda14.init(Unknown
 Source:2) 
        at 
org.apache.poi.ooxml.POIXMLFactory.createDocumentPart(POIXMLFactory.java:61) 
        at 
org.apache.poi.ooxml.POIXMLDocumentPart.read(POIXMLDocumentPart.java:661) 
        at org.apache.poi.ooxml.POIXMLDocument.load(POIXMLDocument.java:165) 
        at 
org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:274) 
        at 
org.apache.poi.xssf.usermodel.XSSFWorkbookFactory.createWorkbook(XSSFWorkbookFactory.java:118)
 
        at 
org.apache.poi.xssf.usermodel.XSSFWorkbookFactory.create(XSSFWorkbookFactory.java:98)
 
        at 
org.apache.poi.xssf.usermodel.XSSFWorkbookFactory.create(XSSFWorkbookFactory.java:36)
 
        at 
org.apache.poi.ss.usermodel.WorkbookFactory.lambda$create$2(WorkbookFactory.java:224)
 
        at 
org.apache.poi.ss.usermodel.WorkbookFactory$$ExternalSyntheticLambda4.create(Unknown
 Source:2) 
        at 
org.apache.poi.ss.usermodel.WorkbookFactory.wp(WorkbookFactory.java:329) 
        at 
org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:224) 
        at 
org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:185) 
        at 
org.dstadler.poiandroidtest.poitest.DocumentListActivity.onCreate(DocumentListActivity.java:81)
 
        at android.app.Activity.performCreate(Activity.java:6975) 
        at 
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213) 
        at 
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770) 
        at 
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6541) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at 
com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 
E/AndroidRuntime: Caused by: org.xml.sax.SAXNotSupportedException: The 
'namespace-prefix' feature is not supported while the 'namespaces' feature is 
enabled.
        at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:258)
        at 
org.apache.xmlbeans.impl.store.Locale$SaxLoader.load(Locale.java:2538)
            ... 34 more {noformat}


> Adjust Class loading for using XMLBeans on Android
> --------------------------------------------------
>
>                 Key: XMLBEANS-612
>                 URL: https://issues.apache.org/jira/browse/XMLBEANS-612
>             Project: XMLBeans
>          Issue Type: New Feature
>    Affects Versions: Version 5.0.3
>            Reporter: Dominik Stadler
>            Assignee: Dominik Stadler
>            Priority: Major
>             Fix For: Version 5.1.0
>
>
> The project [https://github.com/centic9/poi-on-android] allows to run Apache 
> POI as part of Android Apps and thus also uses XMLBeans.
> When trying to update to Apache POI 5.2.2 and XMLBeans 5.1.0, I saw that 
> there is a problem with the Class-loading.
> XMLBeans tries to do the following
> {noformat}
> cl.getResource("xyz.class") {noformat}
> However on Android you cannot get class-resources this way.
> It seems this is only done to prevent a ClassNotFoundException in the call to 
> {{Class.forName}} which follows.
>  
> Therefore I propose to change the code as follows so that we simply expect a 
> ClassNotFoundException instead of doing this separate lookup via getResource()
> {noformat}
> // BEGIN CHANGES 
> =========================================================================
> //
> // Simply remove this pre-check and handle ClassNotFoundException below
> // as Android does not find .class-files in getResource()
> //
> // See 
> https://stackoverflow.com/questions/72616517/looking-up-class-files-via-classloader-getresource-on-android
> // for a related question
> //
> /*if (cl.getResource(clName.replace(".", "/") + ".class") == null) {
>     // if the first class isn't found in the package, continue with the next 
> package
>     break;
> }*/
> try {
>     @SuppressWarnings("unchecked")
>     Class<? extends SchemaTypeLoader> cls = (Class<? extends 
> SchemaTypeLoader>) Class.forName(clName, true, cl);
>     list.add((SchemaTypeLoader) cls.getDeclaredField("typeSystem").get(null));
> } catch (ClassNotFoundException e) {
>     // if the first class isn't found in the package, continue with the next 
> package
>     // this can happen and thus is ignored here
> } catch (Exception e) {
>     throw new XmlRuntimeException(e);
> }
> // END-CHANGES 
> ========================================================================={noformat}
>  
> Applying this change locally makes the project work on Android with Apache 
> POI 5.2.2 and XMLBeans 5.1.0.



--
This message was sent by Atlassian Jira
(v8.20.7#820007)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@poi.apache.org
For additional commands, e-mail: dev-h...@poi.apache.org

Reply via email to