Skip to content

Conversation

@javier-godoy
Copy link
Member

@javier-godoy javier-godoy commented Dec 17, 2025

Close #23

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of JsonValue/JsonObject array parameters so client-callable methods convert and serialize array arguments correctly.
  • Tests

    • Added unit tests (modern and legacy paths) exercising array-of-JSON parameter scenarios to validate instrumentation and conversion behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 17, 2025

Walkthrough

Adds support for instrumenting JsonValue array parameters by mapping JsonValue[] descriptors to the converted component-type array and treating array parameters as JsonValue-containing; includes tests for ClientCallable and LegacyClientCallable variants and Jackson/ObjectNode test flavors.

Changes

Cohort / File(s) Summary
Core instrumentation
src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationJacksonHelper.java, src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java
Add branch to produce array descriptors for JsonValue[] by deriving component converted descriptor; detect JsonValue[] in parameter checks and use converted descriptors for parameters when convertJsonValueParams is enabled.
Test base classes
src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest*.java, src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest*.java
Add abstract createArrayOfJsonObject() hook and new tests test_ArrayOfJsonObject__V and test_JsonObjectVarargs__V / test_JsonObjectArgs__V to exercise array parameter instrumentation.
ClientCallable tests
src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_ArrayOfJsonObject__V.java, src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java
New test classes with @ClientCallable methods accepting JsonObject[] and asserting non-null/non-empty argument then calling trace().
LegacyClientCallable tests
src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonObject__V.java, src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java
New test classes with @LegacyClientCallable methods accepting JsonObject[] and asserting non-null/non-empty argument then calling trace().
Jackson/24 test variants
src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest24.java, src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest24.java
Change createJsonObject() return type to JsonObject; add createArrayOfJsonObject() returning JsonObject[] with two instances.
Jackson+ObjectNode/25 test variants
src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest25.java, src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest25.java
Change createJsonObject() return type to ObjectNode; add createArrayOfJsonObject() returning ObjectNode[] with two constructed instances.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Inspect array-descriptor generation in ClassInstrumentationJacksonHelper for correctness with primitive and reference component types.
  • Verify ClassInstrumentationUtil parameter-descriptor logic change doesn't break other conversion paths.
  • Run/validate newly added tests across both Jackson/ObjectNode variants and both ClientCallable/Legacy paths.

Possibly related PRs

Suggested reviewers

  • mlopezFC
  • paodb

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: instrument JsonValue[] arguments' clearly and concisely describes the main change, which is handling instrumentation of JsonValue[] array parameters.
Linked Issues check ✅ Passed The PR addresses issue #23 by adding instrumentation support for JsonValue[] arguments through modifications to type descriptor handling and method instrumentation logic, matching the expected behavior stated in the issue.
Out of Scope Changes check ✅ Passed All code changes are directly related to supporting JsonValue[] argument instrumentation as required by issue #23, with no unrelated modifications detected.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 20251217-02

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java (1)

452-473: Array parameters are not converted back from Jackson types, causing runtime ClassCastException.

When hasJsonValueParams is true and a parameter is JsonValue[] (e.g., JsonObject[]), the override method signature correctly converts the parameter type to the corresponding Jackson array type (e.g., ObjectNode[]). However, the parameter conversion loop at line 452 only checks JsonValue.class.isAssignableFrom(paramType), which returns false for array types. This causes array parameters to skip conversion and fall through to loadParameter(), passing the Jackson array directly to the super method that expects the original JsonValue array type.

The proposed fix in the review comment to add JsonValue[].class.isAssignableFrom(paramType) to the condition is incomplete. Calling JsonMigration.convertToJsonValue(Object) on an entire array won't work because that method expects single objects. Instead, array parameters require element-by-element conversion, similar to the convertArray() method in JsonMigrationHelper25 (lines 125-155), which iterates through array elements and converts each one individually.

Update the parameter conversion logic to detect array types and implement proper element-by-element conversion, or reuse the existing convertArray() pattern via bytecode generation.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9fe8df0 and 9c6b7d8.

