2011-05-05 44 views
4

我有一个java应用程序,用户可以通过运行java -jar app.jar或通过双击.jar文件从桌面环境从命令行调用。有没有一种安全的编程方式来确定打开Swing窗口是否安全?

我希望应用程序能够检测它是否可以安全地启动Swing GUI,或者它是否必须使用命令行界面。如果我只是在没有检查窗口系统可用性的情况下开始调用Swing函数,那么Java会用一个InternalError进行保护。

举例来说,如果我未设置DISPLAY和运行应用程序,我得到:

 
java.lang.InternalError: Can't connect to X11 window server using '' as the value of the DISPLAY variable. 
    at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method) 
    at sun.awt.X11GraphicsEnvironment.access$200(X11GraphicsEnvironment.java:62) 
    at sun.awt.X11GraphicsEnvironment$1.run(X11GraphicsEnvironment.java:178) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.awt.X11GraphicsEnvironment.(X11GraphicsEnvironment.java:142) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:186) 
    at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:82) 
    at sun.awt.X11.XToolkit.(XToolkit.java:112) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:186) 
    at java.awt.Toolkit$2.run(Toolkit.java:849) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.awt.Toolkit.getDefaultToolkit(Toolkit.java:841) 
     [etc] 

我可能只是尝试...赶上InternalError该并运行在这种情况下,命令行界面,但我d听说不应该捕获错误,因为它们可能会使JVM处于不一致的状态。 (请纠正我,如果我错了。)

有没有什么办法可以检查我是否可以安全地打开Swing窗口而不捕获InternalError? (我可以检查显示器的环境变量不为空,但非空,显示效果不能保证X服务器的实际工作,亦不会这种方法工作在非X11环境。)

+1

尽管您不应该捕获'Error',但在这种特定情况下,可能会收到'InternalError'(仅限于非常有限的'catch'块只调用'getDefaultToolkit()')。但是因为有更好的解决方案('isHeadless()'),所以没有必要。 – 2011-05-05 06:33:33

回答

3

我可以试试......在这种情况下捕获InternalError并运行命令行界面,但我听说不应该捕获错误,因为它们可能会使JVM处于不一致状态。 (请纠正我,如果我错了。)

你的理解是一半的权利。

错误并尝试恢复/继续运行是一个坏主意,因为JVM可能(已经)处于无法恢复的状态。

但是,捕获特定的错误,向控制台打印信息性诊断并立即退出JVM是一件非常安全的事情。 (System.out/err流对于导致Error被抛出的大多数东西都非常有弹性。)

在这种特殊情况下,可能无法恢复任何内容。因此,无论如何,救助是最明智的选择。 (尽管在尝试启动GUI之前调用isHeadless()是个好主意。)

+0

谢谢!在我的情况下,因为即使DISPLAY未设置(或设置为假的东西,比如localhost:38219),isHeadless()也是false,我以这种方式捕获错误并告诉用户传递命令行参数来强制应用程序进入CLI模式。我宁愿运行CLI模式,但如果在捕获InternalError后JVM可能不安全,我会避免这种情况。 – Joe 2011-05-05 15:51:04

+0

这很有趣。根据这个 - http://bugs.gentoo.org/show_bug.cgi?id=361439#c2 - 如果DISPLAY未设置,isHeadless()应该可以工作......但是如果它设置为假的。 – 2011-05-06 03:03:15

14
+1

希望你不要介意,增加一个链接。 – 2011-05-05 06:05:09

+0

打败我吧。 :) – 2011-05-05 06:06:01

+0

您认为'awt.GraphicsEnvironment.isHeadless()'是否也适用于支持SWT的应用程序? – 2011-05-05 06:36:03

相关问题