From 671568f05a6fd3906f3614d793ef6e8b3f97ee11 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Tue, 2 Dec 2025 10:01:41 -0300 Subject: [PATCH 1/6] feat: implement getType in UnsupportedJsonValueImpl --- .../vaadin/jsonmigration/ElementalArrayNode.java | 6 ++++++ .../vaadin/jsonmigration/ElementalBooleanNode.java | 6 ++++++ .../vaadin/jsonmigration/ElementalNullNode.java | 6 ++++++ .../vaadin/jsonmigration/ElementalNumberNode.java | 7 +++++++ .../vaadin/jsonmigration/ElementalObjectNode.java | 6 ++++++ .../vaadin/jsonmigration/ElementalStringNode.java | 6 ++++++ .../vaadin/jsonmigration/UnsupportedJsonValueImpl.java | 6 ------ 7 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalArrayNode.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalArrayNode.java index 75a00a5..267c84f 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalArrayNode.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalArrayNode.java @@ -20,6 +20,7 @@ package com.flowingcode.vaadin.jsonmigration; import elemental.json.JsonArray; +import elemental.json.JsonType; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -49,5 +50,10 @@ private static List children(JsonArray a) { } } + @Override + public JsonType getType() { + return JsonType.ARRAY; + } + } diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalBooleanNode.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalBooleanNode.java index b628fdc..0eca205 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalBooleanNode.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalBooleanNode.java @@ -19,6 +19,7 @@ */ package com.flowingcode.vaadin.jsonmigration; +import elemental.json.JsonType; import tools.jackson.databind.node.BooleanNode; @SuppressWarnings("serial") @@ -28,6 +29,11 @@ public ElementalBooleanNode(boolean value) { super(value); } + @Override + public JsonType getType() { + return JsonType.BOOLEAN; + } + } diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalNullNode.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalNullNode.java index 7c70016..a166498 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalNullNode.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalNullNode.java @@ -19,6 +19,7 @@ */ package com.flowingcode.vaadin.jsonmigration; +import elemental.json.JsonType; import tools.jackson.databind.node.NullNode; @SuppressWarnings("serial") @@ -33,5 +34,10 @@ public String toJson() { return null; } + @Override + public JsonType getType() { + return JsonType.NULL; + } + } diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalNumberNode.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalNumberNode.java index 67680cf..5d96826 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalNumberNode.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalNumberNode.java @@ -19,6 +19,7 @@ */ package com.flowingcode.vaadin.jsonmigration; +import elemental.json.JsonType; import tools.jackson.databind.node.DoubleNode; @SuppressWarnings("serial") @@ -37,5 +38,11 @@ public String toJson() { return UnsupportedJsonValueImpl.super.toJson(); } } + + @Override + public JsonType getType() { + return JsonType.NUMBER; + } + } diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalObjectNode.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalObjectNode.java index ba6e7e4..9c48f8d 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalObjectNode.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalObjectNode.java @@ -21,6 +21,7 @@ import static com.flowingcode.vaadin.jsonmigration.JsonMigrationHelper25.convertToJsonNode; import elemental.json.JsonObject; +import elemental.json.JsonType; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; @@ -51,6 +52,11 @@ private static Map children(JsonObject o) { } } + @Override + public JsonType getType() { + return JsonType.OBJECT; + } + } diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalStringNode.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalStringNode.java index 82be137..7e80173 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalStringNode.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalStringNode.java @@ -19,6 +19,7 @@ */ package com.flowingcode.vaadin.jsonmigration; +import elemental.json.JsonType; import tools.jackson.databind.node.StringNode; @SuppressWarnings("serial") @@ -28,4 +29,9 @@ public ElementalStringNode(String value) { super(value); } + @Override + public JsonType getType() { + return JsonType.STRING; + } + } \ No newline at end of file diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/UnsupportedJsonValueImpl.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/UnsupportedJsonValueImpl.java index 591dfcb..15d477c 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/UnsupportedJsonValueImpl.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/UnsupportedJsonValueImpl.java @@ -19,7 +19,6 @@ */ package com.flowingcode.vaadin.jsonmigration; -import elemental.json.JsonType; import elemental.json.JsonValue; import tools.jackson.databind.JsonNode; @@ -40,11 +39,6 @@ default String asString() { throw new UnsupportedOperationException(); } - @Override - default JsonType getType() { - throw new UnsupportedOperationException(); - } - @Override default String toJson() { return ((JsonNode) this).toString(); From d02fc6d30ca16c70d91a0568d96dbb33bea2efd1 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Tue, 2 Dec 2025 10:02:33 -0300 Subject: [PATCH 2/6] fix: do not convert results that are already a JsonNode --- .../vaadin/jsonmigration/JsonMigrationHelper25.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/JsonMigrationHelper25.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/JsonMigrationHelper25.java index e4b0fb9..300bd7c 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/JsonMigrationHelper25.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/JsonMigrationHelper25.java @@ -66,8 +66,8 @@ public JsonValue convertToJsonValue(Object object) { @SuppressWarnings("unchecked") @Override public JsonValue convertToClientCallableResult(JsonValue object) { - if (object == null) { - return null; + if (object == null || object instanceof JsonNode) { + return object; } else { switch (object.getType()) { case OBJECT: From ddb08fe58cbddc62507bbb2ab522531df6565b4d Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Tue, 2 Dec 2025 12:24:46 -0300 Subject: [PATCH 3/6] refactor: make instrumented classes final --- .../vaadin/jsonmigration/ClassInstrumentationUtil.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java index 9de045f..fcaa6df 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java @@ -248,7 +248,8 @@ private byte[] generateBytecode(String className, Class parent) { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, internalClassName, null, internalParentName, null); + cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, + internalClassName, null, internalParentName, null); generateConstructor(cw, internalParentName); generateClientCallableOverrides(cw, parent, internalClassName, internalParentName); From 7c72fe240b74a8e6fb8c4f2dcf208323baede8eb Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Tue, 2 Dec 2025 12:25:39 -0300 Subject: [PATCH 4/6] fix: preserve private modifier in instrumented methods --- .../vaadin/jsonmigration/ClassInstrumentationUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java index fcaa6df..b79a602 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java @@ -367,7 +367,7 @@ private void generateMethodOverride(ClassWriter cw, Method method, String intern String overrideDescriptor = getMethodDescriptor(method, hasJsonValueParams); String superDescriptor = getMethodDescriptor(method, false); - int access = method.getModifiers() & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED); + int access = method.getModifiers() & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE); MethodVisitor mv = cw.visitMethod(access, method.getName(), overrideDescriptor, null, getExceptionInternalNames(method.getExceptionTypes())); From f51d5abfd0b41a8089989ffe2972de77bafc2ff8 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Tue, 2 Dec 2025 16:09:38 -0300 Subject: [PATCH 5/6] chore: log class instrumentation --- .../vaadin/jsonmigration/ClassInstrumentationUtil.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java index b79a602..7512ddd 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java @@ -42,6 +42,8 @@ import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Utility class for instrumenting classes at runtime. @@ -57,6 +59,8 @@ */ final class ClassInstrumentationUtil { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final int version; private final Map classLoaderCache = new WeakHashMap<>(); @@ -115,6 +119,7 @@ public Class instrumentClass(Class parent) } if (!needsInstrumentation(parent)) { + logger.info("{} no instrumentation needed", parent); return parent; } @@ -362,6 +367,8 @@ private void createLookupHelper(ClassWriter cw, Method method) { } private void generateMethodOverride(ClassWriter cw, Method method, String internalClassName, String internalParentName) { + logger.info("Override {}", method); + boolean hasJsonValueReturn = !hasLegacyVaadin() && JsonValue.class.isAssignableFrom(method.getReturnType()); boolean hasJsonValueParams = !hasLegacyVaadin() && hasJsonValueParameters(method); From 5ad735ae0faa435e27ed29fbdb437e02349f44ee Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Tue, 2 Dec 2025 16:15:11 -0300 Subject: [PATCH 6/6] fix: instrument classes in legacy versions of the framework --- .../vaadin/jsonmigration/InstrumentationViewInitializer.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/InstrumentationViewInitializer.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/InstrumentationViewInitializer.java index 1ade68a..281fd8f 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/InstrumentationViewInitializer.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/InstrumentationViewInitializer.java @@ -22,7 +22,6 @@ import com.vaadin.flow.component.Component; import com.vaadin.flow.router.RouteConfiguration; import com.vaadin.flow.server.VaadinServiceInitListener; -import com.vaadin.flow.server.Version; /** * Abstract base class for Vaadin service initializers that register instrumented views. Subclasses @@ -54,9 +53,7 @@ protected final void registerInstrumentedRoute(Class naviga } String route = annotation.value(); - if (Version.getMajorVersion() > 24) { - navigationTarget = JsonMigration.instrumentClass(navigationTarget); - } + navigationTarget = JsonMigration.instrumentClass(navigationTarget); RouteConfiguration.forApplicationScope().setRoute(route, navigationTarget); }