mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-15 16:44:36 +02:00
8150442: Enforce Supported Platforms in Packager for MSI bundles
Reviewed-by: almatvee, cstein
This commit is contained in:
parent
642816538f
commit
e7157d174c
14 changed files with 404 additions and 10 deletions
|
@ -29,7 +29,7 @@ DISABLED_WARNINGS_java += dangling-doc-comments
|
|||
|
||||
COPY += .gif .png .txt .spec .script .prerm .preinst \
|
||||
.postrm .postinst .list .sh .desktop .copyright .control .plist .template \
|
||||
.icns .scpt .wxs .wxl .wxi .ico .bmp .tiff .service .xsl
|
||||
.icns .scpt .wxs .wxl .wxi .wxf .ico .bmp .tiff .service .xsl
|
||||
|
||||
CLEAN += .properties
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2018, 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
|
||||
|
@ -661,6 +661,12 @@ jpackage will lookup files by specific names in the resource directory.
|
|||
|
||||
: WiX project file for installer UI
|
||||
|
||||
`os-condition.wxf`
|
||||
|
||||
: WiX project file with the condition to block installation on older versions of Windows
|
||||
|
||||
Default resource is *os-condition.wxf*
|
||||
|
||||
`wix-conv.xsl`
|
||||
|
||||
: WiX source code converter. Used for converting WiX sources from WiX v3 to v4 schema when WiX v4 or newer is used
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* Copyright (c) 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package jdk.jpackage.internal;
|
||||
|
||||
import static jdk.jpackage.internal.WinMsiBundler.WIN_APP_IMAGE;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HexFormat;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import jdk.jpackage.internal.util.XmlConsumer;
|
||||
|
||||
|
||||
/**
|
||||
* WiX Condition to block/allow installation based on OS version.
|
||||
*/
|
||||
record OSVersionCondition(WindowsVersion version) {
|
||||
|
||||
static OSVersionCondition createFromAppImage(ApplicationLayout appLayout, Map<String, ? super Object> params) {
|
||||
Objects.requireNonNull(appLayout);
|
||||
|
||||
final List<Path> executables = new ArrayList<>();
|
||||
|
||||
if (!StandardBundlerParam.isRuntimeInstaller(params)) {
|
||||
final var launcherName = StandardBundlerParam.APP_NAME.fetchFrom(params);
|
||||
executables.add(appLayout.launchersDirectory().resolve(launcherName + ".exe"));
|
||||
}
|
||||
|
||||
executables.add(appLayout.runtimeDirectory().resolve("bin\\java.dll"));
|
||||
|
||||
final var lowestOsVersion = executables.stream()
|
||||
.filter(Files::isRegularFile)
|
||||
.map(WindowsVersion::getExecutableOSVersion)
|
||||
// Order by version, with the higher version first
|
||||
.sorted(WindowsVersion.descendingOrder())
|
||||
.findFirst().orElseGet(() -> {
|
||||
// No java.dll, no launchers, it is either a highly customized or messed up app image.
|
||||
// Let it install on Windows NT/95 or newer.
|
||||
return new WindowsVersion(4, 0);
|
||||
});
|
||||
|
||||
return new OSVersionCondition(lowestOsVersion);
|
||||
}
|
||||
|
||||
record WindowsVersion(int majorOSVersion, int minorOSVersion) {
|
||||
|
||||
WindowsVersion {
|
||||
if (majorOSVersion <= 0) {
|
||||
throw new IllegalArgumentException("Invalid major version");
|
||||
}
|
||||
|
||||
if (minorOSVersion < 0) {
|
||||
throw new IllegalArgumentException("Invalid minor version");
|
||||
}
|
||||
}
|
||||
|
||||
static WindowsVersion getExecutableOSVersion(Path executable) {
|
||||
try (final var fin = Files.newInputStream(executable);
|
||||
final var in = new BufferedInputStream(fin)) {
|
||||
// Skip all but "e_lfanew" fields of DOS stub (https://wiki.osdev.org/PE#DOS_Stub)
|
||||
in.skipNBytes(64 - 4);
|
||||
|
||||
final int peHeaderOffset = read32BitLE(in);
|
||||
if (peHeaderOffset <= 0) {
|
||||
throw new IOException("Invalid PE header offset");
|
||||
}
|
||||
|
||||
// Move to PE header
|
||||
in.skip(peHeaderOffset - 64);
|
||||
|
||||
// Read "mMagic" field (aka PE signature), (https://wiki.osdev.org/PE#PE_header)
|
||||
final byte[] peSignature = in.readNBytes(4);
|
||||
if (peSignature.length != 4) {
|
||||
throw notEnoughBytes();
|
||||
}
|
||||
|
||||
if (peSignature[0] != 'P' || peSignature[1] != 'E' || peSignature[2] != 0 || peSignature[3] != 0) {
|
||||
throw new IOException(String.format("Invalid PE signature: %s", HexFormat.of().formatHex(peSignature)));
|
||||
}
|
||||
|
||||
// Read size of optional PE header from "mSizeOfOptionalHeader" field (https://wiki.osdev.org/PE#PE_header)
|
||||
in.skip(16);
|
||||
final int sizeOfOptionalHeader = read16BitLE(in);
|
||||
if (sizeOfOptionalHeader < (40 + 4)) {
|
||||
throw new IOException("Invalid PE optional header size");
|
||||
}
|
||||
|
||||
// Skip PE header
|
||||
in.skip(2);
|
||||
|
||||
// Skip all fields of Optional PE header until "mMajorOperatingSystemVersion" field (https://wiki.osdev.org/PE#Optional_header)
|
||||
in.skip(40);
|
||||
|
||||
final int mMajorOperatingSystemVersion = read16BitLE(in);
|
||||
final int mMinorOperatingSystemVersion = read16BitLE(in);
|
||||
|
||||
return new WindowsVersion(mMajorOperatingSystemVersion, mMinorOperatingSystemVersion);
|
||||
} catch (IOException ex) {
|
||||
throw new UncheckedIOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
static Comparator<WindowsVersion> descendingOrder() {
|
||||
return Comparator.comparing(WindowsVersion::majorOSVersion).thenComparing(WindowsVersion::minorOSVersion).reversed();
|
||||
}
|
||||
|
||||
private static int read16BitLE(InputStream in) throws IOException {
|
||||
byte buffer[] = new byte[2];
|
||||
if (buffer.length != in.read(buffer)) {
|
||||
throw notEnoughBytes();
|
||||
}
|
||||
|
||||
return ((buffer[0] & 0xFF) | ((buffer[1] & 0xFF) << 8));
|
||||
}
|
||||
|
||||
private static int read32BitLE(InputStream in) throws IOException {
|
||||
byte buffer[] = new byte[4];
|
||||
if (buffer.length != in.read(buffer)) {
|
||||
throw notEnoughBytes();
|
||||
}
|
||||
|
||||
return ((buffer[0] & 0xFF) | ((buffer[1] & 0xFF) << 8) |
|
||||
((buffer[2] & 0xFF) << 16) | ((buffer[3] & 0xFF) << 24));
|
||||
}
|
||||
|
||||
private static IOException notEnoughBytes() {
|
||||
return new IOException("Invalid PE file");
|
||||
}
|
||||
}
|
||||
|
||||
int msiVersionNumber() {
|
||||
return version.majorOSVersion() * 100 + version.minorOSVersion();
|
||||
}
|
||||
|
||||
String msiVersionString() {
|
||||
return String.valueOf(msiVersionNumber());
|
||||
}
|
||||
|
||||
static WixFragmentBuilder createWixFragmentBuilder() {
|
||||
final var builder = new WixFragmentBuilder() {
|
||||
@Override
|
||||
protected Collection<XmlConsumer> getFragmentWriters() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
void initFromParams(Map<String, ? super Object> params) {
|
||||
super.initFromParams(params);
|
||||
|
||||
final Path appImageRoot = WIN_APP_IMAGE.fetchFrom(params);
|
||||
|
||||
ApplicationLayout appImageLayout;
|
||||
if (StandardBundlerParam.isRuntimeInstaller(params)) {
|
||||
appImageLayout = ApplicationLayout.javaRuntime();
|
||||
} else {
|
||||
appImageLayout = ApplicationLayout.platformAppImage();
|
||||
}
|
||||
|
||||
appImageLayout = appImageLayout.resolveAt(appImageRoot);
|
||||
|
||||
final var cond = OSVersionCondition.createFromAppImage(appImageLayout, params);
|
||||
|
||||
setWixVariable("JpExecutableMajorOSVersion", String.valueOf(cond.version().majorOSVersion));
|
||||
setWixVariable("JpExecutableMinorOSVersion", String.valueOf(cond.version().minorOSVersion));
|
||||
setWixVariable("JpExecutableOSVersion", String.valueOf(cond.msiVersionString()));
|
||||
}
|
||||
};
|
||||
|
||||
builder.setDefaultResourceName("os-condition.wxf");
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
|
@ -227,7 +227,8 @@ public class WinMsiBundler extends AbstractBundler {
|
|||
appImageBundler = new WinAppBundler().setDependentTask(true);
|
||||
wixFragments = Stream.of(
|
||||
Map.entry("bundle.wxf", new WixAppImageFragmentBuilder()),
|
||||
Map.entry("ui.wxf", new WixUiFragmentBuilder())
|
||||
Map.entry("ui.wxf", new WixUiFragmentBuilder()),
|
||||
Map.entry("os-condition.wxf", OSVersionCondition.createWixFragmentBuilder())
|
||||
).<WixFragmentBuilder>map(e -> {
|
||||
e.getValue().setOutputFileName(e.getKey());
|
||||
return e.getValue();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
|
@ -38,7 +38,6 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import jdk.jpackage.internal.util.XmlConsumer;
|
||||
import jdk.jpackage.internal.OverridableResource.Source;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.CONFIG_ROOT;
|
||||
import jdk.internal.util.Architecture;
|
||||
import static jdk.jpackage.internal.OverridableResource.createResource;
|
||||
|
@ -62,12 +61,15 @@ abstract class WixFragmentBuilder {
|
|||
outputFileName = v;
|
||||
}
|
||||
|
||||
final void setDefaultResourceName(String v) {
|
||||
defaultResourceName = v;
|
||||
}
|
||||
|
||||
void initFromParams(Map<String, ? super Object> params) {
|
||||
wixVariables = null;
|
||||
additionalResources = null;
|
||||
configRoot = CONFIG_ROOT.fetchFrom(params);
|
||||
fragmentResource = createResource(outputFileName, params).setSourceOrder(
|
||||
Source.ResourceDir);
|
||||
fragmentResource = createResource(defaultResourceName, params).setPublicName(outputFileName);
|
||||
}
|
||||
|
||||
List<String> getLoggableWixFeatures() {
|
||||
|
@ -82,7 +84,10 @@ abstract class WixFragmentBuilder {
|
|||
|
||||
void addFilesToConfigRoot() throws IOException {
|
||||
Path fragmentPath = configRoot.resolve(outputFileName);
|
||||
if (fragmentResource.saveToFile(fragmentPath) == null) {
|
||||
final var src = fragmentResource.saveToStream(null);
|
||||
if (src == null) {
|
||||
// There is no predefined resource for the fragment.
|
||||
// The fragment should be built in the format matching the version of the WiX Toolkit.
|
||||
createWixSource(fragmentPath, xml -> {
|
||||
for (var fragmentWriter : getFragmentWriters()) {
|
||||
xml.writeStartElement("Fragment");
|
||||
|
@ -90,6 +95,11 @@ abstract class WixFragmentBuilder {
|
|||
xml.writeEndElement(); // <Fragment>
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Fragment is picked from the resource. May require conversion.
|
||||
final var resourceGroup = new ResourceGroup(getWixType());
|
||||
resourceGroup.addResource(fragmentResource, fragmentPath);
|
||||
resourceGroup.saveResources();
|
||||
}
|
||||
|
||||
if (additionalResources != null) {
|
||||
|
@ -237,6 +247,7 @@ abstract class WixFragmentBuilder {
|
|||
private WixVariables wixVariables;
|
||||
private ResourceGroup additionalResources;
|
||||
private OverridableResource fragmentResource;
|
||||
private String defaultResourceName;
|
||||
private String outputFileName;
|
||||
private Path configRoot;
|
||||
}
|
||||
|
|
|
@ -15,4 +15,6 @@
|
|||
<String Id="InstallDirNotEmptyDlgInstallDirExistMessage">Der Ordner [INSTALLDIR] ist bereits vorhanden. Möchten Sie diesen Ordner trotzdem installieren?</String>
|
||||
|
||||
<String Id="ContextMenuCommandLabel">Mit [ProductName] öffnen</String>
|
||||
|
||||
<String Id="OsConditionMessage">[ProductName][ProductVersion] is not supported on this version of Windows</String>
|
||||
</WixLocalization>
|
||||
|
|
|
@ -15,4 +15,6 @@
|
|||
<String Id="InstallDirNotEmptyDlgInstallDirExistMessage">The folder [INSTALLDIR] already exist. Would you like to install to that folder anyway?</String>
|
||||
|
||||
<String Id="ContextMenuCommandLabel">Open with [ProductName]</String>
|
||||
|
||||
<String Id="OsConditionMessage">[ProductName][ProductVersion] is not supported on this version of Windows</String>
|
||||
</WixLocalization>
|
||||
|
|
|
@ -15,4 +15,6 @@
|
|||
<String Id="InstallDirNotEmptyDlgInstallDirExistMessage">フォルダ[INSTALLDIR]はすでに存在します。そのフォルダにインストールしますか?</String>
|
||||
|
||||
<String Id="ContextMenuCommandLabel">[ProductName]で開く</String>
|
||||
|
||||
<String Id="OsConditionMessage">[ProductName][ProductVersion] is not supported on this version of Windows</String>
|
||||
</WixLocalization>
|
||||
|
|
|
@ -15,4 +15,6 @@
|
|||
<String Id="InstallDirNotEmptyDlgInstallDirExistMessage">文件夹 [INSTALLDIR] 已存在。是否仍要安装到该文件夹?</String>
|
||||
|
||||
<String Id="ContextMenuCommandLabel">使用 [ProductName] 打开</String>
|
||||
|
||||
<String Id="OsConditionMessage">[ProductName][ProductVersion] is not supported on this version of Windows</String>
|
||||
</WixLocalization>
|
||||
|
|
|
@ -76,6 +76,7 @@
|
|||
<ComponentGroupRef Id="Shortcuts"/>
|
||||
<ComponentGroupRef Id="Files"/>
|
||||
<ComponentGroupRef Id="FileAssociations"/>
|
||||
<ComponentGroupRef Id="FragmentOsCondition"/>
|
||||
</Feature>
|
||||
|
||||
<CustomAction Id="JpSetARPINSTALLLOCATION" Property="ARPINSTALLLOCATION" Value="[INSTALLDIR]" />
|
||||
|
@ -123,6 +124,7 @@
|
|||
<?ifndef JpAllowDowngrades ?>
|
||||
<Custom Action="JpDisallowDowngrade" After="JpFindRelatedProducts">JP_DOWNGRADABLE_FOUND</Custom>
|
||||
<?endif?>
|
||||
<LaunchConditions Before="AppSearch"/>
|
||||
<RemoveExistingProducts Before="CostInitialize"/>
|
||||
<Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
|
||||
</InstallExecuteSequence>
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<Fragment>
|
||||
<Condition Message="!(loc.OsConditionMessage)">
|
||||
<![CDATA[Installed OR (VersionNT >= $(var.JpExecutableOSVersion))]]>
|
||||
</Condition>
|
||||
<!--
|
||||
Fragment contents must be referenced. Otherwise, the fragment will be ignored.
|
||||
Use empty component group as an anchor for the reference.
|
||||
-->
|
||||
<ComponentGroup Id="FragmentOsCondition"/>
|
||||
</Fragment>
|
||||
</Wix>
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
* 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
|
||||
|
@ -73,6 +73,19 @@
|
|||
</xsl:template>
|
||||
|
||||
|
||||
<!--
|
||||
From <Condition Message="foo">Bar</Condition> to <Launch Message="foo" Condition="Bar"/>
|
||||
-->
|
||||
<xsl:template match="wix3:Condition">
|
||||
<xsl:element name="Launch" namespace="http://wixtoolset.org/schemas/v4/wxs">
|
||||
<xsl:attribute name="Condition">
|
||||
<xsl:value-of select="text()"/>
|
||||
</xsl:attribute>
|
||||
<xsl:apply-templates select="@*"/>
|
||||
</xsl:element>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<!--
|
||||
Wix3 Product (https://wixtoolset.org/docs/v3/xsd/wix/product/):
|
||||
Id
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package jdk.jpackage.internal;
|
||||
|
||||
import static jdk.jpackage.internal.OSVersionCondition.WindowsVersion.getExecutableOSVersion;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.condition.OS.WINDOWS;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
import jdk.jpackage.internal.OSVersionCondition.WindowsVersion;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledOnOs;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
|
||||
public class ExecutableOSVersionTest {
|
||||
|
||||
@Test
|
||||
@EnabledOnOs(WINDOWS)
|
||||
public void testWindowsVersionGetExecutableOSVersion() {
|
||||
final var javaHome = Path.of(System.getProperty("java.home"));
|
||||
|
||||
final var javaExeVer = getExecutableOSVersion(javaHome.resolve("bin/java.exe"));
|
||||
|
||||
assertTrue(javaExeVer.majorOSVersion() > 0);
|
||||
assertTrue(javaExeVer.minorOSVersion() >= 0);
|
||||
|
||||
final var javaDllVer = getExecutableOSVersion(javaHome.resolve("bin/java.dll"));
|
||||
|
||||
assertEquals(javaExeVer, javaDllVer);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@EnabledOnOs(WINDOWS)
|
||||
@MethodSource
|
||||
public void testWindowsVersionDescendingOrder(List<WindowsVersion> unsorted, WindowsVersion expectedFirst) {
|
||||
final var actualFirst = unsorted.stream().sorted(WindowsVersion.descendingOrder()).findFirst().orElseThrow();
|
||||
assertEquals(expectedFirst, actualFirst);
|
||||
}
|
||||
|
||||
public static Stream<Object[]> testWindowsVersionDescendingOrder() {
|
||||
return Stream.<Object[]>of(
|
||||
new Object[] { List.of(wver(5, 0), wver(5, 1), wver(4, 9)), wver(5, 1) },
|
||||
new Object[] { List.of(wver(5, 0)), wver(5, 0) },
|
||||
new Object[] { List.of(wver(5, 1), wver(5, 1), wver(5, 0)), wver(5, 1) },
|
||||
new Object[] { List.of(wver(3, 11), wver(4, 8), wver(5, 6)), wver(5, 6) },
|
||||
new Object[] { List.of(wver(3, 11), wver(3, 9), wver(3, 13)), wver(3, 13) }
|
||||
);
|
||||
}
|
||||
|
||||
private final static WindowsVersion wver(int major, int minor) {
|
||||
return new WindowsVersion(major, minor);
|
||||
}
|
||||
}
|
29
test/jdk/tools/jpackage/junit/windows/junit.java
Normal file
29
test/jdk/tools/jpackage/junit/windows/junit.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 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
|
||||
* 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
|
||||
* @summary Test function reading OS version from PE file
|
||||
* @requires (os.family == "windows")
|
||||
* @compile/module=jdk.jpackage jdk/jpackage/internal/ExecutableOSVersionTest.java
|
||||
* @run junit jdk.jpackage/jdk.jpackage.internal.ExecutableOSVersionTest
|
||||
*/
|
Loading…
Add table
Add a link
Reference in a new issue