Skip to content

[java] Fix duplicate field name handling in InstanceCoercer#getFieldWriters - #17187

Merged
asolntsev merged 4 commits into
SeleniumHQ:trunkfrom
seethinajayadileep:fix/instancecoercer-duplicate-field-writers
Mar 14, 2026
Merged

[java] Fix duplicate field name handling in InstanceCoercer#getFieldWriters#17187
asolntsev merged 4 commits into
SeleniumHQ:trunkfrom
seethinajayadileep:fix/instancecoercer-duplicate-field-writers

Conversation

@seethinajayadileep

@seethinajayadileep seethinajayadileep commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

💥 What does this PR do?

This PR fixes duplicate field name handling in InstanceCoercer#getFieldWriters.

Previously, field writers were collected using Collectors.toMap(...) without an explicit merge strategy. When duplicate field names were encountered (for example through field hiding in inheritance), the collector would fail with an implicit IllegalStateException caused by duplicate keys.

This change makes duplicate handling explicit by detecting duplicates during map collection and throwing a JsonException with a clear error message.

This prevents ambiguous field mappings and replaces the implicit collector failure with a controlled and descriptive exception.


🔧 Implementation Notes

The change modifies the Collectors.toMap(...) call in getFieldWriters.

Previous behavior

  • Collectors.toMap was used without a merge function.
  • Duplicate field names caused an implicit IllegalStateException from the collector.

New behavior

  • A merge function is provided that throws a JsonException when duplicate field names are encountered.
  • This makes the failure explicit and easier to diagnose.

Example scenario that previously caused an implicit collector failure:

class Parent {
  String value;
}

class Child extends Parent {
  String value;
} 

Both fields resolve to the same JSON key (value), producing a duplicate during field writer collection.

With this change, such cases now fail with a clear JsonException instead of a generic collector error.

💡 Additional Considerations

This change only affects cases where duplicate serialized field names exist.

Valid classes with unique field names continue to behave exactly as before.

A regression test was added to verify that duplicate field names detected during BY_FIELD deserialization result in a JsonException.

🔄 Types of changes

Bug fix (backwards compatible)

@qodo-code-review

Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Fix duplicate field name handling in InstanceCoercer#getFieldWriters

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Fixes duplicate field name handling in InstanceCoercer#getFieldWriters
• Adds merge function to Collectors.toMap() to retain first entry
• Uses LinkedHashMap to preserve field processing order
• Prevents runtime IllegalStateException on duplicate keys

Grey Divider

File Changes

1. java/src/org/openqa/selenium/json/InstanceCoercer.java 🐞 Bug fix +3/-1

Add merge function and LinkedHashMap to toMap collector

• Modified Collectors.toMap() call to include merge function (existing, ignored) -> existing
• Added LinkedHashMap::new as map supplier to preserve insertion order
• Prevents IllegalStateException: Duplicate key when multiple fields resolve to same serialized
 name
• Retains first discovered field writer and ignores subsequent duplicates

java/src/org/openqa/selenium/json/InstanceCoercer.java


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (1) 📎 Requirement gaps (0)

Grey Divider


Action required

1. getFieldWriters duplicates untested📘 Rule violation ⛯ Reliability
Description
The change alters runtime behavior for duplicate field names (now silently keeping the first writer)
without adding a unit test to prevent regressions. This makes it easy for future refactors to
reintroduce duplicate-key failures or change which field “wins” without detection.
Code

java/src/org/openqa/selenium/json/InstanceCoercer.java[R129-131]

+                },
+                (existing, ignored) -> existing,
+                java.util.LinkedHashMap::new));
Evidence
PR Compliance ID 4 requires adding/updating tests for behavior changes where feasible. The updated
collector explicitly changes behavior on duplicate keys, and the PR itself notes tests as follow-up
work rather than including them.

AGENTS.md
java/src/org/openqa/selenium/json/InstanceCoercer.java[129-131]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`InstanceCoercer#getFieldWriters` now retains the first writer when duplicate field names occur, but this behavior change is not covered by tests.
## Issue Context
Duplicate field names can happen via field hiding (same-named fields across a class hierarchy). Historically this could throw `Duplicate key` during collection; now duplicates are ignored. This should be locked in with a unit test to prevent regressions and to ensure deterministic "winner" behavior.
## Fix Focus Areas
- java/src/org/openqa/selenium/json/InstanceCoercer.java[99-132]
- java/test/org/openqa/selenium/json/JsonTest.java[113-145]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Silent duplicate suppression🐞 Bug ✓ Correctness
Description
getFieldWriters now silently ignores later fields that resolve to the same JSON key, which can
hide ambiguous class designs (field hiding) and lead to missing/incorrectly-applied data without any
signal. This trades a clear failure (duplicate key exception) for silent data loss and harder
debugging when duplicates exist.
Code

