diff --git a/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java b/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java index 276c379a564..83e9cd0e7af 100644 --- a/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java +++ b/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -469,8 +469,14 @@ public class ThreadDumper { writer.print("\"" + name + "\": "); } switch (obj) { - // Long may be larger than safe range of JSON integer value - case Long _ -> writer.print("\"" + obj + "\""); + case Long value -> { + // write as string for interop when outside +/- 2^53−1 + if (value < -0x1FFFFFFFFFFFFFL || value > 0x1FFFFFFFFFFFFFL) { + writer.print("\"" + value + "\""); + } else { + writer.print(value); + } + } case Number _ -> writer.print(obj); case Boolean _ -> writer.print(obj); case null -> writer.print("null"); diff --git a/src/jdk.management/share/classes/com/sun/management/doc-files/threadDump.schema.json b/src/jdk.management/share/classes/com/sun/management/doc-files/threadDump.schema.json index 1da3e3941ef..522f0ac5a8f 100644 --- a/src/jdk.management/share/classes/com/sun/management/doc-files/threadDump.schema.json +++ b/src/jdk.management/share/classes/com/sun/management/doc-files/threadDump.schema.json @@ -5,7 +5,7 @@ "type": "object", "properties": { "processId": { - "type": "string", + "type": [ "integer", "string" ], "description": "The native process id of the Java virtual machine." }, "time": { @@ -28,17 +28,11 @@ "description": "The container name. The container name is unique." }, "parent": { - "type": [ - "string", - "null" - ], + "type": [ "string", "null" ], "description": "The parent container name or null for the root container." }, "owner": { - "type": [ - "string", - "null" - ], + "type": [ "integer", "string", "null" ], "description": "The thread identifier of the owner thread if owned." }, "threads": { @@ -49,7 +43,7 @@ "type": "object", "properties": { "tid": { - "type": "string", + "type": [ "integer", "string" ], "description": "The thread identifier." }, "time": { @@ -69,9 +63,7 @@ "description": "true for a virtual thread." }, "parkBlocker": { - "type": [ - "object" - ], + "type": "object", "properties": { "object": { "type": "string", @@ -79,7 +71,7 @@ } }, "owner": { - "type": "string", + "type": [ "integer", "string" ], "description": "The thread identifier of the owner when the parkBlocker is an AbstractOwnableSynchronizer." }, "required": [ @@ -132,7 +124,7 @@ } }, "carrier": { - "type": "string", + "type": [ "integer", "string" ], "description": "The thread identifier of the carrier thread if mounted." } }, @@ -147,7 +139,7 @@ ] }, "threadCount": { - "type": "string", + "type": "integer", "description": "The number of threads in the thread container." } }, diff --git a/test/jdk/com/sun/crypto/provider/Cipher/HPKE/KAT9180.java b/test/jdk/com/sun/crypto/provider/Cipher/HPKE/KAT9180.java index 024d5f977a7..9b6fad6a90d 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/HPKE/KAT9180.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/HPKE/KAT9180.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,12 +82,12 @@ public class KAT9180 { var c1 = Cipher.getInstance("HPKE"); var c2 = Cipher.getInstance("HPKE"); var ts = JSONValue.parse(new String(Files.readAllBytes(archivePath), StandardCharsets.UTF_8)); - for (var tg : ts.asArray()) { - var mode = Integer.parseInt(tg.get("mode").asString()); + for (var tg : ts.elements()) { + var mode = tg.get("mode").asInt(); System.err.print('I'); - var kem_id = Integer.parseInt(tg.get("kem_id").asString()); - var kdf_id = Integer.parseInt(tg.get("kdf_id").asString()); - var aead_id = Integer.parseInt(tg.get("aead_id").asString()); + var kem_id = tg.get("kem_id").asInt(); + var kdf_id = tg.get("kdf_id").asInt(); + var aead_id = tg.get("aead_id").asInt(); var ikmR = h.parseHex(tg.get("ikmR").asString()); var ikmE = h.parseHex(tg.get("ikmE").asString()); var info = h.parseHex(tg.get("info").asString()); @@ -117,7 +117,7 @@ public class KAT9180 { if (enc != null) { System.err.print('e'); var count = 0; - for (var p : enc.asArray()) { + for (var p : enc.elements()) { var aad = h.parseHex(p.get("aad").asString()); var pt = h.parseHex(p.get("pt").asString()); var ct = h.parseHex(p.get("ct").asString()); diff --git a/test/jdk/jdk/jfr/tool/TestPrintJSON.java b/test/jdk/jdk/jfr/tool/TestPrintJSON.java index 3d79c75300f..2abbff68338 100644 --- a/test/jdk/jdk/jfr/tool/TestPrintJSON.java +++ b/test/jdk/jdk/jfr/tool/TestPrintJSON.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import java.time.OffsetDateTime; import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Map; import jdk.jfr.Timespan; import jdk.jfr.Timestamp; @@ -62,7 +63,7 @@ public class TestPrintJSON { JSONValue o = JSONValue.parse(json); JSONValue recording = o.get("recording"); - JSONArray jsonEvents = recording.get("events").asArray(); + List jsonEvents = recording.get("events").elements(); List events = RecordingFile.readAllEvents(recordingFile); Collections.sort(events, new EndTicksComparator()); // Verify events are equal @@ -79,7 +80,7 @@ public class TestPrintJSON { private static void assertEquals(Object jsonObject, Object jfrObject) throws Exception { // Check object if (jfrObject instanceof RecordedObject) { - JSONValue values = ((JSONValue) jsonObject).get("values"); + Map values = ((JSONValue) jsonObject).get("values").members(); RecordedObject recObject = (RecordedObject) jfrObject; Asserts.assertEquals(values.size(), recObject.getFields().size()); for (ValueDescriptor v : recObject.getFields()) { @@ -102,7 +103,7 @@ public class TestPrintJSON { // Check array if (jfrObject != null && jfrObject.getClass().isArray()) { Object[] jfrArray = (Object[]) jfrObject; - JSONArray jsArray = ((JSONArray) jsonObject); + List jsArray = ((JSONValue) jsonObject).elements(); for (int i = 0; i < jfrArray.length; i++) { assertEquals(jsArray.get(i), jfrArray[i]); } diff --git a/test/jdk/sun/security/provider/acvp/ML_DSA_Test.java b/test/jdk/sun/security/provider/acvp/ML_DSA_Test.java index f76f3d8b9a8..0a5cf8fdb12 100644 --- a/test/jdk/sun/security/provider/acvp/ML_DSA_Test.java +++ b/test/jdk/sun/security/provider/acvp/ML_DSA_Test.java @@ -63,12 +63,12 @@ public class ML_DSA_Test { var f = p == null ? KeyFactory.getInstance("ML-DSA") : KeyFactory.getInstance("ML-DSA", p); - for (var t : kat.get("testGroups").asArray()) { + for (var t : kat.get("testGroups").elements()) { var pname = t.get("parameterSet").asString(); var np = genParams(pname); System.out.println(">> " + pname); - for (var c : t.get("tests").asArray()) { - System.out.print(c.get("tcId").asString() + " "); + for (var c : t.get("tests").elements()) { + System.out.print(c.get("tcId").asInt() + " "); var seed = toByteArray(c.get("seed").asString()); g.initialize(np, new FixedSecureRandom(seed)); var kp = g.generateKeyPair(); @@ -85,7 +85,7 @@ public class ML_DSA_Test { var s = p == null ? Signature.getInstance("ML-DSA") : Signature.getInstance("ML-DSA", p); - for (var t : kat.get("testGroups").asArray()) { + for (var t : kat.get("testGroups").elements()) { var pname = t.get("parameterSet").asString(); System.out.println(">> " + pname + " sign"); var det = t.get("deterministic").asBoolean(); @@ -97,14 +97,14 @@ public class ML_DSA_Test { if (t.get("externalMu").asBoolean()) { continue; // Not supported } - for (var c : t.get("tests").asArray()) { - var cstr = c.get("context"); + for (var c : t.get("tests").elements()) { + var cstr = c.getOrAbsent("context").orElse(null); var ctxt = cstr == null ? new byte[0] : toByteArray(cstr.asString()); var hashAlg = c.get("hashAlg").asString(); if (!hashAlg.equals("none") || ctxt.length != 0) { continue; // Not supported } - System.out.print(Integer.parseInt(c.get("tcId").asString()) + " "); + System.out.print(c.get("tcId").asInt() + " "); var sk = new PrivateKey() { public String getAlgorithm() { return pname; } public String getFormat() { return "RAW"; } @@ -129,7 +129,7 @@ public class ML_DSA_Test { var s = p == null ? Signature.getInstance("ML-DSA") : Signature.getInstance("ML-DSA", p); - for (var t : kat.get("testGroups").asArray()) { + for (var t : kat.get("testGroups").elements()) { var pname = t.get("parameterSet").asString(); System.out.println(">> " + pname + " verify"); @@ -143,14 +143,14 @@ public class ML_DSA_Test { continue; // Not supported } - for (var c : t.get("tests").asArray()) { - var cstr = c.get("context"); + for (var c : t.get("tests").elements()) { + var cstr = c.getOrAbsent("context").orElse(null); var ctxt = cstr == null ? new byte[0] : toByteArray(cstr.asString()); var hashAlg = c.get("hashAlg").asString(); if (!hashAlg.equals("none") || ctxt.length != 0) { continue; // Not supported } - System.out.print(c.get("tcId").asString() + " "); + System.out.print(c.get("tcId").asInt() + " "); var pk = new PublicKey() { public String getAlgorithm() { return pname; } public String getFormat() { return "RAW"; } diff --git a/test/jdk/sun/security/provider/acvp/ML_KEM_Test.java b/test/jdk/sun/security/provider/acvp/ML_KEM_Test.java index 35c1ce611da..5d969bc90ed 100644 --- a/test/jdk/sun/security/provider/acvp/ML_KEM_Test.java +++ b/test/jdk/sun/security/provider/acvp/ML_KEM_Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,12 +61,12 @@ public class ML_KEM_Test { var f = p == null ? KeyFactory.getInstance("ML-KEM") : KeyFactory.getInstance("ML-KEM", p); - for (var t : kat.get("testGroups").asArray()) { + for (var t : kat.get("testGroups").elements()) { var pname = t.get("parameterSet").asString(); var np = genParams(pname); System.out.println(">> " + pname); - for (var c : t.get("tests").asArray()) { - System.out.print(c.get("tcId").asString() + " "); + for (var c : t.get("tests").elements()) { + System.out.print(c.get("tcId").asInt() + " "); var seed = toByteArray(c.get("d").asString() + c.get("z").asString()); g.initialize(np, new FixedSecureRandom(seed)); var kp = g.generateKeyPair(); @@ -84,13 +84,13 @@ public class ML_KEM_Test { var g = p == null ? KEM.getInstance("ML-KEM") : KEM.getInstance("ML-KEM", p); - for (var t : kat.get("testGroups").asArray()) { + for (var t : kat.get("testGroups").elements()) { var pname = t.get("parameterSet").asString(); var function = t.get("function").asString(); System.out.println(">> " + pname + " " + function); if (function.equals("encapsulation")) { - for (var c : t.get("tests").asArray()) { - System.out.print(c.get("tcId").asString() + " "); + for (var c : t.get("tests").elements()) { + System.out.print(c.get("tcId").asInt() + " "); var ek = new PublicKey() { public String getAlgorithm() { return pname; } public String getFormat() { return "RAW"; } @@ -111,8 +111,8 @@ public class ML_KEM_Test { public String getFormat() { return "RAW"; } public byte[] getEncoded() { return oct(toByteArray(t.get("dk").asString())); } }; - for (var c : t.get("tests").asArray()) { - System.out.print(c.get("tcId").asString() + " "); + for (var c : t.get("tests").elements()) { + System.out.print(c.get("tcId").asInt() + " "); var d = g.newDecapsulator(dk); var k = d.decapsulate(toByteArray(c.get("c").asString())); Asserts.assertEqualsByteArray(toByteArray(c.get("k").asString()), k.getEncoded()); diff --git a/test/jdk/sun/security/provider/acvp/SHA_Test.java b/test/jdk/sun/security/provider/acvp/SHA_Test.java index 4a64fb00c8c..9f68a583173 100644 --- a/test/jdk/sun/security/provider/acvp/SHA_Test.java +++ b/test/jdk/sun/security/provider/acvp/SHA_Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,14 +37,14 @@ public class SHA_Test { if (alg.startsWith("SHA2-")) alg = "SHA-" + alg.substring(5); var md = provider == null ? MessageDigest.getInstance(alg) : MessageDigest.getInstance(alg, provider); - for (var t : kat.get("testGroups").asArray()) { + for (var t : kat.get("testGroups").elements()) { var testType = t.get("testType").asString(); switch (testType) { case "AFT" -> { - for (var c : t.get("tests").asArray()) { - System.out.print(c.get("tcId").asString() + " "); + for (var c : t.get("tests").elements()) { + System.out.print(c.get("tcId").asInt() + " "); var msg = toByteArray(c.get("msg").asString()); - var len = Integer.parseInt(c.get("len").asString()); + var len = c.get("len").asInt(); if (msg.length * 8 == len) { Asserts.assertEqualsByteArray( toByteArray(c.get("md").asString()), md.digest(msg)); @@ -56,12 +56,12 @@ public class SHA_Test { case "MCT" -> { var mctVersion = t.get("mctVersion").asString(); var trunc = mctVersion.equals("alternate"); - for (var c : t.get("tests").asArray()) { - System.out.print(c.get("tcId").asString() + " "); + for (var c : t.get("tests").elements()) { + System.out.print(c.get("tcId").asInt() + " "); var SEED = toByteArray(c.get("msg").asString()); - var INITIAL_SEED_LENGTH = Integer.parseInt(c.get("len").asString()); + var INITIAL_SEED_LENGTH = c.get("len").asInt(); if (SEED.length * 8 == INITIAL_SEED_LENGTH) { - for (var r : c.get("resultsArray").asArray()) { + for (var r : c.get("resultsArray").elements()) { if (alg.startsWith("SHA3-")) { var MD = SEED; for (var i = 0; i < 1000; i++) { @@ -99,12 +99,12 @@ public class SHA_Test { } } case "LDT" -> { - for (var c : t.get("tests").asArray()) { - System.out.print(c.get("tcId").asString() + " "); + for (var c : t.get("tests").elements()) { + System.out.print(c.get("tcId").asInt() + " "); var lm = c.get("largeMsg"); var ct = toByteArray(lm.get("content").asString()); - var flen = Long.parseLong(lm.get("fullLength").asString()); - var clen = Long.parseLong(lm.get("contentLength").asString()); + var flen = lm.get("fullLength").asLong(); + var clen = lm.get("contentLength").asLong(); var cc = 0L; while (cc < flen) { md.update(ct); diff --git a/test/lib/jdk/test/lib/json/JSONValue.java b/test/lib/jdk/test/lib/json/JSONValue.java index 72ed2fd917c..3ac6441b4c0 100644 --- a/test/lib/jdk/test/lib/json/JSONValue.java +++ b/test/lib/jdk/test/lib/json/JSONValue.java @@ -25,47 +25,55 @@ package jdk.test.lib.json; import java.math.BigInteger; import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Objects; import java.util.Optional; -public interface JSONValue { +public sealed interface JSONValue + permits JSONValue.JSONObject, JSONValue.JSONArray, JSONValue.JSONString, + JSONValue.JSONNumber, JSONValue.JSONBoolean, JSONValue.JSONNull { public final class JSONObject implements JSONValue { - private final Map value; + private final Map members; - public JSONObject(Map value) { - this.value = value; + private JSONObject(Map members) { + this.members = Map.copyOf(members); } @Override - public JSONObject asObject() { - return this; - } - - public JSONValue get(String k) { - return value.get(k); + public JSONValue get(String name) { + JSONValue v = members.get(name); + if (v == null) { + throw new NoSuchElementException("member " + name + " does not exist"); + } + return v; } @Override - public int size() { - return value.size(); + public Optional getOrAbsent(String name) { + return Optional.ofNullable(members.get(name)); + } + + @Override + public Map members() { + return members; } @Override public String toString() { var builder = new StringBuilder(); builder.append("{"); - for (var key : value.keySet()) { + for (String key : members.keySet()) { builder.append("\""); builder.append(key); builder.append("\":"); - builder.append(value.get(key).toString()); + builder.append(members.get(key).toString()); builder.append(","); } - var end = builder.length() - 1; + int end = builder.length() - 1; if (builder.charAt(end) == ',') { builder.deleteCharAt(end); } @@ -73,13 +81,17 @@ public interface JSONValue { builder.append("}"); return builder.toString(); } + + public static JSONObject of(Map members) { + return new JSONObject(members); + } } public final class JSONString implements JSONValue { private final String value; - public JSONString(String value) { - this.value = value; + private JSONString(String value) { + this.value = Objects.requireNonNull(value); } @Override @@ -129,26 +141,17 @@ public interface JSONValue { builder.append("\""); return builder.toString(); } + + public static JSONString of(String value) { + return new JSONString(value); + } } - public final class JSONArray implements JSONValue, Iterable { - private final List values; + public final class JSONArray implements JSONValue { + private final List elements; - public JSONArray(List array) { - this.values = array; - } - - @Override - public JSONArray asArray() { - return this; - } - - public JSONValue get(int i) { - return values.get(i); - } - - public int size() { - return values.size(); + JSONArray(List elements) { + this.elements = List.copyOf(elements); } @Override @@ -156,9 +159,10 @@ public interface JSONValue { var builder = new StringBuilder(); builder.append("["); - for (var i = 0; i < size(); i++) { - builder.append(get(i).toString()); - if (i != (size() - 1)) { + int size = elements.size(); + for (int i = 0; i < size; i++) { + builder.append(elements.get(i).toString()); + if (i != (size - 1)) { builder.append(","); } } @@ -167,13 +171,61 @@ public interface JSONValue { } @Override - public Iterator iterator() { - return values.iterator(); + public List elements() { + return elements; } @Override - public List elements() { - return List.copyOf(values); + public JSONValue element(int index) { + return elements.get(index); + } + + public static JSONArray of(List elements) { + return new JSONArray(elements); + } + } + + public final class JSONNumber implements JSONValue { + private final String value; + + private JSONNumber(String value) { + this.value = Objects.requireNonNull(value); + } + + @Override + public int asInt() { + return Integer.parseInt(value); + } + + @Override + public long asLong() { + return Long.parseLong(value); + } + + @Override + public double asDouble() { + return Double.parseDouble(value); + } + + @Override + public String toString() { + return value; + } + + public static JSONNumber of(String value) { + return new JSONNumber(value); + } + + public static JSONNumber of(int value) { + return of(String.valueOf(value)); + } + + public static JSONNumber of(long value) { + return of(String.valueOf(value)); + } + + public static JSONNumber of(double value) { + return of(String.valueOf(value)); } } @@ -367,11 +419,10 @@ public interface JSONValue { var value = builder.toString(); if (isInteger) { new BigInteger(value); - return new JSONString(value); } else { Double.parseDouble(value); - return new JSONString(value); } + return JSONNumber.of(value); } private JSONString parseString() { @@ -422,7 +473,7 @@ public interface JSONValue { } advance(); // step beyond closing " - return new JSONString(builder.toString()); + return JSONString.of(builder.toString()); } private JSONArray parseArray() { @@ -445,7 +496,7 @@ public interface JSONValue { } advance(); // step beyond closing ']' - return new JSONArray(list); + return JSONArray.of(list); } public JSONNull parseNull() { @@ -486,7 +537,7 @@ public interface JSONValue { } advance(); // step beyond '}' - return new JSONObject(map); + return JSONObject.of(map); } private boolean isDigit(char c) { @@ -574,43 +625,51 @@ public interface JSONValue { } } - public static JSONValue parse(String s) { + static JSONValue parse(String s) { return new JSONParser().parse(s); } - default int size() { - throw new UnsupportedOperationException("Size operation unsupported"); + default JSONValue get(String name) { + throw new UnsupportedOperationException("Unsupported conversion to object"); + } + + default Optional getOrAbsent(String name) { + throw new UnsupportedOperationException("Unsupported conversion to object"); + } + + default Optional valueOrNull() { + return Optional.of(this); + } + + default Map members() { + throw new UnsupportedOperationException("Unsupported conversion to object"); } default List elements() { throw new UnsupportedOperationException("Unsupported conversion to array"); } - default String asString() { - throw new UnsupportedOperationException("Unsupported conversion to String"); - } - - default JSONArray asArray() { + default JSONValue element(int index) { throw new UnsupportedOperationException("Unsupported conversion to array"); } - default JSONObject asObject() { - throw new UnsupportedOperationException("Unsupported conversion to object"); + default String asString() { + throw new UnsupportedOperationException("Unsupported conversion to string"); + } + + default int asInt() { + throw new UnsupportedOperationException("Unsupported conversion to number"); + } + + default long asLong() { + throw new UnsupportedOperationException("Unsupported conversion to number"); + } + + default double asDouble() { + throw new UnsupportedOperationException("Unsupported conversion to number"); } default boolean asBoolean() { throw new UnsupportedOperationException("Unsupported conversion to boolean"); } - - default JSONValue get(String field) { - return asObject().get(field); - } - - default Optional getOrAbsent(String field) { - return Optional.ofNullable(get(field)); - } - - default Optional valueOrNull() { - return Optional.of(this); - } } diff --git a/test/lib/jdk/test/lib/threaddump/ThreadDump.java b/test/lib/jdk/test/lib/threaddump/ThreadDump.java index 972d46675f4..5633d07d35f 100644 --- a/test/lib/jdk/test/lib/threaddump/ThreadDump.java +++ b/test/lib/jdk/test/lib/threaddump/ThreadDump.java @@ -132,17 +132,14 @@ public final class ThreadDump { } /** - * Assert that a JSONValue is a JSONString and parse the string as an int. + * Convert the given JSON value (number or string) to a long. */ - private static int parseStringAsInt(JSONValue valueObj) { - return Integer.parseInt(valueObj.asString()); - } - - /** - * Assert that a JSONValue is a JSONString and parse the string as a long. - */ - private static long parseStringAsLong(JSONValue valueObj) { - return Long.parseLong(valueObj.asString()); + private static long toLong(JSONValue value) { + return switch (value) { + case JSONValue.JSONNumber _ -> value.asLong(); + case JSONValue.JSONString _ -> Long.parseLong(value.asString()); + default -> throw new RuntimeException("Not number or string"); + }; } /** @@ -178,9 +175,9 @@ public final class ThreadDump { * Return the thread identifier of the owner or empty OptionalLong if not owned. */ public OptionalLong owner() { - return containerObj.get("owner") // string or null + return containerObj.get("owner") // number or string or null .valueOrNull() - .map(v -> OptionalLong.of(parseStringAsLong(v))) + .map(v -> OptionalLong.of(toLong(v))) .orElse(OptionalLong.empty()); } @@ -245,7 +242,7 @@ public final class ThreadDump { private final JSONValue threadObj; ThreadInfo(JSONValue threadObj) { - this.tid = parseStringAsLong(threadObj.get("tid")); + this.tid = toLong(threadObj.get("tid")); this.threadObj = threadObj; } @@ -293,7 +290,7 @@ public final class ThreadDump { */ public OptionalLong parkBlockerOwner() { return threadObj.getOrAbsent("parkBlocker") - .map(v -> OptionalLong.of(parseStringAsLong(v.get("owner")))) + .map(v -> OptionalLong.of(toLong(v.get("owner")))) .orElse(OptionalLong.empty()); } @@ -334,7 +331,7 @@ public final class ThreadDump { .map(JSONValue::elements) .orElse(List.of()) .forEach(e -> { - int depth = parseStringAsInt(e.get("depth")); + int depth = e.get("depth").asInt(); List locks = e.get("locks") .elements() .stream() @@ -354,7 +351,7 @@ public final class ThreadDump { */ public OptionalLong carrier() { return threadObj.getOrAbsent("carrier") - .map(s -> OptionalLong.of(parseStringAsLong(s))) + .map(v -> OptionalLong.of(toLong(v))) .orElse(OptionalLong.empty()); } @@ -389,7 +386,7 @@ public final class ThreadDump { * Returns the value of threadDump/processId. */ public long processId() { - return parseStringAsLong(threadDumpObj.get("processId")); + return toLong(threadDumpObj.get("processId")); } /**