Java 8在Big Sur上报告OS .name为"Mac OS x";和操作系统.版本为&quo



这只是我的设置还是其他人有这个问题?

Using AdoptOpenJDK 1.8.0_275安装在:

/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre

System.getProperties()的API文档没有指定任何细节。

可以确认这仍然发生在adoptopenjdk14上,以及j16的openjdk早期访问构建。

如果你想,你可以提交一个bug,但我打赌它会被拒绝。在这一点上,Mac OS X的名称与其说是"操作系统的名称",不如说是"全球一致同意的识别基于unix的mac操作系统的关键字",我指的是全球字面意义上的(如"围绕地球",而不是"跨越你的源库/VM")。改变它只会造成不必要的破坏。这同样适用于10.16版本,只是程度较轻:点之前的东西与其说是"这是操作系统如何标识自己",不如说是"Mac OS的全球一致的版本方案,确定了一套广泛而不明确的功能"。

big sur和catalina之间的过渡并没有什么有意义的区别,除了苹果做了一个营销决策。如果你想指出一个操作系统的转变,可能会证明它是一个完全模糊的选择,认为它是一个"重大变化",当然它是一个catalina,因为这是迄今为止最大的变化(包括完全取消对32位的支持)在最后一批版本。

这给您留下了这样的挑战:好的,很好,我可以使用System.getProperty("os.name")来获得全局一致同意的关键字,这意味着类unix的Mac OS和OS。对于字符串的版本,我可以分解成一些模糊的批量功能,但是如果我需要操作系统的实际名称来展示给用户,该怎么办?

那么你有三个主要的选择:

  1. 简单的方法是编写映射代码。承认os.nameos.version给您提供了(相当有争议的)有用的意图,而不是那么多的正式名称,因此,编写一些映射。这些将把名称/版本对映射到呈现字符串,退回到只是打印名称字符串和版本字符串,逐字拼接。您可以在该表中添加一个映射:Mac OS X/10.16Mac OS Big Sur

  2. 困难的方法:弄清楚你是在mac上(现在更容易;os.name返回Mac OS X,或者只是检查是否存在:Files.isExecutable(Paths.get("/usr/bin/sw_vers"))),然后使用ProcessBuilder执行/usr/bin/sw_vers,将所有输出提取成一个大字符串,然后对其进行解析。其输出如下所示:

ProductName:    macOS
ProductVersion: 11.1
BuildVersion:   20C69

,关键的是,它甚至不包括Big Sur这个词,但却给出了11.1。我不知道如何运行一个命令行工具,实际上给你Big Sur。也许是system_profiler,但请注意,这需要很多分钟来运行,我真的怀疑你想要运行它。

注:你也可以运行.command("/usr/bin/sw_vers", "-productVersion"),它只给你11.1,这可能更容易解析。-productName也可以,只给你macOS

  1. 如果您需要此信息来扫描操作系统功能,那么请停止这样做。它不能在浏览器上工作,对于操作系统版本来说也不是一个好的计划。你在寻找什么能力?想象一下,例如,如果是"我可以运行/usr/bin/sw_vers来解决问题吗",作为一个假设的例子。正确的策略是NOT要检查os.name/os.version,可以推断该命令必须存在,然后运行它,如果不存在则会导致灾难性的失败。正确的做法是检查/usr/bin/sw_vers是否存在,然后执行它,在其他情况下退回到一些基于非mac的解决方案(可能是/usr/bin/uname)。扫描功能,不要扫描操作系统/版本。

调用本地工具sw_vers的Java代码

关于rzwitserloot的答案中的选项# 2,这里有一个完整的代码示例,从Java运行命令行工具sw_vers,该工具描述了在主机上运行的macOS软件的版本。

如果在命令行(控制台)上,例如在Terminal中。App,你运行:

sw_vers
在Intel Mac上的Big Sur中,我们得到:
ProductName:    macOS
ProductVersion: 11.2
BuildVersion:   20D64

我们只需要中间部分。所以运行:

sw_vers -productVersion

…只显示了11.2,这是我们需要的值。

这是一个完整的示例应用程序,它有一个方法来返回这个字符串到Java。

ProcessBuilder类创建操作系统进程。每个新进程由Process类表示。

我们使用try-with-resources语法自动关闭InputStreamScanner对象。

一旦你有了11.2线在手,在FULL STOP上分开,拉动第一个数字11,你就知道你在大苏尔上跑步了。

package org.example;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
/**
* Example code showing how to get current version of macOS from Java
* by running a native command-line tool `sw_vers`.
*/
public class App
{
public static void main ( String[] args )
{
App app = new App();
app.demo();
}
private void demo ( )
{
String version = this.getMacOsVersionNumber();
System.out.println( "version = " + version );
}
public String getMacOsVersionNumber ( )
{
String result = "";
List < String > command = List.of( "sw_vers" , " -productVersion" );
try (
InputStream inputStream = new ProcessBuilder( command ).start().getInputStream() ;
Scanner s = new Scanner( inputStream ).useDelimiter( "\A" ) ;
)
{
result = s.hasNext() ? s.next() : "";
}
catch ( IOException e )
{
e.printStackTrace();
}
return Objects.requireNonNull( result );
}
}

最新更新