【发布时间】:2011-06-22 21:41:31
【问题描述】:
我遇到了一个非常令人沮丧的问题,涉及 OS X 和 Java Swing GUI;特别是我遇到了 Cocoa 兼容模式的问题。
我在机器人实验室工作,我们的很多软件都是通过内部模拟套件运行的。该模拟套件的代码已有近 10 年的历史,由我们的一位首席研究人员在他上大学时创建。模拟在 Swing GUI 中运行。模拟在 Linux 和 Windows 计算机上都可以正常运行,但不能在 OS X 上运行。
需要明确的是,我正在编写的代码不是 GUI 代码。我不是“GUI Guy”。然而,他很久以前编写的代码提供了一个 API,用于快速创建基于关节和链接的标准机械系统的机器人模型模拟,这些模拟以 GUI 的形式出现,以便于启动、停止、记录、回放、跟踪变量等操作,创建绘图等。所以我没有直接调用任何 Swing 代码;这是我们每个模拟使用的所有“沼泽标准”(对我们的情况而言)。而且每一个都在 OS X 上崩溃,而在 Windows 和 Linux 下运行得很好。
我浏览了互联网,虽然我无法找到解决问题的方法,但问题的根源似乎是 Cocoa 兼容模式要求程序员遵守严格的图形线程指南接口。似乎弹出最多的一个例子是,如果您不使用SwingUtilities.invokeLater() 线程化您的GUI,那么您的代码将不稳定。编写代码的人承认,当他最初创建 API 时,他并没有遵循最佳线程实践。
Cocoa 兼容模式也似乎对某种 Swing 操作强制某种超时,不太确定它是什么,但我使用的是 2011 年 MacBook Pro,2.3 GHz 四核i7、8 GB RAM、一个 SSD 和一个 1 GB Radeon 6750M。我想我没有遇到某种超时。
我们在 Eclipse 中开发,并从 Eclipse 启动我们的模拟程序(我们不需要将它们转换为任何形式的可执行文件)。启动模拟时,GUI 会出现并完全填充。但是,它不能与之交互。即使是“红绿灯”也永远不会激活,因此终止 GUI 的唯一方法是使用 Eclipse 中的终止按钮。
Here is a screenshot of what the console looks like。我不是 Cocoa 开发人员,所以错误本身对我来说意义不大,但我知道 NS 前缀意味着错误来自 Cocoa,我知道似乎正在发生的事情是某种线程经理(可能是 Grand Central Dispatch?)正在尝试对空锁对象进行操作,并且在某个时候或另一个线程池存在问题。
据我所知,目前无法禁用 Cocoa 兼容模式(似乎曾经使用 Apple 特定的 java 系统属性,但该属性不再出现在提供的有效系统属性列表中Apple 开发者网站)。我也尝试使用 -XstartOnFirstThread 参数无济于事。虽然我们的实验室主要是 Linux 和 Windows 驱动,但我们的组织规模很大,并且不同的团队想要开始使用我们为他们的项目创建的一些模拟,这个部门主要是使用 Mac 的部门(我也是我自己是 OS X 用户,所以我想继续使用我的 MBP)。
那里的任何人都可以告诉我是否有办法禁用 Cocoa 兼容模式,或者至少我的怀疑是否正确:是什么导致了错误?我们不是官僚机构,我们的老板知道代码有错误,所以如果我的预感是正确的,那么执行直觉和重写并不是不可能的,就像在大公司那样。正如我已经说过的那样,模拟在其他操作系统上没有稳定性问题,并且许多源于 OS X 限制的稳定性问题似乎与提供愉快的用户体验有关,我们并不真正关心,因为这不是面向用户的产品。它根本不是产品。
我不是在寻找与我谈论 UX/UIX、非阻塞 UI 或线程/UI 设计最佳实践的 cmets 或答案。这些都是我所熟悉的,而这些也是我的上司更熟悉的。我只是希望有人可以帮助我消除 OS X 对我们的 Java 代码任意设置的限制,或有人可以为我指明正确的方向,以便我们可以让我们当前的代码符合操作系统的限制。
我正在使用适用于 OS X 的最新 JVM/JDK、最新的 OS X 开发工具和最新版本的 Snow Leopard。
编辑:这是一个自包含并编译的Gist。它完全没有响应,就像上面一样,虽然它没有所有的空锁错误,但它确实有自动释放错误并且在 OS X 上不起作用。
【问题讨论】:
-
您的应用程序是否使用
com.apple.eawt.CocoaComponent以及 Swing? -
重现问题的sscce 可能有助于澄清问题。
-
@trashgod 不,我们不使用 CocoaComponents,此代码不是为 OS X 编写的,并且是在 10 多年前创建的。我想如果它确实使用了这些东西,它可能不会像现在这样在 Windows 或 Linux 上运行。
-
此外,发布代码 sn-p 绝对没有意义,因为这基本上会涉及发布整个庞大的 API,因为所有 Swing 代码都在 API 中。我不会把我们实验室的整个代码库都放在 SO 上。
-
我完全同意,sn-p 是没用的; sscce 可能会有所帮助,但可靠的错误线程通常是显而易见的。我在 Mac OS 上编写了很多跨平台的 Swing,而且我不得不不止一次地在遗留代码中追踪这些东西。 Mac OS 可能会暴露问题,但这是巧合。我很同情,但我不知道如何以目前的形式回答这个问题。
标签: java swing macos user-interface crash