Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
When encoding into xml, this error appears when there are embed objects in the response:
Fatal error: Call to a member function normalize() on a non-object in vendor/symfony/serializer/Encoder/XmlEncoder.php on line 476
This is because, Drupal\serialization\Encoder\XmlEncoder is never setting the $baseEncoder serializer.
Proposed resolution
In Drupal\serialization\Encoder\XmlEncoder::getBaseEncoder() we should call Symfony\Component\Serializer\Encoder\SerializerAwareEncoder::setSerializer() and set the serializer.
Remaining tasks
- Write Patch
User interface changes
N/A
API changes
After the change, XML format should work just like JSON.
Data model changes
N/A
Comment | File | Size | Author |
---|---|---|---|
#27 | interdiff-2685097-27.txt | 862 bytes | damiankloip |
#27 | 2685097-27.patch | 3.08 KB | damiankloip |
#27 | 2685097-27-test-only-FAIL.patch | 1.84 KB | damiankloip |
#23 | interdiff-2685097-23.txt | 688 bytes | damiankloip |
#23 | 2685097-23.patch | 3.08 KB | damiankloip |
Comments
Comment #3
cilefen CreditAttribution: cilefen commentedComment #4
ec0g CreditAttribution: ec0g as a volunteer and at Questex commentedWorking on reproducing this issue in the 8.2-x branch.
Comment #5
ec0g CreditAttribution: ec0g as a volunteer and at Questex commented@davidwbarratt or @cilefen, what's the best way to reproduce the issue? Are you using a REST view with an XML serializer? If so what kind of fields are you exporting?
I see where the "Symfony\Component\Serializer\Encoder\XmlEncoder" object is being instantiated without a serializer. I also see a serializer should have an instance (or multiple) of a normalizer in order for it to be able to normalize an object.
I haven't dug around this code at all, and I see that there's definitely a bug, but it will help if I can reproduce it. Thanks!
Comment #6
cilefen CreditAttribution: cilefen commentedCome find me in the sprint room.
Comment #7
cilefen CreditAttribution: cilefen commentedSorry, mentoring room...
Comment #8
ec0g CreditAttribution: ec0g as a volunteer and at Questex commentedSucks I missed you earlier @cilefen. Had to leave at 3pm.
Comment #9
damiankloip CreditAttribution: damiankloip at Tag1 Consulting commentedThis is likely still the same problem it was, this is the fix. I'm pretty sure I can reproduce but some steps in the issue description here would be good. There is a unit test for this, but the base encoder is set manually for the test so it can be mocked. So we might want to think about that. We could probably expose this in \Drupal\serialization\Tests\EntitySerializationTest but likely there is not an object getting serialized in that test so the serializer on the base xml encoder is not called.
Comment #10
damiankloip CreditAttribution: damiankloip at Tag1 Consulting commentedI think maybe this is not exposed in the regular entity tests also, because the entity is first normalized, which converts everything to an array. If you did the following, it would expose the bug:
Comment #11
damiankloip CreditAttribution: damiankloip at Tag1 Consulting commentedSomething simple like this can test it. A test only patch won't really show much though as the patch is required to have the setSerializer() method on the encoder.
Comment #13
Grayside CreditAttribution: Grayside at Phase2 commentedComment #14
Wim LeersThe only way I can reproduce this is if I add
xml
to one of the REST resource config entities (i.e. to make it support XML), but then fail to rebuild the router.That's being fixed in #2815845: Importing (deploying) REST resource config entities should automatically do the necessary route rebuilding.
If you think this issue still needs to be resolved: this issue will need an IS update to clarify how to reproduce this, and test to prove that it's fixed.
Finally: in #2800873: Add XML GET REST test coverage, work around XML encoder quirks, we're considering to remove XML support.
Comment #15
Wim LeersAlso, this is normal at best if this has received zero confirmations since it was reported: it doesn't seem to affect many sites. Also only 7 followers. Probably because almost no sites use the XML serializer.
Downgrading to normal.
Comment #17
damiankloip CreditAttribution: damiankloip at Acquia commentedThis can be reproduced quite easily IIRC, if you are using the serializer outside of rest. Not sure how not rebuilding the router would reproduce this issue? REST endpoints are not the only user of the serializer :) If you see my comment in #11 you can still reproduce this easily. As we already have the test and the fix for this, it still seems worth us just committing this.
Comment #18
damiankloip CreditAttribution: damiankloip at Acquia commentedComment #19
damiankloip CreditAttribution: damiankloip at Acquia commentedPatch in #11 is still good for 8.4.x
Comment #20
Pavan B S CreditAttribution: Pavan B S at Valuebound commentedRerolled the patch against latest 8.4.x, please review.
Comment #22
damiankloip CreditAttribution: damiankloip at Acquia commentedSweet, another commit mining attempt.
Comment #23
damiankloip CreditAttribution: damiankloip at Acquia commentedThe reroll was not good and broke things with a duplicate
use
statement.Comment #24
Wim LeersI'm tempted to close this because of #2800873: Add XML GET REST test coverage, work around XML encoder quirks.
Comment #25
damiankloip CreditAttribution: damiankloip at Acquia commentedHmm, well I think we should still support bugs of this nature. You can serialize anything using XML - not necessarily entities, or custom stuff. Anything really. Plus this already has the test coverage and the work is done :)
Comment #26
Wim LeersEvery minute spent on improving XML support is a minute not spent on improving everything else, which is what the 99.99% use. But, sure.
Grammatical problems here.
And can we please get a failing test-only patch and a passing complete patch? That'll help the core committer that looks at this.
Comment #27
damiankloip CreditAttribution: damiankloip at Acquia commentedHere are those changes quickly, I actually hit this issue when doing something for work yesterday! :)
Comment #28
Wim LeersSo you're using the
xml
normalizer?Aren't you also running into #2800873: Add XML GET REST test coverage, work around XML encoder quirks then?
Comment #29
damiankloip CreditAttribution: damiankloip at Acquia commentedHa, well, it wasn't being used for a fieldable entity - so it was ok.
Comment #30
Wim LeersMakes sense :)
Comment #32
alexpottCommitted and pushed 081132d to 8.4.x and 009a535 to 8.3.x. Thanks!
I've committed this to 8.3.x because essentially the XmlEncoder is broken and useless without this.
@ec0g thanks for trying to reproduce the issue. I thought about crediting you on this issue because of comment #5 which pinpointed where things were going wrong. But this was also included in the issue summary.
@Pavan B S I've not credited you on the issue because the reroll was not a good one. Given the patch contained a unit test that could have easily been run prior to uploading the patch to confirm the re-roll worked.
Sorted out all the spacing on commit.
Comment #35
Wim LeersThanks for your impressive diligence, Alex!
Comment #37
victor.priceputu CreditAttribution: victor.priceputu commentedThis fix actually breaks the serializer.
Line
Using the service 'serializer.encoder.xml' no longer works, as $this->serializer is NULL.
Comment #38
damiankloip CreditAttribution: damiankloip at Acquia commentedThat would suggest you're trying to use the XmlEncoder directly, not through the serializer. This is a standard pattern from Symfony, SerializerAwareEncoders get setSerializer() called on them when the serializer instance is created. You can't have been using this too well before due to this bug anyway. The XmlEncoder needs the serializer to do anything useful.
Comment #39
Wim Leers#37 + #38: somebody reported the same at #2891850: Fatal error on serialization module.