RecordConverter: Do not throw ClassNotFoundException when "class" attribute is absent#351
Open
toby1984 wants to merge 1 commit intox-stream:masterfrom
Open
RecordConverter: Do not throw ClassNotFoundException when "class" attribute is absent#351toby1984 wants to merge 1 commit intox-stream:masterfrom
toby1984 wants to merge 1 commit intox-stream:masterfrom
Conversation
Contributor
Author
|
Any chance this PR will get merged and XStream 1.5.x released ? We'd like to get rid of your in-house patched version. |
Member
|
As already said on the list: The RecordConverter needs a complete rewrite, since it does not support a large set of standard functionalities. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR fixes a crash in RecordConverter during deserialization.
For some reason the RecordConverter implementation assumes that either the "class" attribute is present or the XML tag name is the record classname. This is not true in at least one case (see unit test added by this PR) and causes a ClassNotFoundException when RecordConverter tries to resolve the member field name as a class.
I'm not familiar with the XStream design but after stepping through the code it seems that the "class" attribute is not being omitted by bug/accident but intentionally (most likely to save memory/disk space) when the actual type of a value stored in a field matches the field's type... so to me it looks like the crash is caused by a bug in RecordConverter and not outside code.
I've fixed the issue by using UnmarshallingContext#getRequiredType() instead of trying to use the "class" attribute and falling back to HierarchicalStreamReader#getNodeName() ... not sure whether this is the right approach though or why the original RecordConverter contribution did not use that method in the first place.
Because I was unsure about using UnmarshallingContext#getRequiredType() I've added a couple additional test cases (Object field type, Object field containing an object array ) to my unit test but it still passes so at least my fix is not trivially wrong.
For the sake of completeness, this is the exception being thrown when running my test case without my RecordConverter change:
com.thoughtworks.xstream.converters.ConversionException:
Class not found.
---- Debugging information ----
message : Class not found.
cause-exception : java.lang.ClassNotFoundException
cause-message : field1
class : com.thoughtworks.xstream.converters.extended.RecordConverterTest$SerializableRecord
required-type : com.thoughtworks.xstream.converters.extended.RecordConverterTest$SerializableRecord
converter-type : com.thoughtworks.xstream.converters.extended.RecordConverter
path : /com.thoughtworks.xstream.converters.extended.RecordConverterTest$MyObj/field1
line number : 1
class[1] : com.thoughtworks.xstream.converters.extended.RecordConverterTest$MyObj
required-type[1] : com.thoughtworks.xstream.converters.extended.RecordConverterTest$MyObj
converter-type[1] : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
version : not available
Caused by: java.lang.ClassNotFoundException: field1
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:375)
at com.thoughtworks.xstream.converters.extended.RecordConverter.classForName(RecordConverter.java:222)
... 40 more