gt:             log.error("Error on startup.", e);
context: /*   $Id$
   *
   *   Copyright 2008 Glencoe Software, Inc. All rights reserved.
   *   Use is subject to license terms supplied in LICENSE.txt
   */
  
  package ome.services.blitz;
  
  import java.io.File;
  import java.util.concurrent.locks.ReentrantLock;
  
  import ome.system.OmeroContext;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.log4j.xml.DOMConfigurator;
  import org.springframework.util.ResourceUtils;
  
  import sun.misc.Signal;
  import sun.misc.SignalHandler;
  
  /**
   * OMERO.blitz startup code. Replaces {@link Main} as the main application entry
   * point. Uses Sun-specific APIs to handle signals.
   */
  public class Entry {
  
      private final static Log log = LogFactory.getLog(Entry.class);
  
      /**
       * Return code status. Initially -1. On successful start, 0. > 1 on
       * exception.
       */
      int status = -1;
  
      /**
       * Name of the {@link OmeroContext} to
       */
      final String name;
  
      /**
       * Prevents multiple calls to {@link #shutdown()}
       */
      final ReentrantLock lock = new ReentrantLock();
  
      /**
       * Context for the OMERO application
       */
      volatile OmeroContext ctx = null;
  
      /**
       * {@link Ice.Communicator} which will be waited on.
       */
      volatile Ice.Communicator ic = null;
  
      /**
       * Entry point to the server. The first argument on the command line will be
       * used as the name for the {@link OmeroContext} via
       * {@link Main2#Main(String)}. Other options include:
       * 
       * -s Check status (all args passed to {@link Ice.Util.initialize(String[])}
       * 
       */
      public static void main(final String[] args) {
          configureLogging();
          String name = "OMERO.blitz";
          if (args != null && args.length > 0) {
              if ("-s".equals(args[0])) {
                  try {
                      new Status(args).run();
                  } catch (Throwable t) {
                      t.printStackTrace();
                      System.exit(1);
                  }
                  System.exit(0);
              }
              // Now we find the first non-"--Ice.Config" argument and
              // pass that to main(). The last --Ice.Config value will be
              // seen by the Ice.Communicator. The last non-Ice.Config argument
              // will be used as a beanRefContext lookup.
              for (String string : args) {
                  if (string.startsWith("--Ice.Config")) {
                      System.setProperty("ICE_CONFIG", string.substring(13));
                  } else {
                      name = string;
                  }
              }
          }
  
          final Entry instance = new Entry(name);
  
          SignalHandler handler = new SignalHandler() {
              public void handle(Signal sig) {
                  log.info(sig.getName() + ": Shutdown requested.");
                  instance.lock.lock();
                  try {
                      instance.status = sig.getNumber();
                      instance.shutdown(true);
                  } finally {
                      // As with the try/finally block around shutdown in the
                      // start method, execution should never reach this point.
                      // But just in case, future code changes should introduce
                      // an exception (and to make findbugs happy) we'll add the
                      // try/finally
                      instance.lock.unlock();
                  }
              }
          };
  
          registerSignal(handler, "INT");
          registerSignal(handler, "TERM");
          registerSignal(handler, "BREAK");
  
          instance.start();
      }
  
      private static void registerSignal(SignalHandler handler, String sig) {
          try {
              Signal.handle(new Signal(sig), handler);
          } catch (IllegalArgumentException iae) {
              // Ok. BREAK will not exist on non-Windows systems, for example.
          }
      }
  
      /**
       * Stores name of the {@link OmeroContext} which is to be used by this
       * instance.
       */
      public Entry(String name) {
          this.name = name;
      }
  
      /**
       * Most ome/omero classes use the {@link Log} and {@link LogFactory}
       * classes for logging. The underlying implementation, however, is
       * more complicated. To prevent a dependency on third party jars,
       * the Ice Logger prints to java.util.logging. Log4j is on the class-
       * path and so is used as the main logger. And slf4j is also bound
       * to log4j, which allows us to use the Slf4J java.util.logging bridge
       * to send JUL to log4j as well. In summary:
       * <pre>
       *
       *  Most classes --> commons logging
       *                       \
       *                        \------------> log4j
       *                        /
       *                 slf4j-/
       *                   ^
       * java.util.logging-|
       *      ^
       * Ice--|
       *
       * </pre>
       */
      public static void configureLogging() {
          try {
  
              org.slf4j.bridge.SLF4JBridgeHandler.install();
  
              String log4j_xml = System.getProperty("log4j.configuration", "");
              if (log4j_xml.length() == 0) {
                  File file = ResourceUtils.getFile("classpath:log4j.xml");
                  log4j_xml = file.getAbsolutePath();
              }
              DOMConfigurator.configureAndWatch(log4j_xml);
          } catch (Exception e) {
              String msg = "CANNOT INITIALIZE LOGGING";
              throw new RuntimeException(msg, e);
          }
      }
  
      /**
       * Obtains the {@link #name named} {@link OmeroContext}, creating it if
       * necessary, and then delegates to
       * {@link Ice.Communicator#waitForShutdown()} until either it is externally
       * shutdown, or until a signal is caught.
       */
      public void start() {
          try {
              log.info("Creating " + name + ". Please wait...");
  
              // TEMPORARY WORKAROUND
              String ICE_CONFIG = System.getProperty("ICE_CONFIG");
              
              // Parse out any omero.* properties from ICE_CONFIG
              // and set them in the System
              Ice.InitializationData id = new Ice.InitializationData();
              id.properties = Ice.Util.createProperties();
              if (ICE_CONFIG != null) {
                  id.properties.load(ICE_CONFIG);
                  for (String k : id.properties.getPropertiesForPrefix("omero").keySet()) {
                      System.setProperty(k, id.properties.getProperty(k));
                  }
              }
              
              ctx = OmeroContext.getInstance(name);
              if (ctx.containsBean("Ice.Communicator")) {
                  ic = (Ice.Communicator) ctx.getBean("Ice.Communicator");
              } else {
                  // TODO This should be adapted to work for any process
                  // that doesn't need to add servants. Here "Indexer" could
                  // be replaced by omero.name or similar.
                  ic = Ice.Util.initialize(id);
                  String adapterName = ctx.getBean("adapterName", String.class);
                  Ice.ObjectAdapter oa = ic.createObjectAdapter(adapterName);
                  oa.activate();
              }
              log.info(name + " now accepting connections.");
              ic.waitForShutdown();
              status = 0;
          } catch (Ice.LocalException e) {
  