diff --git a/test/jdk/java/text/Format/DecimalFormat/DFSSerializationTest.java b/test/jdk/java/text/Format/DecimalFormat/DFSSerializationTest.java index 9e875e851c882..d4ccb77c137eb 100644 --- a/test/jdk/java/text/Format/DecimalFormat/DFSSerializationTest.java +++ b/test/jdk/java/text/Format/DecimalFormat/DFSSerializationTest.java @@ -23,7 +23,9 @@ /* * @test - * @bug 8366401 + * @bug 4068067 4101150 8366401 + * @library /java/text/testlib + * @build HexDumpReader * @summary Check serialization of DecimalFormatSymbols. That is, ensure the * behavior for each stream version is correct during de-serialization. * @run junit/othervm --add-opens java.base/java.text=ALL-UNNAMED DFSSerializationTest @@ -35,9 +37,11 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.io.Serializable; import java.lang.reflect.Field; import java.text.DecimalFormatSymbols; import java.util.Currency; @@ -51,13 +55,36 @@ public class DFSSerializationTest { + // Test that rely on hex dump files that were written from older JDK versions @Nested - class VersionTests { + class HexDumpTests { + + @Test // See 4068067 and CDFS which is the class in the serialized hex dump + void JDK1_1_4Test() { + // Reconstruct a class serialized during 1.1.4 which has a DFS holder + var cdfs = (CheckDecimalFormatSymbols) assertDoesNotThrow( + () -> deSer("DecimalFormatSymbols.114.txt")); + assertDoesNotThrow(cdfs::Update); // Checks getDigit call succeeds + } + + @Test // See 4068067 + void JDK1_4_2Test() { + // Reconstruct a 1.4.2 DFS + var dfs = (DecimalFormatSymbols) assertDoesNotThrow( + () -> deSer("DecimalFormatSymbols.142.txt")); + // Checks curr symbol is saved, and exponent separator default set + assertEquals("E", dfs.getExponentSeparator()); + assertEquals("*SpecialCurrencySymbol*", dfs.getCurrencySymbol()); + } + } + + @Nested + class StreamVersionTests { // Ensure correct monetarySeparator and exponential field defaults // Reads monetary from decimal, and sets exponential to 'E' @Test - public void version0Test() { + void version0Test() { var crafted = new DFSBuilder() .setVer(0) .set("monetarySeparator", '~') @@ -76,7 +103,7 @@ public void version0Test() { // Note that other versions did allow a locale field, which was nullable. // E.g. see nullableLocaleTest which does not set locale when it is `null` @Test - public void version1Test() { + void version1Test() { var crafted = new DFSBuilder() .setVer(1) .set("locale", null) @@ -89,7 +116,7 @@ public void version1Test() { // Version 2 did not have an exponential separator, and created it via exponent // char field. @Test - public void version2Test() { + void version2Test() { var crafted = new DFSBuilder() .setVer(2) .set("exponentialSeparator", null) @@ -103,7 +130,7 @@ public void version2Test() { // Version 3 didn't have perMillText, percentText, and minusSignText. // These were created from the corresponding char equivalents. @Test - public void version3Test() { + void version3Test() { var crafted = new DFSBuilder() .setVer(3) .set("perMillText", null) @@ -125,7 +152,7 @@ public void version3Test() { // Version 4 did not have monetaryGroupingSeparator. It should be based // off of groupingSeparator. @Test - public void version4Test() { + void version4Test() { var crafted = new DFSBuilder() .setVer(4) .set("monetaryGroupingSeparator", 'Z') @@ -142,7 +169,7 @@ public void version4Test() { // the case and previous stream versions can contain a null locale. Thus, // ensure that a null locale does not cause number data loading to fail. @Test - public void nullableLocaleTest() { + void nullableLocaleTest() { var bytes = ser(new DFSBuilder() .set("locale", null) .set("minusSignText", "zFoo") @@ -157,7 +184,7 @@ public void nullableLocaleTest() { // readObject fails when the {@code char} and {@code String} representations // of percent, per mille, and/or minus sign disagree. @Test - public void disagreeingTextTest() { + void disagreeingTextTest() { var expected = "'char' and 'String' representations of either percent, " + "per mille, and/or minus sign disagree."; assertEquals(expected, assertThrows(InvalidObjectException.class, () -> @@ -179,7 +206,7 @@ public void disagreeingTextTest() { // Ensure the serial version is updated to the current after de-serialization. @Test - public void updatedVersionTest() { + void updatedVersionTest() { var bytes = ser(new DFSBuilder().setVer(-25).build()); var dfs = assertDoesNotThrow(() -> deSer(bytes)); assertEquals(5, readField(dfs, "serialVersionOnStream")); @@ -187,7 +214,7 @@ public void updatedVersionTest() { // Should set currency from 4217 code when it is valid. @Test - public void validIntlCurrencyTest() { + void validIntlCurrencyTest() { var bytes = ser(new DFSBuilder().set("intlCurrencySymbol", "JPY").build()); var dfs = assertDoesNotThrow(() -> deSer(bytes)); assertEquals(Currency.getInstance("JPY"), dfs.getCurrency()); @@ -195,7 +222,7 @@ public void validIntlCurrencyTest() { // Should not set currency when 4217 code is invalid, it remains null. @Test - public void invalidIntlCurrencyTest() { + void invalidIntlCurrencyTest() { var bytes = ser(new DFSBuilder() .set("intlCurrencySymbol", ">.,") .set("locale", Locale.JAPAN) @@ -205,6 +232,26 @@ public void invalidIntlCurrencyTest() { assertNull(dfs.getCurrency()); } + // Ensure the currency symbol is read properly + @Test + void currencySymbolTest() { + var crafted = new DecimalFormatSymbols(); + crafted.setCurrencySymbol("*SpecialCurrencySymbol*"); + var bytes = ser(crafted); + var dfs = assertDoesNotThrow(() -> deSer(bytes)); + assertEquals("*SpecialCurrencySymbol*", dfs.getCurrencySymbol()); + } + + // Ensure the exponent separator is read properly + @Test + void exponentSeparatorTest() { + var crafted = new DecimalFormatSymbols(); + crafted.setExponentSeparator("*SpecialExponentSeparator*"); + var bytes = ser(crafted); + var dfs = assertDoesNotThrow(() -> deSer(bytes)); + assertEquals("*SpecialExponentSeparator*", dfs.getExponentSeparator()); + } + // Utilities ---- // Utility to serialize @@ -218,7 +265,7 @@ private static byte[] ser(Object obj) { }, "Unexpected error during serialization"); } - // Utility to deserialize + // Utility to deserialize from byte array private static DecimalFormatSymbols deSer(byte[] bytes) throws IOException, ClassNotFoundException { try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream)) { @@ -226,6 +273,14 @@ private static DecimalFormatSymbols deSer(byte[] bytes) throws IOException, Clas } } + // Utility to deserialize from file in hex format + private static Object deSer(String file) throws IOException, ClassNotFoundException { + try (InputStream stream = HexDumpReader.getStreamFromHexDump(file); + ObjectInputStream ois = new ObjectInputStream(stream)) { + return ois.readObject(); + } + } + // Utility to read a private field private static Object readField(DecimalFormatSymbols dfs, String name) { return assertDoesNotThrow(() -> { @@ -262,3 +317,12 @@ private DecimalFormatSymbols build() { } } } + +// Not nested, so that it can be cast correctly for the 1.1.4 test +class CheckDecimalFormatSymbols implements Serializable { + DecimalFormatSymbols _decFormatSymbols = new DecimalFormatSymbols(); + public char Update() + { + return _decFormatSymbols.getDigit(); + } +} diff --git a/test/jdk/java/text/Format/NumberFormat/DecimalFormat.114.txt b/test/jdk/java/text/Format/DecimalFormat/DecimalFormat.114.txt similarity index 100% rename from test/jdk/java/text/Format/NumberFormat/DecimalFormat.114.txt rename to test/jdk/java/text/Format/DecimalFormat/DecimalFormat.114.txt diff --git a/test/jdk/java/text/Format/NumberFormat/DecimalFormatSymbols.114.txt b/test/jdk/java/text/Format/DecimalFormat/DecimalFormatSymbols.114.txt similarity index 100% rename from test/jdk/java/text/Format/NumberFormat/DecimalFormatSymbols.114.txt rename to test/jdk/java/text/Format/DecimalFormat/DecimalFormatSymbols.114.txt diff --git a/test/jdk/java/text/Format/NumberFormat/DecimalFormatSymbols.142.txt b/test/jdk/java/text/Format/DecimalFormat/DecimalFormatSymbols.142.txt similarity index 100% rename from test/jdk/java/text/Format/NumberFormat/DecimalFormatSymbols.142.txt rename to test/jdk/java/text/Format/DecimalFormat/DecimalFormatSymbols.142.txt diff --git a/test/jdk/java/text/Format/NumberFormat/NumberFormat4185761a.ser.txt b/test/jdk/java/text/Format/DecimalFormat/NumberFormat4185761a.ser.txt similarity index 100% rename from test/jdk/java/text/Format/NumberFormat/NumberFormat4185761a.ser.txt rename to test/jdk/java/text/Format/DecimalFormat/NumberFormat4185761a.ser.txt diff --git a/test/jdk/java/text/Format/NumberFormat/NumberFormat4185761b.ser.txt b/test/jdk/java/text/Format/DecimalFormat/NumberFormat4185761b.ser.txt similarity index 100% rename from test/jdk/java/text/Format/NumberFormat/NumberFormat4185761b.ser.txt rename to test/jdk/java/text/Format/DecimalFormat/NumberFormat4185761b.ser.txt diff --git a/test/jdk/java/text/Format/DecimalFormat/SerializationTest.java b/test/jdk/java/text/Format/DecimalFormat/SerializationTest.java index 09e3f6cf8092d..6a639b8fea1ab 100644 --- a/test/jdk/java/text/Format/DecimalFormat/SerializationTest.java +++ b/test/jdk/java/text/Format/DecimalFormat/SerializationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, 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 @@ -22,65 +22,344 @@ */ /* * @test - * @bug 8327640 - * @summary Check parseStrict correctness for DecimalFormat serialization - * @run junit/othervm SerializationTest + * @bug 4069754 4067878 4101150 4185761 8327640 + * @library /java/text/testlib + * @build HexDumpReader + * @summary Check de-serialization correctness for DecimalFormat. That is, ensure the + * behavior for each stream version is correct during de-serialization. + * @run junit/othervm --add-opens java.base/java.text=ALL-UNNAMED SerializationTest */ -import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import java.io.FileInputStream; -import java.io.FileOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.lang.reflect.Field; +import java.math.RoundingMode; +import java.text.DateFormat; +import java.text.DecimalFormat; import java.text.NumberFormat; -import java.text.ParseException; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Random; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; public class SerializationTest { - private static final NumberFormat FORMAT = NumberFormat.getInstance(); + @Nested // Test that rely on hex dump files that were written from older JDK versions + class HexDumpTests { - @BeforeAll - public static void mutateFormat() { - FORMAT.setStrict(true); + @Test // See 4101150 and CDF which is the serialized hex dump + void JDK1_1_4Test() { + // Reconstruct a 1.1.4 serializable class which has a DF holder + var cdf = (CheckDecimalFormat) assertDoesNotThrow( + () -> deSer("DecimalFormat.114.txt")); + assertDoesNotThrow(cdf::Update); // Checks format call succeeds + } + + @Test // See 4185761 + void minMaxDigitsTest() { + // Reconstructing a DFS stream from an older JDK version + // The min digits are smaller than the max digits and should fail + // minint maxint minfrac maxfrac + // 0x122 0x121 0x124 0x123 + assertEquals("Digit count range invalid", + assertThrows(InvalidObjectException.class, + () -> deSer("NumberFormat4185761a.ser.txt")).getMessage()); + } + + @Test // See 4185761 + void digitLimitTest() { + // Reconstructing a DFS stream from an older JDK version + // The digit values exceed the class invariant limits + // minint maxint minfrac maxfrac + // 0x311 0x312 0x313 0x314 + assertEquals("Digit count out of range", + assertThrows(InvalidObjectException.class, + () -> deSer("NumberFormat4185761b.ser.txt")).getMessage()); + } } + @Nested + class VersionTests { + + // Version 0 did not have exponential fields and defaulted the value to false + @Test + void version0Test() { + var crafted = new DFBuilder() + .setVer(0) + .set("useExponentialNotation", true) + .build(); + var bytes = ser(crafted); + var df = assertDoesNotThrow(() -> deSer(bytes)); + // Ensure we do not observe exponential notation form + assertFalse(df.format(0).contains("E")); + } + + // Version 1 did not support the affix pattern Strings. Ensure when they + // are read in from the stream they are not defaulted and remain null. + @Test + void version1Test() { + var crafted = new DFBuilder() + .setVer(1) + .set("posPrefixPattern", null) + .set("posSuffixPattern", null) + .set("negPrefixPattern", null) + .set("negSuffixPattern", null) + .build(); + var bytes = ser(crafted); + var df = assertDoesNotThrow(() -> deSer(bytes)); + assertNull(readField(df, "posPrefixPattern")); + assertNull(readField(df, "posSuffixPattern")); + assertNull(readField(df, "negPrefixPattern")); + assertNull(readField(df, "negSuffixPattern")); + } + + // Version 2 did not support the min/max int and frac digits. + // Ensure the proper defaults are set. + @Test + void version2Test() { + var crafted = new DFBuilder() + .setVer(2) + .set("maximumIntegerDigits", -1) + .set("maximumFractionDigits", -1) + .set("minimumIntegerDigits", -1) + .set("minimumFractionDigits", -1) + .build(); + var bytes = ser(crafted); + var df = assertDoesNotThrow(() -> deSer(bytes)); + assertEquals(1, df.getMinimumIntegerDigits()); + assertEquals(3, df.getMaximumFractionDigits()); + assertEquals(309, df.getMaximumIntegerDigits()); + assertEquals(0, df.getMinimumFractionDigits()); + } + + // Version 3 did not support rounding mode. Should default to HALF_EVEN + @Test + void version3Test() { + var crafted = new DFBuilder() + .setVer(3) + .set("roundingMode", RoundingMode.UNNECESSARY) + .build(); + var bytes = ser(crafted); + var df = assertDoesNotThrow(() -> deSer(bytes)); + assertEquals(RoundingMode.HALF_EVEN, df.getRoundingMode()); + } + } + + // Some invariant checking in DF relies on checking NF fields. + // Either via NF.readObject() or through super calls in DF.readObject + @Nested // For all these nested tests, see 4185761 + class NumberFormatTests { + + // Ensure the max integer value invariant is not exceeded + @Test + void integerTest() { + var crafted = new DFBuilder() + .setSuper("maximumIntegerDigits", 786) + .setSuper("minimumIntegerDigits", 785) + .build(); + var bytes = ser(crafted); + assertEquals("Digit count out of range", + assertThrows(InvalidObjectException.class, () -> deSer(bytes)).getMessage()); + } + + // Ensure the max fraction value invariant is not exceeded + @Test + void fractionTest() { + var crafted = new DFBuilder() + .setSuper("maximumFractionDigits", 788) + .setSuper("minimumFractionDigits", 787) + .build(); + var bytes = ser(crafted); + assertEquals("Digit count out of range", + assertThrows(InvalidObjectException.class, () -> deSer(bytes)).getMessage()); + } + + // Ensure the minimum integer digits cannot be greater than the max + @Test + void maxMinIntegerTest() { + var crafted = new DFBuilder() + .setSuper("maximumIntegerDigits", 5) + .setSuper("minimumIntegerDigits", 6) + .build(); + var bytes = ser(crafted); + assertEquals("Digit count range invalid", + assertThrows(InvalidObjectException.class, () -> deSer(bytes)).getMessage()); + } + + // Ensure the minimum fraction digits cannot be greater than the max + @Test + void maxMinFractionTest() { + var crafted = new DFBuilder() + .setSuper("maximumFractionDigits", 5) + .setSuper("minimumFractionDigits", 6) + .build(); + var bytes = ser(crafted); + assertEquals("Digit count range invalid", + assertThrows(InvalidObjectException.class, () -> deSer(bytes)).getMessage()); + } + } + + // Ensure the serial version is updated to the current after de-serialization. @Test - public void testSerialization() throws IOException, ClassNotFoundException { - // Serialize - serialize("fmt.ser", FORMAT); - // Deserialize - deserialize("fmt.ser", FORMAT); - } - - private void serialize(String fileName, NumberFormat... formats) - throws IOException { - try (ObjectOutputStream os = new ObjectOutputStream( - new FileOutputStream(fileName))) { - for (NumberFormat fmt : formats) { - os.writeObject(fmt); - } + void versionTest() { + var bytes = ser(new DFBuilder().setVer(-25).build()); + var df = assertDoesNotThrow(() -> deSer(bytes)); + assertEquals(4, readField(df, "serialVersionOnStream")); + } + + // Ensure strictness value is read properly when it is set. + @Test + void strictnessTest() { + var crafted = new DecimalFormat(); + crafted.setStrict(true); + var bytes = ser(crafted); + var df = assertDoesNotThrow(() -> deSer(bytes)); + assertTrue(df.isStrict()); + } + + // Ensure invalid grouping sizes are corrected to the default invariant. + @Test + void groupingSizeTest() { + var crafted = new DFBuilder() + .set("groupingSize", (byte) -5) + .build(); + var bytes = ser(crafted); + var df = assertDoesNotThrow(() -> deSer(bytes)); + assertEquals(3, df.getGroupingSize()); + } + + // Ensure a de-serialized dFmt does not throw NPE from missing digitList + // later when formatting. i.e. re-construct the transient digitList field + @Test // See 4069754, 4067878 + void digitListTest() { + var crafted = new DecimalFormat(); + var bytes = ser(crafted); + var df = assertDoesNotThrow(() -> deSer(bytes)); + assertDoesNotThrow(() -> df.format(1)); + assertNotNull(readField(df, "digitList")); + } + + // Similar to the previous test, but the original regression test + // which was a failure in DateFormat due to DecimalFormat NPE + @Test // See 4069754 and 4067878 + void digitListDateFormatTest() { + var fmt = new FooFormat(); + fmt.now(); + var bytes = ser(fmt); + var ff = (FooFormat) assertDoesNotThrow(() -> deSer0(bytes)); + assertDoesNotThrow(ff::now); + } + + static class FooFormat implements Serializable { + DateFormat dateFormat = DateFormat.getDateInstance(); + + public String now() { + GregorianCalendar calendar = new GregorianCalendar(); + Date t = calendar.getTime(); + return dateFormat.format(t); } } - private static void deserialize(String fileName, NumberFormat... formats) - throws IOException, ClassNotFoundException { - try (ObjectInputStream os = new ObjectInputStream( - new FileInputStream(fileName))) { - for (NumberFormat fmt : formats) { - NumberFormat obj = (NumberFormat) os.readObject(); - assertEquals(fmt, obj, "Serialized and deserialized" - + " objects do not match"); +// Utilities ---- - String badNumber = "fooofooo23foo"; - assertThrows(ParseException.class, () -> fmt.parse(badNumber)); - assertThrows(ParseException.class, () -> obj.parse(badNumber)); + // Utility to serialize + private static byte[] ser(Object obj) { + return assertDoesNotThrow(() -> { + try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(byteArrayOutputStream)) { + oos.writeObject(obj); + return byteArrayOutputStream.toByteArray(); } + }, "Unexpected error during serialization"); + } + + // Utility to deserialize + private static Object deSer0(byte[] bytes) throws IOException, ClassNotFoundException { + try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); + ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream)) { + return ois.readObject(); } } + + // Convenience cast to DF + private static DecimalFormat deSer(byte[] bytes) throws IOException, ClassNotFoundException { + return (DecimalFormat) deSer0(bytes); + } + + // Utility to deserialize from file in hex format + private static Object deSer(String file) throws IOException, ClassNotFoundException { + try (InputStream stream = HexDumpReader.getStreamFromHexDump(file); + ObjectInputStream ois = new ObjectInputStream(stream)) { + return ois.readObject(); + } + } + + // Utility to read a private field + private static Object readField(DecimalFormat df, String name) { + return assertDoesNotThrow(() -> { + var field = DecimalFormat.class.getDeclaredField(name); + field.setAccessible(true); + return field.get(df); + }, "Unexpected error during field reading"); + } + + // Utility class to build instances of DF via reflection + private static class DFBuilder { + + private final DecimalFormat df; + + private DFBuilder() { + df = new DecimalFormat(); + } + + private DFBuilder setVer(Object value) { + return set("serialVersionOnStream", value); + } + + private DFBuilder setSuper(String field, Object value) { + return set(df.getClass().getSuperclass(), field, value); + } + + private DFBuilder set(String field, Object value) { + return set(df.getClass(), field, value); + } + + private DFBuilder set(Class clzz, String field, Object value) { + return assertDoesNotThrow(() -> { + Field f = clzz.getDeclaredField(field); + f.setAccessible(true); + f.set(df, value); + return this; + }, "Unexpected error during reflection setting"); + } + + private DecimalFormat build() { + return df; + } + } +} + +// Not nested, so that it can be recognized and cast correctly for the 1.1.4 test +class CheckDecimalFormat implements Serializable { + DecimalFormat _decFormat = (DecimalFormat) NumberFormat.getInstance(); + public String Update() { + Random r = new Random(); + return _decFormat.format(r.nextDouble()); + } } diff --git a/test/jdk/java/text/Format/NumberFormat/DFSDeserialization142.java b/test/jdk/java/text/Format/NumberFormat/DFSDeserialization142.java deleted file mode 100644 index 2927f4e2c3b94..0000000000000 --- a/test/jdk/java/text/Format/NumberFormat/DFSDeserialization142.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2005, 2016, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * No at-test for this test, because it needs to be run on older version JDK than 1.6 to test. - * It was tested using 1.4.2. The file object was created using JDK1.6. - */ - - - -import java.awt.*; -import java.text.*; -import java.util.*; -import java.io.*; - -public class DFSDeserialization142{ - - public static void main(String[] args) - { - try { - - File file = new File("DecimalFormatSymbols.current"); - FileInputStream istream = new FileInputStream(file); - ObjectInputStream p = new ObjectInputStream(istream); - DecimalFormatSymbols dfs = (DecimalFormatSymbols)p.readObject(); - if (dfs.getCurrencySymbol().equals("*SpecialCurrencySymbol*")){ - System.out.println("Serialization/Deserialization Test Passed."); - }else{ - throw new Exception("Serialization/Deserialization Test Failed:"+dfs.getCurrencySymbol()); - } - istream.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/test/jdk/java/text/Format/NumberFormat/DFSSerialization.java b/test/jdk/java/text/Format/NumberFormat/DFSSerialization.java deleted file mode 100644 index dea1d68ff6e50..0000000000000 --- a/test/jdk/java/text/Format/NumberFormat/DFSSerialization.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2005, 2024, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 4068067 - * @library /java/text/testlib - * @build DFSSerialization HexDumpReader - * @run junit DFSSerialization - * @summary Three different tests are done. - * 1. read from the object created using jdk1.4.2 - * 2. create a valid DecimalFormatSymbols object with current JDK, then read the object - * 3. Try to create an valid DecimalFormatSymbols object by passing null to set null - * for the exponent separator symbol. Expect the NullPointerException. - */ - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.text.DecimalFormatSymbols; -import java.util.Locale; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.fail; - -public class DFSSerialization{ - - @Test - public void TestDFSSerialization(){ - /* - * 1. read from the object created using jdk1.4.2 - */ - File oldFile = new File(System.getProperty("test.src", "."), "DecimalFormatSymbols.142.txt"); - DecimalFormatSymbols dfs142 = readTestObject(oldFile); - if (dfs142 != null){ - if (dfs142.getExponentSeparator().equals("E") && dfs142.getCurrencySymbol().equals("*SpecialCurrencySymbol*")){ - System.out.println("\n Deserialization of JDK1.4.2 Object from the current JDK: Passed."); - System.out.println(" Deserialization of JDK1.4.2 Object from the current JDK: Passed."); - } else { - fail(" Deserialization of JDK1.4.2 Object from the current JDK was Failed:" - +dfs142.getCurrencySymbol()+" "+dfs142.getExponentSeparator()); - /* - * logically should not throw this exception as errln throws exception - * if not thrown yet - but in case errln got changed - */ - throw new RuntimeException(" Deserialization of JDK1.4.2 Object from the current JDK was Failed:" - +dfs142.getCurrencySymbol()+" "+dfs142.getExponentSeparator()); - } - } - /* - * 2. create a valid DecimalFormatSymbols object with current JDK, then read the object - */ - String validObject = "DecimalFormatSymbols.current"; - File currentFile = createTestObject(validObject, "*SpecialExponentSeparator*"); - - DecimalFormatSymbols dfsValid = readTestObject(currentFile); - if (dfsValid != null){ - if (dfsValid.getExponentSeparator().equals("*SpecialExponentSeparator*") && - dfsValid.getCurrencySymbol().equals("*SpecialCurrencySymbol*")){ - System.out.println(" Deserialization of current JDK Object from the current JDK: Passed."); - System.out.println(" Deserialization of current JDK Object from the current JDK: Passed."); - } else { - fail(" Deserialization of current JDK Object from the current JDK was Failed:" - +dfsValid.getCurrencySymbol()+" "+dfsValid.getExponentSeparator()); - /* - * logically should not throw this exception as errln throws exception - * if not thrown yet - but in case errln got changed - */ - throw new RuntimeException(" Deserialization of current Object from the current JDK was Failed:" - +dfsValid.getCurrencySymbol()+" "+dfsValid.getExponentSeparator()); - } - } - /* - * 3. Try to create an valid DecimalFormatSymbols object by passing null - * to set null for the exponent separator symbol. Expect the NullPointerException. - */ - DecimalFormatSymbols symNPE = new DecimalFormatSymbols(Locale.US); - boolean npePassed = false; - try { - symNPE.setExponentSeparator(null); - } catch (NullPointerException npe){ - npePassed = true; - System.out.println(" Trying to set exponent separator with null: Passed."); - System.out.println(" Trying to set exponent separator with null: Passed."); - } - if (!npePassed){ - System.out.println(" Trying to set exponent separator with null:Failed."); - fail(" Trying to set exponent separator with null:Failed."); - /* - * logically should not throw this exception as errln throws exception - * if not thrown yet - but in case errln got changed - */ - throw new RuntimeException(" Trying to set exponent separator with null:Failed."); - } - - } - - private DecimalFormatSymbols readTestObject(File inputFile){ - try (InputStream istream = inputFile.getName().endsWith(".txt") ? - HexDumpReader.getStreamFromHexDump(inputFile) : - new FileInputStream(inputFile)) { - ObjectInputStream p = new ObjectInputStream(istream); - DecimalFormatSymbols dfs = (DecimalFormatSymbols)p.readObject(); - return dfs; - } catch (Exception e) { - fail("Test Malfunction in DFSSerialization: Exception while reading the object"); - /* - * logically should not throw this exception as errln throws exception - * if not thrown yet - but in case errln got changed - */ - throw new RuntimeException("Test Malfunction: re-throwing the exception", e); - } - } - - private File createTestObject(String objectName, String expString){ - DecimalFormatSymbols dfs= new DecimalFormatSymbols(); - dfs.setExponentSeparator(expString); - dfs.setCurrencySymbol("*SpecialCurrencySymbol*"); - System.out.println(" The special exponent separator is set : " + dfs.getExponentSeparator()); - System.out.println(" The special currency symbol is set : " + dfs.getCurrencySymbol()); - - // 6345659: create a test object in the test.class dir where test user has a write permission. - File file = new File(System.getProperty("test.class", "."), objectName); - try (FileOutputStream ostream = new FileOutputStream(file)) { - ObjectOutputStream p = new ObjectOutputStream(ostream); - p.writeObject(dfs); - //System.out.println(" The special currency symbol is set : " + dfs.getCurrencySymbol()); - return file; - } catch (Exception e){ - fail("Test Malfunction in DFSSerialization: Exception while creating an object"); - /* - * logically should not throw this exception as errln throws exception - * if not thrown yet - but in case errln got changed - */ - throw new RuntimeException("Test Malfunction: re-throwing the exception", e); - } - } -} diff --git a/test/jdk/java/text/Format/NumberFormat/DFSSerialization142.java b/test/jdk/java/text/Format/NumberFormat/DFSSerialization142.java deleted file mode 100644 index 4a5e873ee2354..0000000000000 --- a/test/jdk/java/text/Format/NumberFormat/DFSSerialization142.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2005, 2016, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * No at-test for this test, because it needs to be run on JDK 1.4.2 - * Instead, the resulting serialized file - * DecimalFormatSymbols.142 is archived. - */ - -import java.awt.*; -import java.text.*; -import java.util.*; -import java.io.*; - -public class DFSSerialization142 { - - public static void main(String[] args) - { - try { - - DecimalFormatSymbols dfs= new DecimalFormatSymbols(); - System.out.println("Default currency symbol in the default locale : " + dfs.getCurrencySymbol()); - dfs.setCurrencySymbol("*SpecialCurrencySymbol*"); - System.out.println("The special currency symbol is set : " + dfs.getCurrencySymbol()); - FileOutputStream ostream = new FileOutputStream("DecimalFormatSymbols.142"); - ObjectOutputStream p = new ObjectOutputStream(ostream); - p.writeObject(dfs); - ostream.close(); - System.out.println("DecimalFormatSymbols saved ok."); - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/test/jdk/java/text/Format/NumberFormat/NumberRegression.java b/test/jdk/java/text/Format/NumberFormat/NumberRegression.java index 2ff111f0e4bfd..dcc87643b2bea 100644 --- a/test/jdk/java/text/Format/NumberFormat/NumberRegression.java +++ b/test/jdk/java/text/Format/NumberFormat/NumberRegression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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,9 +28,8 @@ * 4087251 4087535 4088161 4088503 4090489 4090504 4092480 4092561 4095713 * 4098741 4099404 4101481 4106658 4106662 4106664 4108738 4110936 4122840 * 4125885 4134034 4134300 4140009 4141750 4145457 4147295 4147706 4162198 - * 4162852 4167494 4170798 4176114 4179818 4185761 4212072 4212073 4216742 - * 4217661 4243011 4243108 4330377 4233840 4241880 4833877 8008577 8227313 - * 8174269 + * 4162852 4167494 4170798 4176114 4179818 4212072 4212073 4216742 4217661 + * 4243011 4243108 4330377 4233840 4241880 4833877 8008577 8227313 8174269 * @summary Regression tests for NumberFormat and associated classes * @library /java/text/testlib * @build HexDumpReader TestUtils @@ -307,33 +306,6 @@ public void Test4068693() Locale.setDefault(savedLocale); } - /* bugs 4069754, 4067878 - * null pointer thrown when accessing a deserialized DecimalFormat - * object. - */ - @Test - public void Test4069754() - { - try { - myformat it = new myformat(); - System.out.println(it.Now()); - FileOutputStream ostream = new FileOutputStream("t.tmp"); - ObjectOutputStream p = new ObjectOutputStream(ostream); - p.writeObject(it); - ostream.close(); - System.out.println("Saved ok."); - - FileInputStream istream = new FileInputStream("t.tmp"); - ObjectInputStream p2 = new ObjectInputStream(istream); - myformat it2 = (myformat)p2.readObject(); - System.out.println(it2.Now()); - istream.close(); - System.out.println("Loaded ok."); - } catch (Exception foo) { - fail("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage()); - } - } - /** * DecimalFormat.applyPattern(String) allows illegal patterns */ @@ -1485,59 +1457,6 @@ public void Test4179818() { } } - @Test - public void Test4185761() throws IOException, ClassNotFoundException { - /* Code used to write out the initial files, which are - * then edited manually: - NumberFormat nf = NumberFormat.getInstance(Locale.US); - nf.setMinimumIntegerDigits(0x111); // Keep under 309 - nf.setMaximumIntegerDigits(0x112); // Keep under 309 - nf.setMinimumFractionDigits(0x113); // Keep under 340 - nf.setMaximumFractionDigits(0x114); // Keep under 340 - FileOutputStream ostream = - new FileOutputStream("NumberFormat4185761"); - ObjectOutputStream p = new ObjectOutputStream(ostream); - p.writeObject(nf); - ostream.close(); - */ - - // File minint maxint minfrac maxfrac - // NumberFormat4185761a 0x122 0x121 0x124 0x123 - // NumberFormat4185761b 0x311 0x312 0x313 0x314 - // File a is bad because the mins are smaller than the maxes. - // File b is bad because the values are too big for a DecimalFormat. - // These files have a sufix ".ser.txt". - - InputStream istream = HexDumpReader.getStreamFromHexDump("NumberFormat4185761a.ser.txt"); - ObjectInputStream p = new ObjectInputStream(istream); - try { - NumberFormat nf = (NumberFormat) p.readObject(); - fail("FAIL: Deserialized bogus NumberFormat int:" + - nf.getMinimumIntegerDigits() + ".." + - nf.getMaximumIntegerDigits() + " frac:" + - nf.getMinimumFractionDigits() + ".." + - nf.getMaximumFractionDigits()); - } catch (InvalidObjectException e) { - System.out.println("Ok: " + e.getMessage()); - } - istream.close(); - - istream = HexDumpReader.getStreamFromHexDump("NumberFormat4185761b.ser.txt"); - p = new ObjectInputStream(istream); - try { - NumberFormat nf = (NumberFormat) p.readObject(); - fail("FAIL: Deserialized bogus DecimalFormat int:" + - nf.getMinimumIntegerDigits() + ".." + - nf.getMaximumIntegerDigits() + " frac:" + - nf.getMinimumFractionDigits() + ".." + - nf.getMaximumFractionDigits()); - } catch (InvalidObjectException e) { - System.out.println("Ok: " + e.getMessage()); - } - istream.close(); - } - - /** * Some DecimalFormatSymbols changes are not picked up by DecimalFormat. * This includes the minus sign, currency symbol, international currency @@ -1930,20 +1849,6 @@ public void test8227313() throws ParseException { } } -@SuppressWarnings("serial") -class myformat implements Serializable -{ - DateFormat _dateFormat = DateFormat.getDateInstance(); - - public String Now() - { - GregorianCalendar calendar = new GregorianCalendar(); - Date t = calendar.getTime(); - String nowStr = _dateFormat.format(t); - return nowStr; - } -} - @SuppressWarnings("serial") class MyNumberFormatTest extends NumberFormat { public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) { diff --git a/test/jdk/java/text/Format/NumberFormat/SerializationLoadTest.java b/test/jdk/java/text/Format/NumberFormat/SerializationLoadTest.java deleted file mode 100644 index 501af54c7da20..0000000000000 --- a/test/jdk/java/text/Format/NumberFormat/SerializationLoadTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 1998, 2016, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 4101150 - * @library /java/text/testlib - * @build SerializationLoadTest HexDumpReader - * @run main SerializationLoadTest - * @summary test serialization compatibility of DecimalFormat and DecimalFormatSymbols - * @key randomness - */ - -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.Serializable; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.text.NumberFormat; -import java.util.Random; - -public class SerializationLoadTest { - - public static void main(String[] args) - { - try { - InputStream istream1 = HexDumpReader.getStreamFromHexDump("DecimalFormat.114.txt"); - ObjectInputStream p = new ObjectInputStream(istream1); - CheckDecimalFormat it = (CheckDecimalFormat)p.readObject(); - System.out.println("1.1.4 DecimalFormat Loaded ok."); - System.out.println(it.Update()); - System.out.println("Called Update successfully."); - istream1.close(); - - InputStream istream2 = HexDumpReader.getStreamFromHexDump("DecimalFormatSymbols.114.txt"); - ObjectInputStream p2 = new ObjectInputStream(istream2); - CheckDecimalFormatSymbols it2 = (CheckDecimalFormatSymbols)p2.readObject(); - System.out.println("1.1.4 DecimalFormatSymbols Loaded ok."); - System.out.println("getDigit : " + it2.Update()); - System.out.println("Called Update successfully."); - istream2.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } -} - -@SuppressWarnings("serial") -class CheckDecimalFormat implements Serializable -{ - DecimalFormat _decFormat = (DecimalFormat)NumberFormat.getInstance(); - - public String Update() - { - Random r = new Random(); - return _decFormat.format(r.nextDouble()); - } -} - -@SuppressWarnings("serial") -class CheckDecimalFormatSymbols implements Serializable -{ - DecimalFormatSymbols _decFormatSymbols = new DecimalFormatSymbols(); - - public char Update() - { - return _decFormatSymbols.getDigit(); - } -} diff --git a/test/jdk/java/text/Format/NumberFormat/SerializationSaveTest.java b/test/jdk/java/text/Format/NumberFormat/SerializationSaveTest.java deleted file mode 100644 index 0332efeca0f1f..0000000000000 --- a/test/jdk/java/text/Format/NumberFormat/SerializationSaveTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 1998, 2016, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * No at-test for this test, because it needs to be run on JDK 1.1.4. - * Instead, the resulting serialized files DecimalFormat.114 and - * DecimalFormatSymbols.114 are archived. - */ - -import java.awt.*; -import java.text.*; -import java.util.*; -import java.io.*; - -public class SerializationSaveTest { - - public static void main(String[] args) - { - try { - CheckDecimalFormat it = new CheckDecimalFormat(); - System.out.println(it.Update()); - FileOutputStream ostream = new FileOutputStream("DecimalFormat.114"); - ObjectOutputStream p = new ObjectOutputStream(ostream); - p.writeObject(it); - ostream.close(); - System.out.println("DecimalFormat saved ok."); - CheckDecimalFormatSymbols it2 = new CheckDecimalFormatSymbols(); - System.out.println("getDigit : " + it2.Update()); - FileOutputStream ostream2 = new FileOutputStream("DecimalFormatSymbols.114"); - ObjectOutputStream p2 = new ObjectOutputStream(ostream2); - p2.writeObject(it2); - ostream2.close(); - System.out.println("DecimalFormatSymbols saved ok."); - } catch (Exception e) { - e.printStackTrace(); - } - } -} - -@SuppressWarnings("serial") -class CheckDecimalFormat implements Serializable -{ - DecimalFormat _decFormat = (DecimalFormat)NumberFormat.getInstance(); - - public String Update() - { - Random r = new Random(); - return _decFormat.format(r.nextDouble()); - } -} - -@SuppressWarnings("serial") -class CheckDecimalFormatSymbols implements Serializable -{ - DecimalFormatSymbols _decFormatSymbols = new DecimalFormatSymbols(); - - public char Update() - { - return _decFormatSymbols.getDigit(); - } -}