Skip to content

Commit 926c900

Browse files
committed
8359830: Incorrect os.version reported on macOS Tahoe 26 (Beta)
Reviewed-by: rriggs Backport-of: 8df6b2c
1 parent 658f80e commit 926c900

File tree

2 files changed

+67
-39
lines changed

2 files changed

+67
-39
lines changed

src/java.base/macosx/native/libjava/java_props_macosx.c

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
2323
* questions.
2424
*/
2525

26+
#include <stdbool.h>
2627
#include <sys/socket.h>
2728
#include <netinet/in.h>
2829
#include <arpa/inet.h>
@@ -229,33 +230,50 @@ void setOSNameAndVersion(java_props_t *sprops) {
229230
NSString *nsVerStr = NULL;
230231
char* osVersionCStr = NULL;
231232
NSOperatingSystemVersion osVer = [[NSProcessInfo processInfo] operatingSystemVersion];
232-
// Copy out the char* if running on version other than 10.16 Mac OS (10.16 == 11.x)
233-
// or explicitly requesting version compatibility
234-
if (!((long)osVer.majorVersion == 10 && (long)osVer.minorVersion >= 16) ||
235-
(getenv("SYSTEM_VERSION_COMPAT") != NULL)) {
236-
if (osVer.patchVersion == 0) { // Omit trailing ".0"
233+
// Some macOS versions require special handling. For example,
234+
// when the NSOperatingSystemVersion reports 10.16 as the version
235+
// then it should be treated as 11. Similarly, when it reports 16.0
236+
// as the version then it should be treated as 26.
237+
// If the SYSTEM_VERSION_COMPAT environment variable (a macOS construct)
238+
// is set to 1, then we don't do any special handling for any versions
239+
// and just literally use the value that NSOperatingSystemVersion reports.
240+
const char* envVal = getenv("SYSTEM_VERSION_COMPAT");
241+
const bool versionCompatEnabled = envVal != NULL
242+
&& strncmp(envVal, "1", 1) == 0;
243+
const bool requiresSpecialHandling =
244+
((long) osVer.majorVersion == 10 && (long) osVer.minorVersion >= 16)
245+
|| ((long) osVer.majorVersion == 16 && (long) osVer.minorVersion >= 0);
246+
if (!requiresSpecialHandling || versionCompatEnabled) {
247+
// no special handling - just use the version reported
248+
// by NSOperatingSystemVersion
249+
if (osVer.patchVersion == 0) {
250+
// Omit trailing ".0"
237251
nsVerStr = [NSString stringWithFormat:@"%ld.%ld",
238252
(long)osVer.majorVersion, (long)osVer.minorVersion];
239253
} else {
240254
nsVerStr = [NSString stringWithFormat:@"%ld.%ld.%ld",
241-
(long)osVer.majorVersion, (long)osVer.minorVersion, (long)osVer.patchVersion];
255+
(long)osVer.majorVersion, (long)osVer.minorVersion,
256+
(long)osVer.patchVersion];
242257
}
243258
} else {
244-
// Version 10.16, without explicit env setting of SYSTEM_VERSION_COMPAT
245-
// AKA 11+ Read the *real* ProductVersion from the hidden link to avoid SYSTEM_VERSION_COMPAT
246-
// If not found, fallback below to the SystemVersion.plist
247-
NSDictionary *version = [NSDictionary dictionaryWithContentsOfFile :
248-
@"/System/Library/CoreServices/.SystemVersionPlatform.plist"];
259+
// Requires special handling. We ignore the version reported
260+
// by the NSOperatingSystemVersion API and instead read the
261+
// *real* ProductVersion from
262+
// /System/Library/CoreServices/.SystemVersionPlatform.plist.
263+
// If not found there, then as a last resort we fallback to
264+
// /System/Library/CoreServices/SystemVersion.plist
265+
NSDictionary *version = [NSDictionary dictionaryWithContentsOfFile:
266+
@"/System/Library/CoreServices/.SystemVersionPlatform.plist"];
249267
if (version != NULL) {
250-
nsVerStr = [version objectForKey : @"ProductVersion"];
268+
nsVerStr = [version objectForKey: @"ProductVersion"];
251269
}
252270
}
253-
// Fallback to reading the SystemVersion.plist
271+
// Last resort - fallback to reading the SystemVersion.plist
254272
if (nsVerStr == NULL) {
255-
NSDictionary *version = [NSDictionary dictionaryWithContentsOfFile :
256-
@"/System/Library/CoreServices/SystemVersion.plist"];
273+
NSDictionary *version = [NSDictionary dictionaryWithContentsOfFile:
274+
@"/System/Library/CoreServices/SystemVersion.plist"];
257275
if (version != NULL) {
258-
nsVerStr = [version objectForKey : @"ProductVersion"];
276+
nsVerStr = [version objectForKey: @"ProductVersion"];
259277
}
260278
}
261279

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 2015, 2021 SAP SE. All rights reserved.
3+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
34
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
45
*
56
* This code is free software; you can redistribute it and/or modify it
@@ -28,56 +29,65 @@
2829

2930
/*
3031
* @test
31-
* @bug 8132374
32+
* @bug 8132374 8359830
3233
* @summary Check that the value of the os.version property is equal
3334
* to the value of the corresponding OS provided tools.
3435
* @library /test/lib
36+
* @build jtreg.SkippedException
3537
* @run main OsVersionTest
3638
* @author Volker Simonis
3739
*/
3840
public class OsVersionTest {
3941

40-
public static void main(String args[]) throws Throwable {
42+
public static void main(String[] args) throws Throwable {
4143
final String osVersion = System.getProperty("os.version");
4244
if (osVersion == null) {
43-
throw new Error("Cant query 'os.version' property!");
45+
throw new Error("Missing value for os.version system property");
4446
}
4547
if (Platform.isLinux()) {
4648
OutputAnalyzer output = ProcessTools.executeProcess("uname", "-r");
49+
output.shouldHaveExitValue(0);
4750
if (!osVersion.equals(output.getOutput().trim())) {
4851
throw new Error(osVersion + " != " + output.getOutput().trim());
4952
}
50-
}
51-
else if (Platform.isOSX()) {
52-
OutputAnalyzer output = ProcessTools.executeProcess("sw_vers", "-productVersion");
53-
String swVersOutput = output.getOutput().trim();
54-
if (!osVersion.equals(swVersOutput)) {
55-
// This section can be removed if minimum build SDK is xcode 12+
56-
if (swVersOutput.startsWith(osVersion)) {
57-
throw new SkippedException("MacOS version only matches in parts, this is expected when " +
58-
"JDK was built with Xcode < 12 and MacOS version patch is > 0");
59-
}
60-
throw new Error(osVersion + " != " + swVersOutput);
61-
}
62-
}
63-
else if (Platform.isAix()) {
53+
} else if (Platform.isOSX()) {
54+
testMacOS(osVersion);
55+
} else if (Platform.isAix()) {
6456
OutputAnalyzer output1 = ProcessTools.executeProcess("uname", "-v");
57+
output1.shouldHaveExitValue(0);
6558
OutputAnalyzer output2 = ProcessTools.executeProcess("uname", "-r");
59+
output2.shouldHaveExitValue(0);
6660
String version = output1.getOutput().trim() + "." + output2.getOutput().trim();
6761
if (!osVersion.equals(version)) {
6862
throw new Error(osVersion + " != " + version);
6963
}
70-
}
71-
else if (Platform.isWindows()) {
64+
} else if (Platform.isWindows()) {
7265
OutputAnalyzer output = ProcessTools.executeProcess("cmd", "/c", "ver");
66+
output.shouldHaveExitValue(0);
7367
String version = output.firstMatch(".+\\[Version ([0-9.]+)\\]", 1);
7468
if (version == null || !version.startsWith(osVersion)) {
7569
throw new Error(osVersion + " != " + version);
7670
}
77-
}
78-
else {
79-
System.out.println("This test is currently not supported on " +
71+
} else {
72+
throw new jtreg.SkippedException("This test is currently not supported on " +
8073
Platform.getOsName());
8174
}
8275
}
76+
77+
private static void testMacOS(final String sysPropOsVersion) throws Exception {
78+
final ProcessBuilder pb = new ProcessBuilder("sw_vers", "-productVersion");
79+
// if the test was launched with SYSTEM_VERSION_COMPAT environment variable set,
80+
// then propagate that to the sw_vers too
81+
final String versionCompat = System.getenv().get("SYSTEM_VERSION_COMPAT");
82+
if (versionCompat != null) {
83+
pb.environment().put("SYSTEM_VERSION_COMPAT", versionCompat);
84+
}
85+
final OutputAnalyzer output = ProcessTools.executeCommand(pb);
86+
output.shouldHaveExitValue(0);
87+
final String swVersOutput = output.getOutput().trim();
88+
if (!sysPropOsVersion.equals(swVersOutput)) {
89+
throw new Error("sw_vers reports macOS version: " + swVersOutput
90+
+ " but os.version system property reports version: " + sysPropOsVersion);
91+
}
92+
}
8393
}

0 commit comments

Comments
 (0)