java/src/org/openqa/selenium/json/InstanceCoercer.java[R129-131]

+                },
+                (existing, ignored) -> existing,
+                java.util.LinkedHashMap::new));
Evidence
Fields are collected starting from the concrete class and then walking up the superclass chain, and
the collector now keeps the first entry and drops subsequent ones for the same key. During
deserialization only the retained writer is used for a given JSON key, so any dropped duplicate
field can never be set, with no warning/error emitted by this code path.

java/src/org/openqa/selenium/json/InstanceCoercer.java[99-105]
java/src/org/openqa/selenium/json/InstanceCoercer.java[107-132]
java/src/org/openqa/selenium/json/InstanceCoercer.java[77-88]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`InstanceCoercer#getFieldWriters` now resolves duplicate field-name collisions by silently keeping the first writer and ignoring the rest. This can cause silent data loss / surprising field selection when a subclass hides a superclass field, making deserialization bugs very hard to detect.
### Issue Context
The stream collects fields across the class hierarchy and then builds a map keyed by `Field::getName`. With the new merge function, duplicates are no longer surfaced to the caller.
### Fix Focus Areas
- java/src/org/openqa/selenium/json/InstanceCoercer.java[99-132]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@selenium-ci selenium-ci added the C-java Java Bindings label Mar 7, 2026
@seethinajayadileep seethinajayadileep changed the title Fix duplicate field name handling in InstanceCoercer#getFieldWriters [java] Fix duplicate field name handling in InstanceCoercer#getFieldWriters Mar 7, 2026
Comment thread java/src/org/openqa/selenium/json/InstanceCoercer.java Outdated
@seethinajayadileep

Copy link
Copy Markdown
Contributor Author

Hi maintainers, could someone please assign a reviewer for this PR? Thank you.

@asolntsev asolntsev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's slightly better than previously, so we can merge this PR. Thank you.

Before:

java.lang.IllegalStateException: Duplicate key value (attempted merging values org.openqa.selenium.json.InstanceCoercer$TypeAndWriter@4e70a728 and org.openqa.selenium.json.InstanceCoercer$TypeAndWriter@b7838a9)

After:

org.openqa.selenium.json.JsonException: Duplicate JSON field name detected while collecting field writers

P.S. But the name of the field is not still shown in the error message. Ideally, we should show the name as well. But I can it in a separate PR if you wish.

@asolntsev asolntsev added this to the 4.42.0 milestone Mar 13, 2026
@asolntsev asolntsev self-assigned this Mar 14, 2026
@asolntsev
asolntsev merged commit fbe3881 into SeleniumHQ:trunk Mar 14, 2026
42 of 44 checks passed
asolntsev added a commit to asolntsev/selenium that referenced this pull request Mar 14, 2026
This PR extracts few anonymous lambdas in InstanceCoercer.java to named classes which now have "toString" method. Thus, they look readable in exception messages.

continuation of SeleniumHQ#17187
asolntsev added a commit to asolntsev/selenium that referenced this pull request Mar 14, 2026
This PR extracts few anonymous lambdas in InstanceCoercer.java to named classes which now have "toString" method. Thus, they look readable in exception messages.

continuation of SeleniumHQ#17187
asolntsev added a commit that referenced this pull request Mar 14, 2026
#17225)

Add field names to JsonException "Duplicate JSON field name..."

This PR extracts few anonymous lambdas in InstanceCoercer.java to named classes which now have "toString" method. Thus, they look readable in exception messages.

continuation of #17187
krishnamohan-kothapalli pushed a commit to krishnamohan-kothapalli/selenium that referenced this pull request Mar 18, 2026
…riters (SeleniumHQ#17187)

* Fix duplicate field name handling in InstanceCoercer#getFieldWriters

* added unit testcase
krishnamohan-kothapalli pushed a commit to krishnamohan-kothapalli/selenium that referenced this pull request Mar 18, 2026
SeleniumHQ#17225)

Add field names to JsonException "Duplicate JSON field name..."

This PR extracts few anonymous lambdas in InstanceCoercer.java to named classes which now have "toString" method. Thus, they look readable in exception messages.

continuation of SeleniumHQ#17187
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-java Java Bindings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants