java.awt.Desktop的问题

时间:2010-11-10 15:19:51

标签: java awt

我的程序中有一个按钮,当按下时,它会带你到我的wiki页面关于该程序。我使用以下行来执行此操作:

java.awt.Desktop.getDesktop().browse(new java.net.URI("http://supuh.wikia.com/wiki/BHT"));

问题在于,无论程序运行的环境如何,我总是会收到以下错误:

java.security.AccessControlException: access denied (java.awt.AWTPermission showWindowWithoutWarningBanner)

有谁知道如何解决这个问题?请注意,这仅适用于一个程序。我制作的任何其他程序都可以使用相同的方法,没有任何问题。

退出挂钩


在程序开始时,添加了此挂钩。没有它,程序运行良好......

System.setSecurityManager(new SecurityManager()
{
  @Override
  public void checkExit(int status)
  {
    closeFile(status);
  }
});

需要此挂钩,但有问题的browse(URI uri)方法不适用。溶液

2 个答案:

答案 0 :(得分:7)

这意味着您正在使用安全管理器:

  

SecurityException - 如果存在安全管理器并且它拒绝AWTPermission(“showWindowWithoutWarningBanner”)权限,或者不允许调用线程创建子进程;而不是从applet或Java Web Started应用程序中调用

如果这是applet或Java Web Start应用程序 - 请在jar上签名。

更新添加安全管理器以检测程序退出错误。有多种方法可以正确地完成这项工作。在你的情况下,我想这是最合适的:

Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
      @Override
      public void run() {
         closeFile();
      }
));

特定于Swing的解决方案是:

  • 如果您不必执行其他操作,请使用frame.setDefaultCloseAction(Frame.EXIT_ON_CLOSE)

  • 使用addWindowStateListener并检查WindowEvent.WINDOW_CLOSED

那说,两个音符:

  • 您不能长时间保持文件打开状态。使用try/catch/finally可在需要时打开和关闭它们。

  • 如果您确实需要某个安全管理器,请确保覆盖SecurityManager的相应方法,以检查您是否可以打开该链接。 (不会告诉你哪一个,所以你不想跳到这个解决方案,这是错误的)

总结一下,我会去setDefaultActionOnClose,并在我读完/写完后立即关闭每个文件。

更新2:在您链接到原始问题后,描述了您想要实现的目标,事情会发生一些变化。您 试图阻止退出,因此您需要SecurityManager。这使得你应该覆盖checkPermission方法并在那里什么都不做(即不抛出异常),至少在检查这些权限时(在调用浏览时检查它们):

  • new AWTPermission("showWindowWithoutWarningBanner")
  • new FilePermission("<<ALL FILES>>", SecurityConstants.FILE_EXECUTE_ACTION)

更新3 以下是完全覆盖该方法的方法:

@Override
public void checkPermission(Permission permission) {
   if (permission instanceof AWTPermission) {
       if (permission.getName().equals("showWindowWithoutWarningBanner")) {
           return;
       }
   }

   if (permission instanceof FilePermission) {
       if (permission.getActions().equalsIgnoreCase("execute")) {
          return;
       }
   }

   java.security.AccessController.checkPermission(permission);
}

(你可以没有外面的if-s)

更新4 只有在您授予程序权限的情况下,上述方法才有效。否则,JVM的一个记录不明确的行为是不允许覆盖安全管理器的非特权。看看this report - 评论说如何解决它。

为了让您的生活更简单,您只需使用空方法体@Override public void checkPermission(..)即可。

答案 1 :(得分:0)

而不是使用您自己的SecurityManager,而是安装一个关闭钩子:

Runnable runnable = new Runnable() {
    closeFile(status);
}

Runtime.getRuntime().addShutdownHook(new Thread (runnable, "Close file"));