📒 Files selected for processing (12)
  • src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationJacksonHelper.java (1 hunks)
  • src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java (2 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_ArrayOfJsonObject__V.java (1 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java (1 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest.java (2 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest24.java (3 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest25.java (2 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonObject__V.java (1 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java (1 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest.java (2 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest24.java (2 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest25.java (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-25T16:35:42.544Z
Learnt from: javier-godoy
Repo: FlowingCode/JsonMigrationHelper PR: 11
File: src/main/java/com/flowingcode/vaadin/jsonmigration/JsonSerializer.java:281-301
Timestamp: 2025-11-25T16:35:42.544Z
Learning: In the JsonMigrationHelper project, code copied from the Vaadin codebase should be kept consistent with the original source unless there's a specific reason to deviate.

Applied to files:

  • src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java
  • src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java
  • src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java
  • src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest25.java
  • src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationJacksonHelper.java
🔇 Additional comments (17)
src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationJacksonHelper.java (1)

51-52: LGTM! Array handling looks correct.

The logic correctly maps JsonValue[] (and its subtypes like JsonObject[]) to the corresponding Jackson array descriptors by recursively converting the component type. This handles the use case from issue #23.

Note: Multi-dimensional arrays (e.g., JsonValue[][]) are not handled and will fall through to the default descriptor. This seems acceptable given the scope of issue #23.

src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java (2)

240-241: LGTM! Extended parameter detection for arrays.

The addition of JsonValue[].class.isAssignableFrom(paramType) correctly extends the detection logic to handle array parameters, addressing issue #23.


586-586: Necessary change to support array parameter conversion.

Changing from checking individual JsonValue parameters to always calling getConvertedTypeDescriptor when convertJsonValueParams is true is the correct approach. This is because:

  1. The old code only checked JsonValue.class.isAssignableFrom(paramType), which returns false for JsonValue[] arrays
  2. getConvertedTypeDescriptor handles both scalar and array cases internally, falling back to Type.getDescriptor for non-JsonValue types
  3. This change enables proper descriptor generation for array parameters while maintaining backward compatibility
src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest24.java (1)

59-66: LGTM! Test infrastructure improvements.

The return type change for createJsonObject() improves type safety, and the new createArrayOfJsonObject() method provides test data for the array parameter test cases.

src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest25.java (2)

45-45: LGTM! Extended validation for array parameters.

Correctly adds JsonValue[].class.isAssignableFrom(arg) to detect array parameters that should trigger the error message about using @LegacyClientCallable.


80-87: LGTM! Test infrastructure improvements.

The return type refinement and new createArrayOfJsonObject() method align with the test patterns in this PR.

src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest25.java (2)

65-67: LGTM! Return type refinement improves type safety.

The change from Object to ObjectNode provides better type safety while remaining compatible with the abstract method signature from the parent class.


69-72: LGTM! Array factory method correctly implemented.

The method properly implements the abstract factory pattern, creating a two-element ObjectNode[] array suitable for testing array parameter instrumentation.

src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest.java (3)

80-80: LGTM! Abstract factory method follows established pattern.

The method signature is consistent with other abstract factory methods in the test class, allowing subclasses to provide appropriate test data for array parameters.


288-296: LGTM! Array parameter test follows established patterns.

The test properly validates that JsonObject[] array parameters are correctly instrumented and traced. The implementation is consistent with existing test methods.


299-307: LGTM! Varargs test complements array parameter coverage.

The test validates that varargs JsonObject... parameters work correctly with instrumentation. Using createArrayOfJsonObject() is appropriate since arrays can be passed to varargs parameters.

src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest24.java (3)

41-41: LGTM! Validates that JsonValue[] is rejected for legacy callables.

The check correctly ensures that JsonValue[] parameters are not allowed in legacy client callables, as these require the new instrumentation logic introduced for Vaadin 25.


78-80: LGTM! Return type refinement enhances code clarity.

The change from Object to JsonObject makes the method's contract more explicit while maintaining compatibility with the abstract method signature.


82-85: LGTM! Array factory implementation is correct.

The method properly creates a JsonObject[] array for testing, consistent with the implementation pattern used in other test classes.

src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest.java (3)

80-80: LGTM! Abstract method maintains test hierarchy consistency.

The method signature mirrors the pattern established in ClientCallablesTest.java, ensuring consistent test structure across the legacy and modern test suites.


318-326: LGTM! Legacy array parameter test properly structured.

The test validates that JsonObject[] arrays work correctly with legacy client callable instrumentation, following the established test pattern.


328-336: LGTM! Varargs test completes legacy parameter coverage.

The test ensures that varargs JsonObject... parameters are correctly handled in legacy client callable instrumentation, providing comprehensive test coverage alongside the array parameter test.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_ArrayOfJsonObject__V.java (1)

30-35: Test should access array elements to verify instrumentation.

While the assertions for null and non-empty are improvements, the test still doesn't access the array elements themselves. Since this PR fixes JsonValue[] instrumentation (issue #23), the test must verify that individual elements are properly converted and usable.

Apply this diff to access and verify array elements:

 @ClientCallable
 public void test(JsonObject[] arg) {
   Assert.assertNotNull(arg);
   Assert.assertThat(arg, not(emptyArray()));
+  // Verify array elements are properly instrumented and accessible
+  JsonObject first = arg[0];
+  Assert.assertNotNull("First element should not be null", first);
   trace();
 }

Alternatively, if the test framework supports passing data to trace(), consider:

 @ClientCallable
 public void test(JsonObject[] arg) {
   Assert.assertNotNull(arg);
   Assert.assertThat(arg, not(emptyArray()));
-  trace();
+  trace(arg[0] != null);
 }
🧹 Nitpick comments (3)
src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java (1)

30-35: Test improvement: consider accessing individual array elements.

The test now validates that the array is not null and not empty, which is an improvement over the previous version. However, to fully exercise the runtime conversion logic for JsonObject[] parameters, consider accessing individual array elements to ensure proper type conversion.

For example:

 @ClientCallable
 public void test(JsonObject[] arg) {
   Assert.assertNotNull(arg);
   Assert.assertThat(arg, not(emptyArray()));
+  // Access elements to exercise conversion
+  for (JsonObject obj : arg) {
+    Assert.assertNotNull(obj);
+  }
   trace();
 }
src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonObject__V.java (1)

29-34: Test improvement: consider accessing individual array elements.

Similar to the ClientCallable variant, this test validates the array structure but doesn't access individual JsonObject elements. Consider iterating through the array to fully exercise the conversion logic.

Example enhancement:

 @LegacyClientCallable
 public void test(JsonObject[] arg) {
   Assert.assertNotNull(arg);
   Assert.assertThat(arg, not(emptyArray()));
+  // Verify elements are properly converted
+  for (JsonObject obj : arg) {
+    Assert.assertNotNull(obj);
+  }
   trace();
 }
src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest25.java (1)

45-45: Consider a more explicit array type check for clarity.

The current check JsonValue[].class.isAssignableFrom(arg) is correct and leverages Java's array covariance, but a more explicit alternative might improve readability:

-      if (JsonValue.class.isAssignableFrom(arg) || JsonValue[].class.isAssignableFrom(arg)) {
+      if (JsonValue.class.isAssignableFrom(arg) || 
+          (arg.isArray() && JsonValue.class.isAssignableFrom(arg.getComponentType()))) {

This makes it clearer that you're checking for array types and inspecting the component type, though the current implementation is functionally equivalent.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9c6b7d8 and 4d86e85.

📒 Files selected for processing (12)
  • src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationJacksonHelper.java (1 hunks)
  • src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java (2 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_ArrayOfJsonObject__V.java (1 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java (1 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest.java (2 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest24.java (3 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest25.java (2 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonObject__V.java (1 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java (1 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest.java (2 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest24.java (2 hunks)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest25.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java
  • src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest24.java
  • src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationJacksonHelper.java
  • src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest.java
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-25T16:35:42.544Z
Learnt from: javier-godoy
Repo: FlowingCode/JsonMigrationHelper PR: 11
File: src/main/java/com/flowingcode/vaadin/jsonmigration/JsonSerializer.java:281-301
Timestamp: 2025-11-25T16:35:42.544Z
Learning: In the JsonMigrationHelper project, code copied from the Vaadin codebase should be kept consistent with the original source unless there's a specific reason to deviate.

Applied to files:

  • src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest24.java
  • src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest25.java
  • src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java
  • src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonObject__V.java
🔇 Additional comments (9)
src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java (2)

240-241: LGTM! Array parameter detection added.

The extension to check for JsonValue[] arrays correctly implements the PR objective to instrument JsonValue array arguments.


586-587: No issue found with parameter descriptor handling.

The implementation correctly handles all parameter types. The getConvertedTypeDescriptor method returns converted Jackson type descriptors for JsonValue parameters but returns the original type descriptor for all other parameters (line 54 in ClassInstrumentationJacksonHelper). This matches the actual bytecode conversion logic which only converts JsonValue-assignable parameters, ensuring descriptor and conversion behavior are consistent.

src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest25.java (1)

65-72: LGTM! Test data providers updated.

The changes align with the test suite pattern, providing both single ObjectNode instances and arrays for comprehensive testing of JsonValue array instrumentation.

src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest24.java (2)

41-41: LGTM! Array type validation added.

Consistent with the other test variants, this properly validates that array parameters require @LegacyClientCallable annotation.


78-85: LGTM! Test data providers for Vaadin 24.

The return type refinement and new array method provide appropriate test data using the Vaadin 24 API (Json.createObject()).

src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest.java (2)

80-80: LGTM! Abstract method added for array test data.

The new abstract method properly extends the test framework to support JsonObject[] parameter testing across different Vaadin versions.


318-336: LGTM! Comprehensive array parameter tests added.

Both test methods follow the established pattern and provide coverage for:

  1. Explicit array parameters (JsonObject[])
  2. Varargs parameters (also JsonObject[] at runtime)

The tests properly verify that instrumented methods with array parameters are correctly annotated and traced.

src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest25.java (2)

80-82: LGTM! More specific return type improves clarity.

Changing the return type from Object to ObjectNode makes the method signature more precise and improves type safety without affecting functionality.


84-87: LGTM! Correctly implements array creation for JsonValue[] testing.

The new method properly creates an array of ObjectNode instances to support testing JsonValue[] argument instrumentation, directly addressing the PR objective from issue #23.

@paodb paodb merged commit bcb7201 into master Dec 17, 2025
3 checks passed
@paodb paodb deleted the 20251217-02 branch December 17, 2025 18:11
@github-project-automation github-project-automation bot moved this from To Do to Pending release in Flowing Code Addons Dec 17, 2025
@javier-godoy javier-godoy moved this from Pending release to Done in Flowing Code Addons Dec 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

Vaadin 25: JsonValue[] argument is not instrumented

3 participants