2009-02-05 23 views
7

Tengo una aplicación RCP que utiliza una conexión a una base de datos en memoria. Hay una circunstancia que, al cerrar Windows, la aplicación se cancela sin darle la oportunidad de cerrar la conexión a la base de datos.¿Cuál es la forma correcta de agregar un Shutdown Hook para una aplicación Eclipse RCP?

Investigué un poco y parece que agregar un gancho de apagado es la mejor manera de detectar este evento y hacer una limpieza en una aplicación Java. Sin embargo, ¿cuál es la forma correcta de procesar esto si tiene una aplicación RCP, posiblemente con varios editores abiertos?

Respuesta

1

He probado el siguiente código, que yo haga de mi IApplication implementador método start(), antes de la aplicación RCP es en realidad puso en marcha:

Runtime.getRuntime().addShutdownHook(new Thread() { 
    public void run() { 
     if (PlatformUI.isWorkbenchRunning()) { 
      PlatformUI.getWorkbench().close(); 
     } 
     logger.info("Shutdown request received"); 
     cleanup(); 
    } 
}); 

Cuando la limpieza() cierra la conexión a la base de datos. Cerrar debería solicitar a los usuarios que guarden si hay documentos abiertos.

3

Debe anular el método preShutdown en su clase que extiende WorkbenachAdvisor. Devuelve falso para detener el proceso de cierre o true para continuar.

+1

Tengo eso también, pero si la JVM termina esta sección no se llama. Por ejemplo, como resultado de System.exit() –

5

Nota: este blog entry sugiere la siguiente aplicación para el gancho de cierre:

El código de parada se debe ejecutar en el hilo de interfaz de usuario y no se debe ejecutar si el banco está cerrado por otros medios. Todos los editores sucios se guardan automáticamente. Esto evita que el usuario que está probablemente en casa duerma cuando su computadora se apaga. Finalmente, el banco de trabajo está cerrado.

(por lo que no exactamente su escenario, pero la aplicación sigue siendo interesante porque muestra cómo ejecutar dentro del hilo de interfaz de usuario)

private class ShutdownHook extends Thread { 
    @Override 
    public void run() { 
    try { 
     final IWorkbench workbench = PlatformUI.getWorkbench(); 
     final Display display = PlatformUI.getWorkbench() 
             .getDisplay(); 
     if (workbench != null && !workbench.isClosing()) { 
     display.syncExec(new Runnable() { 
      public void run() { 
      IWorkbenchWindow [] workbenchWindows = 
          workbench.getWorkbenchWindows(); 
      for(int i = 0;i < workbenchWindows.length;i++) { 
       IWorkbenchWindow workbenchWindow = 
             workbenchWindows[i]; 
       if (workbenchWindow == null) { 
       // SIGTERM shutdown code must access 
       // workbench using UI thread!! 
       } else { 
       IWorkbenchPage[] pages = workbenchWindow 
              .getPages(); 
       for (int j = 0; j < pages.length; j++) { 
        IEditorPart[] dirtyEditors = pages[j] 
              .getDirtyEditors(); 
        for (int k = 0; k < dirtyEditors.length; k++) { 
        dirtyEditors[k] 
          .doSave(new NullProgressMonitor()); 
        } 
       } 
       } 
      } 
      } 
     }); 
     display.syncExec(new Runnable() { 
      public void run() { 
      workbench.close(); 
      } 
     }); 
     } 
    } catch (IllegalStateException e) { 
     // ignore 
    } 
    } 
} 

Se establece, como usted ha dicho, en IA aplicación:

public class IPEApplication implements IApplication { 
    public Object start(IApplicationContext context) throws Exception { 
    final Display display = PlatformUI.createDisplay(); 
    Runtime.getRuntime().addShutdownHook(new ShutdownHook()); } 
    // start workbench... 
    } 
} 
Cuestiones relacionadas