为什么 .headless 默认为 True?

Why Is .headless Defaulted To True?

问题设置

这个问题有几个变化的部分,所以我会尽力以最简单的形式复制这个问题。

我正在尝试将 TrayIcon 添加到 SystemTray。这通常是一个非常简单的 objective 在操作系统 ("platforms") 上 support 调用(稍后将发挥不可或缺的作用)。

我目前正在为 Windows 机器编程(这不是关于互操作性的问题)。

这是我得到的有效代码背后的逻辑:

public class SomeClass {

    public static void main(String[] args) {

        if(SystemTray.isSupported()) {
            // DO SOMETHING TO ADD AN ICON
        }
    }
}

包含所有内容,这很有效。然而,我真正追求的是能够将 SystemTray 实例与它的图标一起注入 "ready to go"。

该代码看起来有点像这样:

public class SomeClass extends NecessarySpringExtension {
    private @Setter(onMethod=@_@Resource(name="SystemTrayControl"))) SystemTrayControl systemTrayControl;
    // The above uses Lombok, as well.

    public static void main(String[] args) {
        // DO SOME RELATED STUFF like setting the configurations for
        // for the application
    }
}

资源 returns SystemTrayControl class 的实例 (@Bean),它本身会调用 SystemTray;但是,现在 SystemTray 不再受支持(请参阅下面 The Question 部分中的一些解释)。

一些更改细节

这是其中一些代码的片段(显然,我已经被这个问题淹没了。如果上下文需要扩展,请告诉我。我相信以下代码应该足以让您了解结构):

SystemTrayControl Class:

@PostConstruct
    public void showIcon() {

        if (SystemTray.isSupported()) {
            val tray = SystemTray.getSystemTray(); ....

资源 Class:

@Configuration
public class BeansForNeeds {

    @Bean
    public SystemTrayControl systemTrayControl() {
        return new SystemTrayControl():
    } ....

为了更多上下文:如果我删除 SystemTrayControl class 中看到的条件,我会得到一个 HeadlessException (我已经做了一些阅读).

问题

问题源于这样一个事实,即在您的程序中使用 SpringApplicationBuilder 时,.headless 属性 默认为 true。 javadoc 指出:

Sets if the application is headless and should not instantiate AWT. Defaults to true to prevent java icons appearing

如果我手动将属性设置为false,那么应用程序运行良好;然而,我总是有点 "shaky" 覆盖默认行为,特别是如果 "prevents" x、y 或 z 的语言混合在一起。

所以,问题是:

为什么 属性 默认为 true?允许 .headless 禁止的行为有什么副作用?它有什么反对 AWT 的?

曾几何时,在没有 X 的 Unix 等真正的无头机器上引入 AWT classes(和原生的东西)会导致 运行 时间异常和其他讨厌的 OS 级故障。错误只会在 classes 加载后发生,所以它可能有点不确定。

这是 Java 6 左右,我 recall.Things 可能从那时起已经改变了。而且我认为重要的是,这只是 AIX Java 的问题,它是一个不基于 Sun 参考实现的洁净室 Java。不过,严格来说这不是一个错误,因为当我查看每个参考实现的代码时,参考实现只是错误地避开了同样的问题。

在我的例子中,我们必须在一些启动代码中小心,不要意外地使用一个方便的实用程序 class 如果它接触到 AWT,因为那样的话所有的东西都会被拉进来,并因为它而倒下运行 变成失踪的原生 UI。这永远不会发生在 Windows,那里发生了很多发展。但是,一旦部署在真正的无头 AIX 机器上,该应用程序就会严重失败,并出现 运行time 异常,该异常会直接冒泡给用户。

这是因为我们有 "client" 代码(表面上是无头的,不依赖于任何 UI 代码)和 "UI" 代码(知道如何交互使用命令行或完整的 Swing GUI。)客户端代码已更改,因此它引入了一些方便的实用程序 class(我忘了是哪个)但这导致 VM 引入了其他一些classes,它引入了 AWT,它命中了一些本机代码,期望有某种本机 UI。

由于 AIX 机器没有 X,这些本地组件不存在,整个事情因 t运行 预计 native/runtime 异常而崩溃。

因此,我们不仅需要 运行 VM 无头,还必须确保我们的代码不会意外地直接或间接引用任何 AWT 代码。

我想做更多研究以了解这种情况如何与此处讨论的 属性 相互作用,但对我来说关键的收获是跨平台 意味着 跨平台! "headless" 在不同平台上的含义可能非常具体。