无法在Mac OS X上获得SWT显示

Mat*_*ist 6 swt osgi eclipse-rcp

我正在运行Mac OS X Snow Leopard并且不想从OSGi包中的激活器访问显示器.

以下是我的激活器的启动方法:

@Override
public void start(BundleContext context) throws Exception {
    ExecutorService service = Executors.newSingleThreadExecutor();
    service.execute(new Runnable() {

        @Override
        public void run() {
            Display display = Display.getDefault();
            Shell shell = new Shell(display);
            Text helloText = new Text(shell, SWT.CENTER);
            helloText.setText("Hello SWT!");
            helloText.pack();
            shell.pack();
            shell.open();
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch())
                    display.sleep();
            }
            display.dispose();
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

在Windows环境中调用此代码可以正常工作,但在Mac OS XI上部署会得到以下输出:

2009-10-14 17:17:54.050 java[2010:10003] *** __NSAutoreleaseNoPool(): Object 0x101620d20 of class NSCFString autoreleased with no pool in place - just leaking
2009-10-14 17:17:54.081 java[2010:10003] *** __NSAutoreleaseNoPool(): Object 0x100119240 of class NSCFNumber autoreleased with no pool in place - just leaking
2009-10-14 17:17:54.084 java[2010:10003] *** __NSAutoreleaseNoPool(): Object 0x1001024b0 of class NSCFString autoreleased with no pool in place - just leaking
2009-10-14 17:17:54.086 java[2010:10003] *** __NSAutoreleaseNoPool(): Object 0x7fff701d7f70 of class NSCFString autoreleased with no pool in place - just leaking
2009-10-14 17:17:54.087 java[2010:10003] *** __NSAutoreleaseNoPool(): Object 0x100113330 of class NSCFString autoreleased with no pool in place - just leaking
2009-10-14 17:17:54.092 java[2010:10003] *** __NSAutoreleaseNoPool(): Object 0x101624540 of class NSCFData autoreleased with no pool in place - just leaking
.
.
.

我没有运气就使用了-XstartOnFirstThread VM参数.我在64位Cocoa上,但我也试过32位Cocoa.

尝试使用Carbon时出现以下错误:

Invalid memory access of location 00000020 eip=9012337c

调试Display类时,我可以看到Displays []数组只包含空引用.

Mat*_*ips 3

我可以确认,我们在 Mac OS X 上成功地在其自己的事件循环中运行了 SWT Carbon,该事件循环由捆绑激活启动,因此这绝对是可能的!这是在启动 VM 时使用 -XstartOnFirstThread。

但是,使用 Cocoa SWT(64 位),我看到同样的错误:(

看来,虽然我们运行 Carbon SWT 的方式有效,但它可能并不合规:我们是通过另一个线程驱动事件循环,而不是您应该的主线程。在 Cocoa SWT 下,这不再起作用,而且无论如何这可能是一种狡猾的做法。

在创建 Display 之前,我可以使用以下 hack 修复线程池错误(改编自 Cocoa SWT Device 构造函数):

  NSAutoreleasePool pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
  NSThread nsthread = NSThread.currentThread();
  NSMutableDictionary dictionary = nsthread.threadDictionary();
  NSString key = NSString.stringWith("SWT_NSAutoreleasePool");
  id obj = dictionary.objectForKey(key);
  if (obj == null) {
          NSNumber nsnumber = NSNumber.numberWithInteger(pool.id);
          dictionary.setObject(nsnumber, key);
  } else {
          pool.release();
  }
Run Code Online (Sandbox Code Playgroud)

然而,随后的事件循环挂起(即display.readAndDispatch()/display.sleep()之舞)。我怀疑它只是因为不是主线程而没有读取 UI 事件。

我不确定是否有一个彻底的方法来解决这个问题。就我而言,我们控制启动 OSGi 的主 JVM 线程,因此我正在考虑在其中添加一个钩子,以便在 OSGi 启动后运行 SWT 事件循环。