Skip to content

Commit

Permalink
Records should not use default constructor if available (#552)
Browse files Browse the repository at this point in the history
Records should not use default constructor if available

Signed-off-by: David Kral <david.k.kral@oracle.com>
  • Loading branch information
Verdent committed Apr 27, 2022
1 parent 5bc927b commit 58b2d1e
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 2 deletions.
Expand Up @@ -46,6 +46,10 @@ static JsonbCreator findCreator(Class<?> clazz,
return null;
}

public static boolean isRecord(Class<?> clazz) {
return false;
}

public static Optional<JsonbException> exceptionToThrow(Class<?> clazz) {
return Optional.empty();
}
Expand Down
Expand Up @@ -23,6 +23,7 @@

import jakarta.json.bind.config.PropertyNamingStrategy;

import org.eclipse.yasson.internal.ClassMultiReleaseExtension;
import org.eclipse.yasson.internal.ReflectionUtils;
import org.eclipse.yasson.internal.model.customization.ClassCustomization;
import org.eclipse.yasson.internal.model.customization.StrategiesProvider;
Expand Down Expand Up @@ -190,7 +191,12 @@ public Constructor<?> getDefaultConstructor() {
// Example: Deserialization into Map won't use this constructor, and therefore never needs to call this method.
// Note: Null is a valid result and needs to be cached.
if (!isInitialized.get()) {
defaultConstructor = ReflectionUtils.getDefaultConstructor(clazz, false);
if (ClassMultiReleaseExtension.isRecord(clazz)) {
//No default constructor should be used in case of records
defaultConstructor = null;
} else {
defaultConstructor = ReflectionUtils.getDefaultConstructor(clazz, false);
}
isInitialized.set(true);
}
return defaultConstructor;
Expand Down
Expand Up @@ -39,7 +39,7 @@ static boolean shouldTransformToPropertyName(Method method) {
}

static boolean isSpecialAccessorMethod(Method method, Map<String, Property> classProperties) {
return method.getDeclaringClass().isRecord()
return isRecord(method.getDeclaringClass())
&& method.getParameterCount() == 0
&& !void.class.equals(method.getReturnType())
&& classProperties.containsKey(method.getName());
Expand All @@ -56,6 +56,10 @@ static JsonbCreator findCreator(Class<?> clazz,
return null;
}

public static boolean isRecord(Class<?> clazz) {
return clazz.isRecord();
}

public static Optional<JsonbException> exceptionToThrow(Class<?> clazz) {
if (clazz.isRecord()) {
if (clazz.getDeclaredConstructors().length > 1) {
Expand Down
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/

package org.eclipse.yasson.records;

public record CarWithDefaultConstructor(String type, String color) {

public CarWithDefaultConstructor() {
this("some", "other");
}

}
10 changes: 10 additions & 0 deletions src/test/java16/org/eclipse/yasson/records/RecordTest.java
Expand Up @@ -96,4 +96,14 @@ public void testRecordJsonbCreator() {
assertThat(deserialized, is(car));
}

@Test
public void testRecordWithDefaultConstructor() {
CarWithDefaultConstructor car = new CarWithDefaultConstructor("skoda", "red");
String expected = "{\"color\":\"red\",\"type\":\"skoda\"}";

String json = Jsonbs.defaultJsonb.toJson(car);
assertThat(json, is(expected));
assertThrows(JsonbException.class, () -> Jsonbs.defaultJsonb.fromJson(expected, CarWithDefaultConstructor.class));
}

}

0 comments on commit 58b2d1e

Please sign in to comment.