【问题标题】:Running SWT application on Mac throws Illegal thread access在 Mac 上运行 SWT 应用程序会引发非法线程访问
【发布时间】:2016-04-08 06:57:12
【问题描述】:

我使用 SWT 编写了一个跨平台应用程序。在 Mac 上,它会抛出一个 SWTExceptionIllegal thread access

manyanswerswhichsaytouse-XstartOnFirstThread

但是,使用起来确实很不方便。不得不说很郁闷

要运行该应用程序,只需双击该程序,除非您使用 Mac。如果您使用 Mac,请打开终端,然后运行以下命令。如果它们不起作用,请参阅这些说明以了解如何配置 PATH 和 JAVA_HOME

有没有什么方法可以在不使用-XstartOnFirstThread 的情况下在 Java 中解决这个问题?

【问题讨论】:

    标签: java macos swt


    【解决方案1】:

    实际上有一种方法可以在主线程上以编程方式运行 SWT 的readAndDispatch,而无需使用命令行选项。它一般不常被提及,在谈论 SWT 时甚至更少提及。我刚刚发现了这一点,它可以挽救生命。

    com.apple.concurrent.Dispatch 仅存在于 Mac 上,并且可以生成一个Executor,它允许将任务提交到主线程。使用它可以创建一个始终在双击时打开的跨平台 SWT 应用程序。

    当然,因为 Windows/Linux 上不存在该类,所以不能简单地直接调用所需的方法。如果您这样做,您的应用程序将在 Windows/Linux 上从ClassNotFoundException 失败。相反,仅当当前操作系统是 Mac 时,您才需要使用一些反射在主线程上运行 readAndDispatch

    您需要检查操作系统是否为 Mac。为此,您可以使用以下代码。

    if (System.getProperty("os.name").toLowerCase().contains("mac"))
    

    之后,就可以使用反射来调用必要的方法了。

    Executor executor;
    try {
        Class<?> dispatchClass = Class.forName("com.apple.concurrent.Dispatch");
        Object dispatchInstance = dispatchClass.getMethod("getInstance").invoke(null);
        executor = (Executor) dispatchClass.getMethod("getNonBlockingMainQueueExecutor").invoke(dispatchInstance);
    } catch (Throwable throwable) {
        throw new RuntimeException("Could not reflectively access Dispatch", throwable);
    }
    

    最后,您可以在 executor 中执行您的 runnable,并为您的应用程序再次跨平台而哭泣。

    【讨论】:

    • 注意:通过发布到 Stack Overflow,您已同意使用 CCA Share Alike 许可您的贡献
    猜你喜欢
    • 2011-12-15
    • 1970-01-01
    • 2012-10-08
    • 1970-01-01
    • 2023-03-10
    • 2013-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多