diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/JsonGenerator.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/JsonGenerator.java index b602c2595f5d..882f618c0692 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/JsonGenerator.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/JsonGenerator.java @@ -288,6 +288,7 @@ public void serialize(Object json) throws IOException { switch (TypeUtils.getImpliedType(TypeChecker.getType(json)).getTag()) { case TypeTags.ARRAY_TAG: + case TypeTags.TUPLE_TAG: if (json instanceof StreamingJsonValue) { ((StreamingJsonValue) json).serialize(this); break; @@ -316,6 +317,7 @@ public void serialize(Object json) throws IOException { break; case TypeTags.MAP_TAG: case TypeTags.JSON_TAG: + case TypeTags.RECORD_TYPE_TAG: this.startObject(); for (Entry entry : ((MapValueImpl) json).entrySet()) { this.writeFieldName(entry.getKey().getValue()); diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/runtime/api/tests/JsonValues.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/runtime/api/tests/JsonValues.java index 0d602ce171a5..255b414a177e 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/runtime/api/tests/JsonValues.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/runtime/api/tests/JsonValues.java @@ -26,9 +26,12 @@ import io.ballerina.runtime.api.values.BMap; import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BTypedesc; +import io.ballerina.runtime.internal.JsonGenerator; import io.ballerina.runtime.internal.values.ErrorValue; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.nio.charset.StandardCharsets; @@ -99,4 +102,16 @@ public static Object testParsingNullString(BString str) { public static Object testBStringParsingWithProcessingMode(BString str) { return JsonUtils.parse(str, JsonUtils.NonStringValueProcessingMode.FROM_JSON_STRING); } + + public static Object testJsonSerializeExtern(Object jsonObject) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try (JsonGenerator gen = new JsonGenerator(out)) { + gen.serialize(jsonObject); + gen.flush(); + out.close(); + } catch (IOException e) { + throw new ErrorValue(StringUtils.fromString(e.getMessage()), e); + } + return StringUtils.fromString(out.toString()); + } } diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/json/main.bal b/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/json/main.bal index 74b642a7b656..f07f63c49312 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/json/main.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/json/main.bal @@ -44,8 +44,33 @@ public function main() { result = testStringParsingWithProcessingMode(jsonStr); test:assertTrue(result is json, "Invalid json"); + + testJsonSerialize(); +} + +const string[] CONST_ROLES = ["Admin"]; + +type Profile record {| + string name; + int age; +|}; + +function testJsonSerialize() { + Profile profile = {name: "John", age: 30}; + json j = { + roles: CONST_ROLES, + ID: "User1", + profile: profile + }; + string expected = "{\"roles\":[\"Admin\"], \"ID\":\"User1\", \"profile\":{\"name\":\"John\", \"age\":30}}"; + string result = checkpanic testJsonSerializeExtern(j); + test:assertEquals(result, expected, "Invalid json serialization"); } +public isolated function testJsonSerializeExtern(json j) returns string|error = @java:Method { + 'class: "org.ballerinalang.nativeimpl.jvm.runtime.api.tests.JsonValues" +} external; + public isolated function testParsingWrongCharset(string str) returns json|error = @java:Method { 'class: "org.ballerinalang.nativeimpl.jvm.runtime.api.tests.JsonValues" } external;