Skip to content

Commit 4e1b59c

Browse files
authored
chore!: Remove elemental-json from flow-server (#22655)
Remove all elemental-json usage from flow-server module (excluding flow-client which still uses it for GWT). This removes internal APIs and updates all code to use Jackson 3 exclusively. Changes: - Delete JsonUtils.java and JsonSerializer.java (internal APIs) - Remove elemental-json bridge methods from JacksonUtils.java - Remove gwt-elemental dependency from flow-server/pom.xml - Update EventData documentation to remove elemental.json.JsonValue - Update VaadinServletContextInitializer package exclusions - Update RouterLinkView test to use Jackson ObjectNode - Update DefaultApplicationConfigurationFactoryTest to use JacksonUtils BREAKING CHANGE: Internal APIs JsonUtils and JsonSerializer have been removed. Applications should use Jackson 3 types (JsonNode, ObjectNode, ArrayNode) and JacksonUtils methods instead. The EventData annotation no longer supports elemental.json.JsonValue - use JsonNode instead.
1 parent ccf2cef commit 4e1b59c

File tree

13 files changed

+115
-2309
lines changed

13 files changed

+115
-2309
lines changed

flow-client/src/test/java/com/vaadin/client/flow/ExecuteJavaScriptProcessorTest.java

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import com.vaadin.client.flow.collection.JsArray;
2828
import com.vaadin.client.flow.collection.JsMap;
2929
import com.vaadin.client.flow.reactive.Reactive;
30-
import com.vaadin.flow.internal.JsonUtils;
3130
import com.vaadin.flow.internal.nodefeature.NodeFeatures;
3231
import com.vaadin.flow.internal.nodefeature.NodeProperties;
3332

@@ -106,10 +105,12 @@ Registry getRegistry() {
106105
public void execute_parametersAndCodeAreValidAndNoNodeParameters() {
107106
CollectingExecuteJavaScriptProcessor processor = new CollectingExecuteJavaScriptProcessor();
108107

109-
JsonArray invocation1 = JsonUtils.createArray(Json.create("script1"));
108+
JsonArray invocation1 = TestJsonUtils
109+
.createArray(Json.create("script1"));
110110
JsonArray invocation2 = Stream.of("param1", "param2", "script2")
111-
.map(Json::create).collect(JsonUtils.asArray());
112-
JsonArray invocations = JsonUtils.createArray(invocation1, invocation2);
111+
.map(Json::create).collect(TestJsonUtils.asArray());
112+
JsonArray invocations = TestJsonUtils.createArray(invocation1,
113+
invocation2);
113114

114115
processor.execute(invocations);
115116

@@ -157,11 +158,11 @@ public void execute_nodeParametersAreCorrectlyPassed() {
157158
json.put("@v-node", node.getId());
158159

159160
JsonArray invocation = Stream.of(json, Json.create("$0"))
160-
.collect(JsonUtils.asArray());
161+
.collect(TestJsonUtils.asArray());
161162

162163
// JRE impl of the array uses
163164

164-
processor.execute(JsonUtils.createArray(invocation));
165+
processor.execute(TestJsonUtils.createArray(invocation));
165166

166167
Assert.assertEquals(1, processor.nodeParametersList.size());
167168

@@ -193,9 +194,9 @@ public void execute_nodeParameterIsVirtualChildAwaitingInit() {
193194
json.put("@v-node", node.getId());
194195

195196
JsonArray invocation = Stream.of(json, Json.create("$0"))
196-
.collect(JsonUtils.asArray());
197+
.collect(TestJsonUtils.asArray());
197198

198-
processor.execute(JsonUtils.createArray(invocation));
199+
processor.execute(TestJsonUtils.createArray(invocation));
199200

200201
// The invocation has not been executed
201202
Assert.assertEquals(0, processor.nodeParametersList.size());
@@ -234,9 +235,9 @@ public void execute_nodeParameterIsHidden() {
234235
json.put("@v-node", node.getId());
235236

236237
JsonArray invocation = Stream.of(json, Json.create("$0"))
237-
.collect(JsonUtils.asArray());
238+
.collect(TestJsonUtils.asArray());
238239

239-
processor.execute(JsonUtils.createArray(invocation));
240+
processor.execute(TestJsonUtils.createArray(invocation));
240241

241242
Assert.assertEquals(0, processor.nodeParametersList.size());
242243

@@ -274,9 +275,9 @@ public void execute_nodeParameterIsNotVirtualChild() {
274275
json.put("@v-node", node.getId());
275276

276277
JsonArray invocation = Stream.of(json, Json.create("$0"))
277-
.collect(JsonUtils.asArray());
278+
.collect(TestJsonUtils.asArray());
278279

279-
processor.execute(JsonUtils.createArray(invocation));
280+
processor.execute(TestJsonUtils.createArray(invocation));
280281

281282
// The invocation has been executed
282283
Assert.assertEquals(1, processor.nodeParametersList.size());
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright 2000-2025 Vaadin Ltd.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package com.vaadin.client.flow;
17+
18+
import java.util.EnumSet;
19+
import java.util.Set;
20+
import java.util.function.BiConsumer;
21+
import java.util.function.BinaryOperator;
22+
import java.util.function.Function;
23+
import java.util.function.Supplier;
24+
import java.util.stream.Collector;
25+
26+
import elemental.json.Json;
27+
import elemental.json.JsonArray;
28+
import elemental.json.JsonValue;
29+
30+
/**
31+
* Test utilities for JSON operations, replacing the removed JsonUtils from
32+
* flow-server.
33+
*/
34+
public class TestJsonUtils {
35+
36+
/**
37+
* Creates an array with the provided values.
38+
*
39+
* @param values
40+
* the values to add to the array
41+
* @return a new JSON array
42+
*/
43+
public static JsonArray createArray(JsonValue... values) {
44+
JsonArray array = Json.createArray();
45+
for (JsonValue value : values) {
46+
array.set(array.length(), value);
47+
}
48+
return array;
49+
}
50+
51+
/**
52+
* Collector for JSON values to a JSON array.
53+
*
54+
* @return a collector that collects JSON values into a JSON array
55+
*/
56+
public static Collector<JsonValue, JsonArray, JsonArray> asArray() {
57+
return new Collector<JsonValue, JsonArray, JsonArray>() {
58+
@Override
59+
public Supplier<JsonArray> supplier() {
60+
return Json::createArray;
61+
}
62+
63+
@Override
64+
public BiConsumer<JsonArray, JsonValue> accumulator() {
65+
return (array, value) -> array.set(array.length(), value);
66+
}
67+
68+
@Override
69+
public BinaryOperator<JsonArray> combiner() {
70+
return (left, right) -> {
71+
for (int i = 0; i < right.length(); i++) {
72+
JsonValue value = right.get(i);
73+
left.set(left.length(), value);
74+
}
75+
return left;
76+
};
77+
}
78+
79+
@Override
80+
public Function<JsonArray, JsonArray> finisher() {
81+
return Function.identity();
82+
}
83+
84+
@Override
85+
public Set<Characteristics> characteristics() {
86+
return EnumSet.of(Characteristics.IDENTITY_FINISH);
87+
}
88+
};
89+
}
90+
}

flow-client/src/test/java/com/vaadin/client/flow/TreeChangeProcessorTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import com.vaadin.client.flow.collection.JsSet;
2727
import com.vaadin.client.flow.nodefeature.MapProperty;
2828
import com.vaadin.client.flow.nodefeature.NodeList;
29-
import com.vaadin.flow.internal.JsonUtils;
3029
import com.vaadin.flow.internal.nodefeature.NodeFeatures;
3130
import com.vaadin.flow.shared.JsonConstants;
3231

@@ -328,7 +327,7 @@ public void testNodeDetachRemovesParent() {
328327
}
329328

330329
private static JsonArray toArray(JsonValue... changes) {
331-
return Arrays.stream(changes).collect(JsonUtils.asArray());
330+
return Arrays.stream(changes).collect(TestJsonUtils.asArray());
332331
}
333332

334333
private static JsonObject baseChange(int node, String type) {
@@ -415,7 +414,7 @@ private static JsonObject nodeSpliceChange(int node, int ns, int index,
415414

416415
if (children != null && children.length != 0) {
417416
JsonArray add = Arrays.stream(children).mapToObj(Json::create)
418-
.collect(JsonUtils.asArray());
417+
.collect(TestJsonUtils.asArray());
419418
json.put(JsonConstants.CHANGE_SPLICE_ADD_NODES, add);
420419
}
421420

flow-server/pom.xml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,6 @@
7373
<scope>provided</scope>
7474
</dependency>
7575

76-
<dependency>
77-
<groupId>com.vaadin.external.gwt</groupId>
78-
<artifactId>gwt-elemental</artifactId>
79-
<version>2.8.2.vaadin2</version>
80-
</dependency>
81-
8276
<dependency>
8377
<groupId>org.apache.commons</groupId>
8478
<artifactId>commons-fileupload2-jakarta-servlet6</artifactId>

flow-server/src/main/java/com/vaadin/flow/component/EventData.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@
4242
* <li>Primitives and their wrappers: {@link Integer}, {@link Double},
4343
* {@link Boolean}, int, double, boolean, etc.</li>
4444
* <li>String values: {@link String}</li>
45-
* <li>JSON types: {@link tools.jackson.databind.JsonNode},
46-
* {@link elemental.json.JsonValue}</li>
45+
* <li>JSON types: {@link tools.jackson.databind.JsonNode}</li>
4746
* <li>Bean/DTO types: Any Java bean or record that can be deserialized from
4847
* JSON using Jackson</li>
4948
* <li>Collections: {@link java.util.List}, {@link java.util.Map}, etc. (when

flow-server/src/main/java/com/vaadin/flow/internal/JacksonUtils.java

Lines changed: 0 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,6 @@
5555
import com.vaadin.flow.component.Component;
5656
import com.vaadin.flow.dom.Node;
5757

58-
import elemental.json.Json;
59-
import elemental.json.JsonArray;
60-
import elemental.json.JsonBoolean;
61-
import elemental.json.JsonNull;
62-
import elemental.json.JsonNumber;
63-
import elemental.json.JsonObject;
64-
import elemental.json.JsonValue;
65-
6658
/**
6759
* Helpers for using <code>jackson</code>.
6860
* <p>
@@ -120,109 +112,6 @@ public static ValueNode nullNode() {
120112
return (ValueNode) objectMapper.nullNode();
121113
}
122114

123-
/**
124-
* Map JsonArray to ArrayNode.
125-
*
126-
* @param jsonArray
127-
* JsonArray to change
128-
* @return ArrayNode of elemental json array object or null for null
129-
* jsonArray
130-
*/
131-
public static ArrayNode mapElemental(JsonArray jsonArray) {
132-
if (jsonArray == null || jsonArray instanceof JsonNull) {
133-
return null;
134-
}
135-
try {
136-
return (ArrayNode) objectMapper.readTree(jsonArray.toJson());
137-
} catch (JacksonException e) {
138-
throw new RuntimeException(e);
139-
}
140-
}
141-
142-
/**
143-
* Map JsonObject to ObjectNode.
144-
*
145-
* @param jsonObject
146-
* JsonObject to change
147-
* @return ObjectNode of elemental json object object or null for null
148-
* jsonObject
149-
*/
150-
public static ObjectNode mapElemental(JsonObject jsonObject) {
151-
if (jsonObject == null) {
152-
return null;
153-
}
154-
try {
155-
return (ObjectNode) objectMapper.readTree(jsonObject.toJson());
156-
} catch (JacksonException e) {
157-
throw new RuntimeException(e);
158-
}
159-
}
160-
161-
/**
162-
* Map JsonValue to ObjectNode.
163-
*
164-
* @param jsonValue
165-
* JsonValue to change
166-
* @return ObjectNode of elemental json value
167-
*/
168-
public static BaseJsonNode mapElemental(JsonValue jsonValue) {
169-
if (jsonValue == null || jsonValue instanceof JsonNull) {
170-
return nullNode();
171-
}
172-
if (jsonValue instanceof JsonObject) {
173-
return mapElemental((JsonObject) jsonValue);
174-
}
175-
if (jsonValue instanceof JsonArray) {
176-
return mapElemental((JsonArray) jsonValue);
177-
}
178-
if (jsonValue instanceof JsonNumber) {
179-
return objectMapper.valueToTree(jsonValue.asNumber());
180-
}
181-
if (jsonValue instanceof JsonBoolean) {
182-
return objectMapper.valueToTree(jsonValue.asBoolean());
183-
}
184-
return objectMapper.valueToTree(jsonValue.asString());
185-
}
186-
187-
/**
188-
* Convert the contents of an ArrayNode into a JsonArray. This is mostly
189-
* needed for arrays that may contain arrays and values.
190-
*
191-
* @param jsonNodes
192-
* ArrayNode to convert
193-
* @return JsonArray of ArrayNode content
194-
*/
195-
public static JsonArray createElementalArray(ArrayNode jsonNodes) {
196-
return (JsonArray) parseNode(jsonNodes);
197-
}
198-
199-
private static JsonValue parseNode(JsonNode node) {
200-
if (node instanceof ArrayNode) {
201-
JsonArray jsonArray = Json.createArray();
202-
node.forEach(arrayNode -> parseArrayNode(arrayNode, jsonArray));
203-
return jsonArray;
204-
}
205-
return Json.parse(node.toString());
206-
}
207-
208-
private static void parseArrayNode(JsonNode node, JsonArray jsonArray) {
209-
if (JsonNodeType.NUMBER.equals(node.getNodeType())) {
210-
jsonArray.set(jsonArray.length(), Json.create(node.doubleValue()));
211-
} else if (JsonNodeType.STRING.equals(node.getNodeType())) {
212-
jsonArray.set(jsonArray.length(), Json.create(node.textValue()));
213-
} else if (JsonNodeType.ARRAY.equals(node.getNodeType())) {
214-
JsonArray array = Json.createArray();
215-
node.forEach(arrayNode -> parseArrayNode(arrayNode, array));
216-
jsonArray.set(jsonArray.length(), array);
217-
} else if (JsonNodeType.BOOLEAN.equals(node.getNodeType())) {
218-
jsonArray.set(jsonArray.length(), Json.create(node.booleanValue()));
219-
} else if (JsonNodeType.NULL.equals(node.getNodeType())) {
220-
jsonArray.set(jsonArray.length(), Json.createNull());
221-
} else {
222-
jsonArray.set(jsonArray.length(), Json.parse(node.toString()));
223-
}
224-
}
225-
226115
/**
227116
* Read Json string to JsonNode.
228117
*

0 commit comments

Comments
 (0)