- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 230
Description
I am trying to deserialise some XML and am getting the following exception.
I have these includes:
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.13.2"
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.2")
implementation("com.fasterxml.woodstox:woodstox-core:6.2.8")
I can serialise/deserialize json fine, the issue is just with XML.
java.lang.NoSuchMethodError: No static method newFactory(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljavax/xml/stream/XMLInputFactory; in class Ljavax/xml/stream/XMLInputFactory; or its super classes (declaration of 'javax.xml.stream.XMLInputFactory' appears in /data/app/~~uieaA4ZwQHgkIyUGH_LkxA==/com.clashcaddie.clashcaddie-xRbKiEW2_xNYMI-cfwHckQ==/base.apk!classes14.dex) at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:115) at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:101) at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:85) at com.fasterxml.jackson.dataformat.xml.XmlMapper.<init>(XmlMapper.java:127) at com.clashcaddie.clashcaddie.ui.caddieoverlay.GridSettingsOverlayViewModel.saveGrids(GridSettingsOverlayViewModel.kt:69) at com.clashcaddie.clashcaddie.ui.caddieoverlay.GridSettingsOverlayViewModel.applyGrids(GridSettingsOverlayViewModel.kt:53) at com.clashcaddie.clashcaddie.databinding.ActivityGridSettingsOverlayBindingImpl._internalCallbackOnClick(ActivityGridSettingsOverlayBindingImpl.java:283) at com.clashcaddie.clashcaddie.generated.callback.OnClickListener.onClick(OnClickListener.java:11) at android.view.View.performClick(View.java:7455) at android.view.View.performClickInternal(View.java:7432) at android.view.View.access$3700(View.java:835) at android.view.View$PerformClick.run(View.java:28810) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7842) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
2022-06-22 13:54:26.194 17351-17351/com.clashcaddie.clashcaddie E/AndroidRuntime: FATAL EXCEPTION: main Process: com.clashcaddie.clashcaddie, PID: 17351 java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/xml/stream/XMLInputFactory; at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:115) at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:101) at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:85) at com.fasterxml.jackson.dataformat.xml.XmlMapper.<init>(XmlMapper.java:127) at com.clashcaddie.clashcaddie.ui.caddieoverlay.GridSettingsOverlayViewModel.saveGrids(GridSettingsOverlayViewModel.kt:66) at com.clashcaddie.clashcaddie.ui.caddieoverlay.GridSettingsOverlayViewModel.applyGrids(GridSettingsOverlayViewModel.kt:50) at com.clashcaddie.clashcaddie.databinding.ActivityGridSettingsOverlayBindingImpl._internalCallbackOnClick(ActivityGridSettingsOverlayBindingImpl.java:283) at com.clashcaddie.clashcaddie.generated.callback.OnClickListener.onClick(OnClickListener.java:11) at android.view.View.performClick(View.java:7455) at android.view.View.performClickInternal(View.java:7432) at android.view.View.access$3700(View.java:835) at android.view.View$PerformClick.run(View.java:28810) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7842) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) Caused by: java.lang.ClassNotFoundException: Didn't find class "javax.xml.stream.XMLInputFactory" on path: DexPathList[[dex file "/data/data/com.clashcaddie.clashcaddie/code_cache/.overlay/base.apk/classes4.dex", dex file "/data/data/com.clashcaddie.clashcaddie/code_cache/.overlay/base.apk/classes.dex", dex file "/data/data/com.clashcaddie.clashcaddie/code_cache/.overlay/base.apk/classes14.dex", zip file "/data/app/~~NbB0p3D0j-XgvmhaM3JYmg==/com.clashcaddie.clashcaddie-cnHJSvUA99dufgkz2-Gs7g==/base.apk"],nativeLibraryDirectories=[/data/app/~~NbB0p3D0j-XgvmhaM3JYmg==/com.clashcaddie.clashcaddie-cnHJSvUA99dufgkz2-Gs7g==/lib/arm64, /system/lib64, /system_ext/lib64]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:218) at java.lang.ClassLoader.loadClass(ClassLoader.java:379) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:115) at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:101) at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:85) at com.fasterxml.jackson.dataformat.xml.XmlMapper.<init>(XmlMapper.java:127) at com.clashcaddie.clashcaddie.ui.caddieoverlay.GridSettingsOverlayViewModel.saveGrids(GridSettingsOverlayViewModel.kt:66) at com.clashcaddie.clashcaddie.ui.caddieoverlay.GridSettingsOverlayViewModel.applyGrids(GridSettingsOverlayViewModel.kt:50) at com.clashcaddie.clashcaddie.databinding.ActivityGridSettingsOverlayBindingImpl._internalCallbackOnClick(ActivityGridSettingsOverlayBindingImpl.java:283) at com.clashcaddie.clashcaddie.generated.callback.OnClickListener.onClick(OnClickListener.java:11) at android.view.View.performClick(View.java:7455) at android.view.View.performClickInternal(View.java:7432) at android.view.View.access$3700(View.java:835) at android.view.View$PerformClick.run(View.java:28810) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7842) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
Activity
cowtowncoder commentedon Jun 22, 2022
Perhaps Android SDK does not include JDK Stax API (types in
javax.xml.stream
)? Or has an incompatible version.You may be able to work around this by constructing
XMLInputFactory
(andXMLOutputFactory
) directly -- implementations from Woodstox areWstxInputFactory
andWstxOutputFactory
-- and constructingXmlFactory
with those, and thenXmlMapper
with thisXmlFactory
.clashcaddie commentedon Jun 22, 2022
Unfortunately the types aren't compatible
var inputFactory = WstxInputFactory()
var xmlFactory = XmlFactory(inputFactory)
XmlFactory
won't takeWstxInputFactory
it requiresXMLInputFactory
cowtowncoder commentedon Jun 22, 2022
But
WstxInputFactory
ISjavax.xml.stream.XMLInputFactory
, similarlyWstxOutputFactory
isjavax.xml.stream.XMLOutputFactory
(in both cases through intermediateXMLInputFactory2
/XMLOutputFactory2
types).You can see that from
So if IDE shows these as incompatible, there is something wrong with API jars.
farmisen commentedon Jul 13, 2022
@clashcaddie
After adding
implementation 'javax.xml.stream:stax-api:1.0-2'
to my dependencies the following works for me:vitorpamplona commentedon Aug 31, 2022
To help clarify this, the default XmlFactory calls a javax.xml.stream.XMLInputFactory.newFactory function that does not exist on Android. Looks like this method from the JavaX Stream API was introduced on Java 11 and hasn't been added to Android yet.
All Android usages of this lib must hardcode their Factories:
cowtowncoder commentedon Aug 31, 2022
I don't think it can be in Java 11; Jackson 2.x only requires Java 8 now. I think javax.xml.stream itself was added in JDK 6 and I thought all methods we call would be in JDK 6.
However, Android has always had gnarly issues in arbitrarily leaving out some JDK packages and I remember years ago
javax.xml.stream
was one such package: was neither included NOR COULD BE INCLUDED since alljavax.
packages where deny-listed. :-(Thank you for including the necessary workaround, that should help Android users facing the issue.
vitorpamplona commentedon Aug 31, 2022
Actually, I misspoke. Android doesn't have any
javax.xml.stream.*
classes. Generally, people addjavax.xml.stream:stax-api:1.0-2
to fix the issue. But thestax-api
'sXMLInputFactory
doesn't have the newnewFactory
method. It uses the oldnewInstance
API.Same issue when using
xerces:xercesImpl
. The implementation ofxml-apis:xml-apis
doesn't have the newnewFactory
methodcowtowncoder commentedon Aug 31, 2022
Ah... that's unfortunate but not surprising.
I would take a PR against 2.14 to use the old "deprecated" method if that helps Android compatibility.
[-]java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/xml/stream/XMLInputFactory[/-][+](Android) java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/xml/stream/XMLInputFactory[/+]Update release notes wrt #533
cowtowncoder commentedon Mar 13, 2023
Hoping that PR #583 resolves this for upcoming 2.15.0