From 74faf033127ab3a5e28be75b91e662c589f81084 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Fri, 9 Jan 2026 23:36:19 +0000 Subject: [PATCH] 8374819: jpackage and jpackage tests leave some I/O streams unclosed Reviewed-by: almatvee --- .../internal/AppImageInfoPListFile.java | 6 ++--- .../jdk/jpackage/internal/AppImageFile.java | 23 ++++++++++++++++--- .../jpackage/internal/util/PListReader.java | 5 ++-- .../jdk/jpackage/test/AppImageFile.java | 5 ++-- .../jdk/jpackage/test/LauncherVerifier.java | 11 +++++---- .../jpackage/macosx/HostArchPkgTest.java | 5 ++-- .../jpackage/windows/WinLongVersionTest.java | 7 +++--- 7 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/AppImageInfoPListFile.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/AppImageInfoPListFile.java index 4787d1297bb..602e147a970 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/AppImageInfoPListFile.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/AppImageInfoPListFile.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 @@ -24,8 +24,6 @@ */ package jdk.jpackage.internal; -import static jdk.jpackage.internal.util.XmlUtils.initDocumentBuilder; - import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -50,7 +48,7 @@ record AppImageInfoPListFile(String bundleIdentifier, String bundleName, String static AppImageInfoPListFile loadFromInfoPList(Path infoPListFile) throws IOException, InvalidPlistFileException, SAXException { - final var plistReader = new PListReader(initDocumentBuilder().parse(Files.newInputStream(infoPListFile))); + final var plistReader = new PListReader(Files.readAllBytes(infoPListFile)); try { return new AppImageInfoPListFile( diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java index 5f473b554be..75ead9d08ad 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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,11 +28,12 @@ import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toUnmodifiableMap; import static java.util.stream.Collectors.toUnmodifiableSet; import static jdk.jpackage.internal.cli.StandardAppImageFileOption.APP_VERSION; -import static jdk.jpackage.internal.cli.StandardAppImageFileOption.LAUNCHER_AS_SERVICE; import static jdk.jpackage.internal.cli.StandardAppImageFileOption.DESCRIPTION; +import static jdk.jpackage.internal.cli.StandardAppImageFileOption.LAUNCHER_AS_SERVICE; import static jdk.jpackage.internal.cli.StandardAppImageFileOption.LAUNCHER_NAME; import static jdk.jpackage.internal.util.function.ThrowingFunction.toFunction; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.NoSuchFileException; @@ -162,7 +163,23 @@ final class AppImageFile { final var relativeAppImageFilePath = appImageDir.relativize(appImageFilePath); try { - final Document doc = XmlUtils.initDocumentBuilder().parse(Files.newInputStream(appImageFilePath)); + // + // Use javax.xml.parsers.DocumentBuilder#parse(java.io.InputStream). + // Don't use javax.xml.parsers.DocumentBuilder#parse(java.io.File) as this will introduce + // dependency on how the XML parser reports filesystem I/O errors. + // E.g.: the default JDK XML parser throws java.io.FileNotFoundException if the supplied + // directory is not found and throws org.xml.sax.SAXParseException if the supplied file is a directory. + // Another DOM XML parser (a different version of Xerces?) may behave differently. + // + // The use of javax.xml.parsers.DocumentBuilder#parse(java.io.InputStream) eliminates + // differences in how XML parsers handle file system I/O errors. + // Filesystem I/O is delegated to java.nio.file.Files#readAllBytes(java.nio.file.Path), + // XML parser deals with the byte stream in memory and the error handling code + // doesn't depend on how XML parser reports filesystem I/O errors because + // it reads data from memory, not from the filesystem. + // + final Document doc = XmlUtils.initDocumentBuilder().parse( + new ByteArrayInputStream(Files.readAllBytes(appImageFilePath))); final XPath xPath = XPathFactory.newInstance().newXPath(); diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/PListReader.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/PListReader.java index 2c693939dab..4c85358d424 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/PListReader.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/PListReader.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 @@ -35,7 +35,6 @@ import java.util.NoSuchElementException; import java.util.Objects; import java.util.Optional; import java.util.stream.Stream; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.dom.DOMSource; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; @@ -311,7 +310,7 @@ public final class PListReader { } } - public PListReader(byte[] xmlData) throws ParserConfigurationException, SAXException, IOException { + public PListReader(byte[] xmlData) throws SAXException, IOException { this(XmlUtils.initDocumentBuilder().parse(new ByteArrayInputStream(xmlData))); } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AppImageFile.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AppImageFile.java index 94f5b0a52b4..1c6c0ce4447 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AppImageFile.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AppImageFile.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 @@ -28,7 +28,6 @@ import static jdk.jpackage.internal.util.function.ThrowingFunction.toFunction; import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier; import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; import java.util.HashMap; @@ -132,7 +131,7 @@ public record AppImageFile(String mainLauncherName, Optional mainLaunche public static AppImageFile load(Path appImageDir) { return toSupplier(() -> { Document doc = XmlUtils.initDocumentBuilder().parse( - Files.newInputStream(getPathInAppImage(appImageDir))); + getPathInAppImage(appImageDir).toFile()); XPath xPath = XPathFactory.newInstance().newXPath(); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherVerifier.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherVerifier.java index 15d96311d98..f9fcfb905af 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherVerifier.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherVerifier.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 @@ -39,7 +39,6 @@ import java.util.function.BiFunction; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Stream; -import javax.xml.parsers.ParserConfigurationException; import jdk.jpackage.internal.resources.ResourceLocator; import jdk.jpackage.internal.util.PListReader; import jdk.jpackage.internal.util.function.ThrowingBiConsumer; @@ -367,7 +366,7 @@ public final class LauncherVerifier { } } - private void verifyMacEntitlements(JPackageCommand cmd) throws ParserConfigurationException, SAXException, IOException { + private void verifyMacEntitlements(JPackageCommand cmd) throws SAXException, IOException { Path launcherPath = cmd.appLauncherPath(name); var entitlements = MacSignVerify.findEntitlements(launcherPath); @@ -457,8 +456,10 @@ public final class LauncherVerifier { private static final class DefaultEntitlements { private static Map loadFromResources(String resourceName) { return ThrowingSupplier.toSupplier(() -> { - var bytes = ResourceLocator.class.getResourceAsStream(resourceName).readAllBytes(); - return new PListReader(bytes).toMap(true); + try (var in = ResourceLocator.class.getResourceAsStream(resourceName)) { + var bytes = in.readAllBytes(); + return new PListReader(bytes).toMap(true); + } }).get(); } diff --git a/test/jdk/tools/jpackage/macosx/HostArchPkgTest.java b/test/jdk/tools/jpackage/macosx/HostArchPkgTest.java index 7498043c14f..7aebff7cb00 100644 --- a/test/jdk/tools/jpackage/macosx/HostArchPkgTest.java +++ b/test/jdk/tools/jpackage/macosx/HostArchPkgTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -64,8 +64,7 @@ public class HostArchPkgTest { dbf.setFeature("http://apache.org/xml/features/" + "nonvalidating/load-external-dtd", false); DocumentBuilder b = dbf.newDocumentBuilder(); - org.w3c.dom.Document doc - = b.parse(Files.newInputStream(distributionFile)); + org.w3c.dom.Document doc = b.parse(distributionFile.toFile()); XPath xPath = XPathFactory.newInstance().newXPath(); diff --git a/test/jdk/tools/jpackage/windows/WinLongVersionTest.java b/test/jdk/tools/jpackage/windows/WinLongVersionTest.java index 2ee76bcaa15..13650b2dfd3 100644 --- a/test/jdk/tools/jpackage/windows/WinLongVersionTest.java +++ b/test/jdk/tools/jpackage/windows/WinLongVersionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -180,9 +180,8 @@ public class WinLongVersionTest { cmd.setFakeRuntime(); // Create package without Upgrade table - Document doc = XmlUtils.initDocumentBuilder().parse( - Files.newInputStream(TKit.SRC_ROOT.resolve( - "windows/classes/jdk/jpackage/internal/resources/main.wxs"))); + Document doc = XmlUtils.initDocumentBuilder().parse(TKit.SRC_ROOT.resolve( + "windows/classes/jdk/jpackage/internal/resources/main.wxs").toFile()); XPath xPath = XPathFactory.newInstance().newXPath(); NodeList nodes = (NodeList) xPath.evaluate("/Wix/Product/Upgrade", doc, XPathConstants.NODESET);