2009-10-14 16 views
6

Estoy ejecutando Mac OS X Snow Leopard y no quiero acceder a la pantalla desde el activador en un paquete OSGi.No se puede obtener la pantalla SWT en Mac OS X

A continuación se muestra el método de inicio para mi activador:

@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(); 
     } 
    }); 
} 

Al llamar a este código en un entorno de Windows funciona bien, pero el despliegue en Mac OS XI obtener el siguiente resultado:

 
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 
. 
. 
. 

I' he usado el argumento -XstartOnFirstThread VM sin suerte. Estoy en Cocoa de 64 bits, pero también probé Cocoa de 32 bits.

Cuando se trata de Carbono me sale el siguiente error:

 
Invalid memory access of location 00000020 eip=9c 

Al depurar en la clase Display puedo ver que la Muestra [] array sólo contiene referencias nulas.

+0

Funciona en Windows? De Verdad? Tendré que intentarlo ... – andyczerwonka

Respuesta

2

Puedo confirmar que ejecutamos con éxito SWT Carbon en Mac OS X en su propio ciclo de evento iniciado por un paquete de activación, por lo que es definitivamente posible. Esto está utilizando -XstartOnFirstThread al iniciar la máquina virtual.

Pero, con cacao SWT (64 bits), veo el mismo error :(

Parece que, a pesar de la forma en que nos encontramos carbono SWT trabajado, probablemente no era kosher: estábamos conduciendo el evento pasa por otro hilo, no el principal como se supone que debes hacerlo. En Cocoa SWT, esto ya no funciona, y probablemente fue una práctica poco fiable.

Puedo solucionar los errores del grupo de subprocesos con el siguiente truco antes de crear la pantalla (adaptado del constructor del dispositivo Cocoa SWT):

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(); 
    } 

Sin embargo, el ciclo de eventos que sigue cuelga (es decir el display.readAndDispatch() /display.sleep() dance). Sospecho que simplemente no está leyendo eventos de IU debido a que no es el hilo principal.

No estoy seguro de si hay una forma kosher de arreglar esto. En mi caso, controlamos el hilo principal de JVM que lanza OSGi, así que estoy jugando con la idea de agregar un gancho que pueda ejecutar el bucle de eventos SWT después del lanzamiento de OSGi.

+0

¿Es posible obtener un código simple para ponerlo en funcionamiento? Y una configuración de inicio de trabajo? –

+0

Has entendido mi pregunta correctamente. El último comentario que dices es que estás buscando agregar un gancho para ejecutar el ciclo de eventos SWT. Creo que es compatible con la clase Display, una vez que haya creado la primera instancia en el hilo principal, los métodos estáticos funcionarán como se esperaba. Al menos si crees en los documentos. Desde mi entendimiento, entonces podrás llamar a Display.asyncExec (..) para ejecutar el código en el hilo del evento SWT ... así es como lo haces en Eclipse al menos. –

+0

Crear la instancia de pantalla en el hilo principal es la parte difícil. Utilizamos una clase genérica de "arranque" que inicia el marco OSGi, y no tiene idea sobre SWT o incluso el acceso a las clases, ya que en realidad las carga el paquete SWT. Mi idea es agregar un tipo de gancho genérico al código de arranque, que el paquete SWT utilizará para ejecutar su bucle por el hilo principal. El truco es hacer esto limpiamente ... –

0

Este código se ve muy extraño ... ¿se supone que es un plugin de Eclipse? ¿Que estás tratando de hacer? Supongo que está intentando crear un complemento RCP con una interfaz de usuario. Si es así, aquí está la respuesta: no hagas eso. Su Activador OSGi no se hace responsable de crear el ciclo de evento de visualización SWT.

Crea una extensión de aplicación en tu plugin.xml para crear declarativamente SWT bootstrap. Se verá algo como esto:

<extension 
     id="application" 
     point="org.eclipse.core.runtime.applications"> 
     <application> 
     <run 
       class="com.yourcompany.foo.Application"> 
     </run> 
     </application> 
    </extension> 

A continuación, cree la clase Application (llamar lo que quieras) a ser algo como esto:

public class Application implements IApplication { 

    /* (non-Javadoc) 
    * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext) 
    */ 
    public Object start(IApplicationContext context) { 
     Display display = PlatformUI.createDisplay(); 
     try { 
      int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor()); 
      if (returnCode == PlatformUI.RETURN_RESTART) { 
       return IApplication.EXIT_RESTART; 
      } 
      return IApplication.EXIT_OK; 
     } finally { 
      display.dispose(); 
     } 
    } 

    /* (non-Javadoc) 
    * @see org.eclipse.equinox.app.IApplication#stop() 
    */ 
    public void stop() { 
     final IWorkbench workbench = PlatformUI.getWorkbench(); 
     if (workbench == null) 
      return; 
     final Display display = workbench.getDisplay(); 
     display.syncExec(new Runnable() { 
      public void run() { 
       if (!display.isDisposed()) 
        workbench.close(); 
      } 
     }); 
    } 
} 

Obviamente asegúrese de que tiene los plugins SWT (org. eclipse.ui) disponible en su Manifiesto, así como en el tiempo de ejecución.

Espero que ayude.

+1

No, no estoy tratando de crear un plugin de Eclipse. Estoy tratando de usar SWT en un entorno OSGi sin Eclipse RCP. Sé que Workbench en RCP es responsable de crear la pantalla y que se realiza en el hilo principal antes de que se activen los complementos. AFAIK debería ser posible crear la pantalla en cualquier hilo, siempre que se use como el hilo de la interfaz de usuario después de eso. Del doc: "En SWT, el subproceso que crea una instancia de pantalla se distingue como el subproceso de interfaz de usuario para esa pantalla." –

+0

Sin embargo, aprendí que Mac OS X requiere que el hilo sea el hilo 0. Eso podría explicar por qué funciona en Windows pero no en Mac. Sin embargo, no sé cómo resolverlo ... –

+0

Quiere SWT sin RCP pero quiere OSGi - parece extraño. RCP es básicamente SWT y OSGi con algunos otros complementos que no tiene que usar si no los quiere. – andyczerwonka

1

Tuve el problema de que tan pronto como se llamaba "display.sleep()" la ventana congelaba la aplicación. Si alguien más tiene el mismo problema, la solución que funcionó para mí fue agregar: -XstartOnFirstThread a la VM en el momento de la ejecución.

yo estaba tratando de hacer que el trabajo de software Areca Backup en mi Mac, y sé de su trabajo :)

Mi sistema es: MacOsX Snow Leopard 10.6.2

adiós, Daniel W.

1

Tuve el mismo problema y lo resolví agregando -d32 y -XstartOnFirstThread

Cuestiones relacionadas