メインクラスの為に

Windows で動作するJava main() クラスの為に、補助するものを用意してみた。
困ったことに、Eclipse での javaw 実行では、SIGTERM シグナル送信して受け取らせることができない。
つまり
    Runtime.getRuntime().addShutdownHook
で登録したスレッドの動作確認がEclipseでは困難である。

// main() クラスのための補助
public abstract class MainSupport{
   /** Object Lock wait */
   public static void waitLock(){
      Object lock = new Object();
      synchronized(lock){
         try{
         lock.wait();
         }catch(InterruptedException e){
         }
      }
   }
   /**
    * 停止フック登録
    * シグナル SIGTERM を受信した時、System.exit(int)が実行されたとき、
    * JVM 終了時に、引数で指定した Serviceのend()を逆の順序で実行する。
    * 逆の順序で実行されることに注意
    * @param services Serviceのコレクション
    */

   public static void setShutdownHook(Collection<Service> services){
      Runtime.getRuntime().addShutdownHook(new Thread(new _ShutdownHook(services)));
   }
   /* 停止フック */
   public static class _ShutdownHook implements Runnable{
      private ArrayList<Service> services;
      public _ShutdownHook(Collection<Service> services){
         this.services = new ArrayList<Service>(services);
         Collections.reverse(this.services);
      }
      @Override
      public void run(){
         // shutdown time exec
         for(Service service : this.services){
            service.end();
         }
      }
   }

   /**
    * 指定時間後に、JVM終了.
    */

   public static void proceedExit(long delay){
      new Timer().schedule(new _ExitProceed(),delay);
   }
   static class _ExitProceed extends TimerTask{
      @Override
      public void run(){
         System.exit(0);
      }
   }
}

-------------------------------
public interface ServiceFactory{
   public Collection<Service> create();
}
-------------------------------
public interface Service{
   public void start();
   public void end();
}

======== mainサンプル ============

public class Sample extends MainSupport{
   public static void main(String[] args){

      // ServiceFactory実装する factory を生成

      // Service インスタンス生成

      Collection<Service> services = factory.create();

      // shutdown フック登録
      setShutdownHook(services);

      // Service 処理開始
      for(Service service : services){
         service.start();
      }
      // Object Lock wait
      waitLock();
   }
}