Skip to content

Introduce predicate-based dynamic serializer selection - #3027

Open
thkluge wants to merge 12 commits into
jMonkeyEngine:masterfrom
thkluge:networking_records
Open

thkluge wants to merge 12 commits into
jMonkeyEngine:masterfrom
thkluge:networking_records

Conversation

@thkluge

@thkluge thkluge commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

This pull request introduces a flexible mechanism for dynamically selecting custom serializers in the Serializer system based on user-defined predicates. This enables feature-specific serializers (such as for Java Records) to be registered and automatically applied to matching classes without modifying the engine core. It also includes comprehensive tests to verify the new predicate-based serializer registration and routing logic. Additionally, there are minor bug fixes and improvements in message reliability handling.

Serializer predicate-based extension:

  • Introduced a registerSerializerPredicate(Predicate<Class<?>>, Serializer) method in Serializer to allow registering custom serializers that are selected for classes matching a given predicate. This enables dynamic, feature-specific serializer selection without hardcoding logic into the engine

  • Added a new test class PredicateSerializerTest that verifies:

    • Predicate-based serializers override the default for matching classes.
    • Non-matching classes fall back to the default FieldSerializer.
    • Predicate-based serializers are correctly used during auto-registration fallback.

Copilot AI balanced review requested due to automatic review settings October 26, 2026 20:46

@jaime-jmebot jaime-jmebot 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.

  • Clean addition of native Java record serialization support with a dedicated RecordSerializer and robust test coverage.
  • Proper handling of immutable message patterns via setReliable reassignments in networking adapters.

Copilot AI 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.

🟡 Changes recommended

Unchecked warnings block compilation, and unresolved serialization and registration defects prevent valid record values from round-tripping.

6 open issues
What changed in this PR

Adds Java record support to the networking serialization framework, alongside existing field-based serialization.

Changes:

  • Adds cached reflective record serialization and automatic serializer selection.
  • Preserves replacement messages returned by immutable setReliable() implementations.
  • Adds record round-trip, registry, immutability, performance, and legacy serialization tests.
File Description
jme3-networking/​src/​test/​java/​com/​jme3/​network/​serializing/​RecordSerializerTest.java Adds record serialization and legacy regression tests.
jme3-networking/​src/​main/​java/​com/​jme3/​network/​serializing/​serializers/​RecordSerializer.java Serializes record components and reconstructs records through their canonical constructor.
jme3-networking/​src/​main/​java/​com/​jme3/​network/​serializing/​Serializer.java Detects records and updates serializer selection.
jme3-networking/​src/​main/​java/​com/​jme3/​network/​serializing/​Serializable.java Changes the annotation default to enable automatic serializer selection.
jme3-networking/​src/​main/​java/​com/​jme3/​network/​base/​KernelAdapter.java Dispatches the message returned by setReliable().
jme3-networking/​src/​main/​java/​com/​jme3/​network/​base/​ConnectorAdapter.java Preserves immutable reliability updates before dispatch.

Review effort: Balanced

Copilot AI 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.

fixed nestedrecord test

Copilot AI 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.

🔵 Needs a closer look

The invalid Javadoc parameter tag causes the configured documentation validation task to fail.

1 open issue
1 previously missed issue

In code that hasn't changed since last review

Low severity Fix Javadoc parameter name mismatch

jme3-networking/​src/​main/​java/​com/​jme3/​network/​serializing/​serializers/​RecordSerializer.java:105

The method parameter is named cls, so @param clazz is invalid. The Javadoc validation command in .github/workflows/main.yml enables -Xdoclint:all,-missing and -Werror through common.gradle, so this causes that task to fail. Rename the tag to match the parameter.

1 resolved since last review

Review effort: Balanced

@riccardobl

Copy link
Copy Markdown
Member

Thanks for your PR!

Record serialization support is definitely useful, but I don't think we should merge this implementation into the core just yet, mainly because:

  • Changing the default serializer in the @Serializable annotation is a breaking change.
  • This PR introduces quite a bit of reflection and complexity for a language feature that isn't supported by our current target Java version (Java 8, soon moving to Java 11).

I'd suggest reducing the scope of this PR to the minimum, backward-compatible changes needed to allow record serialization, while keeping the actual RecordSerializer implementation outside the PR for now. Developers who need it, can register it from their application.

Specifically, I'd keep two changes:

  1. Keep the m = m.setReliable(reliable); changes in the networking adapters

  2. Introduce predicate-based serializer selection: Add a generic mechanism to register a Predicate<Class<?>> alongside a Serializer, allowing custom serializers to be selected automatically based on the target class.

For example, applications running on Java 16+ could register their own RecordSerializer using Class::isRecord as the predicate, instead of having record-specific reflective detection hardcoded into the core.

This would also be useful beyond records, as other serializers could use the same mechanism to support different kinds of classes.

@riccardobl
riccardobl marked this pull request as draft October 26, 2026 23:10
removed records serializer as this can be implemented now vie predict
@thkluge
thkluge requested review from jaime-jmebot and a balanced review from Copilot October 27, 2026 07:35

Copilot AI 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.

🟡 Changes recommended

Registry resets retain stale predicate serializers, and the delivered functionality does not match the advertised native record support.

2 open issues
1 resolved since last review

Review effort: Balanced

Comment on lines +296 to +297
// if the default FieldSerializer is requested, check predicates first
if (serializerClass == FieldSerializer.class) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

changed title and description of the PR

@thkluge thkluge changed the title Add support for records serialization Introduce predicate-based dynamic serializer selection Oct 27, 2026

@jaime-jmebot jaime-jmebot 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.

Thanks for updating the PR to focus on the lightweight predicate-based serializer selection mechanism and networking adapter updates!

  • The predicate-based registration approach is clean and flexible for application-level custom serializers.
  • One fix is needed in Serializer.java: @Serializable defaults to FieldSerializer.class, which causes annotated classes to bypass predicate selection. Restricting the annotation check to explicit non-default serializers allows registered predicates to evaluate correctly.

@riccardobl
riccardobl marked this pull request as ready for review October 27, 2026 08:39
@thkluge
thkluge requested a review from jaime-jmebot October 27, 2026 10:05

@jaime-jmebot jaime-jmebot 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.

Thanks for rescoping this — the predicate-based selection is now a small, backward-compatible addition, and the record-specific machinery is out of the PR as suggested.

  • The registerSerializerPredicate(Predicate<Class<?>>, Serializer) API is a clean, generic extension point that applications (including Java 16+ record support) can build on without core changes.
  • My earlier concern is addressed: classes with the default @Serializable serializer no longer short-circuit the predicate checks, and explicit custom serializers still win.
  • The m = m.setReliable(reliable) fixes in both adapters are correct for immutable message implementations.
  • Tests cover predicate override, non-matching fallback, and the auto-registration path nicely.

One thing worth adding to the registerSerializerPredicate Javadoc: matches are evaluated in registration order with first-match-wins, and predicates only affect classes registered afterwards — that ordering behavior is easy to trip over.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants