为什么.headhead默认为真?

时间:2015-02-17 20:47:49

标签: java spring awt

问题设置

这个问题有一些活动部分,所以我会尽力以最简单的形式复制问题。

我正在尝试向TrayIcon添加SystemTray。这通常是操作系统(“平台”)的一个非常简单的目标support呼叫(这将在片刻内发挥不可或缺的作用)。

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

这是我所拥有的代码背后的逻辑:

public class SomeClass {

    public static void main(String[] args) {

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

包含所有内容,这都有效。然而,我真正追求的是能够注入SystemTray实例,其图标已经“准备好了”。

该代码看起来更像这样:

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
    }
}

资源返回@Bean类的实例(SystemTrayControl),该实例本身会调用SystemTray;但是,现在,不再支持SystemTray(请参阅下面的问题部分中的一些说明)。

一些变更细节

这里有一些代码片段(显然,我已经把头埋在了这个问题中。让我知道上下文是否需要扩展。我的信念是以下应该是足够的代码让你感觉到结构):

SystemTrayControl 类:

@PostConstruct
    public void showIcon() {

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

资源类:

@Configuration
public class BeansForNeeds {

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

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

问题

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

  

设置应用程序是否无头,不应实例化AWT。   默认为true以防止出现java图标

如果我手动将属性设置为false,那么应用程序运行良好;但是,我总是有点“摇摇欲坠”地覆盖默认行为,特别是如果“阻止”x,y或z的语言混合使用。

所以,问题是:

为什么财产违约为真?允许.headless禁止的行为会产生什么副作用?对AWT有什么影响?

1 个答案:

答案 0 :(得分:4)

曾几何时,在没有X的Unix上真正的无头盒子中引入AWT类(和原生内容)会导致运行时异常和其他令人讨厌的操作系统级别故障。并且错误只会在类加载后发生,所以它可能有点不确定。

我记得这是Java 6左右。从那以后,事情可能已经发生了变化。我认为重要的是它只是AIX Java的一个问题,它是一个不基于Sun参考实现的洁净室Java。但是,它并不是严格一个错误,因为当我查看每个错误时,参考实现只是错误地逃避了相同的问题。

在我的情况下,我们必须小心一些启动代码,如果它触及AWT时不小心使用了一个方便的实用程序类,因为所有它都会被拉入,并且当它遇到缺少本机UI时会掉下来。这种情况永远不会发生在Windows上,在那里进行了大量的开发。但是,一旦部署在一个真正的无头AIX盒子上,应用程序就会因运行时异常而失败,而这个异常会冒泡到用户身上。

这是因为我们有"客户"代码(表面上看,无头,并且不依赖于任何UI代码)和" UI"代码(知道如何与命令行或完整的Swing GUI交互。)客户端代码被更改,以便它引入一些方便的实用程序类(我忘记了哪一个),但这导致VM引入其他一些类,它引入了AWT,它击中了一些原生代码,期望有某种原生用户界面。

由于AIX框没有X,因此这些本机组件不存在,整个事情因翻译的本机/运行时异常而崩溃。

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

我想进行更多研究,看看这个场景如何与此处讨论的属性进行交互,但对我来说关键的一点是跨平台意味着跨平台!并且"无头"可能意味着在不同平台上非常具体的东西。

相关问题