我有一个用户可以通过运行java -jar app.jar从命令行调用的java应用程序,或者通过双击.jar文件从桌面环境调用。
我希望应用程序能够检测它是否可以安全地启动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并在这种情况下运行命令行界面,但我听说不应该捕获错误,因为它们可能会使JVM处于不一致状态。 (如果我错了,请纠正我。)
有什么方法可以检查我是否可以安全地打开Swing窗口而不会捕获InternalError? (我可以检查DISPLAY环境变量是否为空,但是非空的DISPLAY不能保证X服务器实际工作。这种方法也不适用于非X11环境。)
答案 0 :(得分:14)
答案 1 :(得分:4)
我可以尝试...捕获InternalError并在这种情况下运行命令行界面,但我听说不应该捕获错误,因为它们可能会使JVM处于不一致状态。 (如果我错了,请纠正我。)
你的理解是正确的。
捕获错误并尝试恢复/继续运行是一个坏主意,因为JVM可能(已经)处于无法恢复的状态。
但是,捕获特定错误,向控制台打印信息性诊断并立即退出JVM是一件非常安全的事情。 (对于导致Error
被抛出的大多数事情,System.out / err流非常有弹性。)
在这种特殊情况下,你可能无法恢复。无论如何,拯救是最明智的选择。 (在尝试启动GUI之前调用isHeadless()
是一个更好的主意。)