All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gemstone.gemfire.internal.process.ProcessUtils Maven / Gradle / Ivy

There is a newer version: 2.0-BETA
Show newest version
/*
 * Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License. You
 * may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License. See accompanying
 * LICENSE file.
 */
package com.gemstone.gemfire.internal.process;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.management.ManagementFactory;

import com.gemstone.gemfire.internal.util.IOUtils;

/**
 * Utility operations for processes such as identifying the process id (pid).
 * 
 * @author Kirk Lund
 * @since 7.0
 */
public final class ProcessUtils {
  
  private static InternalProcessUtils internal = initializeInternalProcessUtils();
  
  private ProcessUtils() {}
  
  /**
   * Returns the pid for this process.
   * 
   * @throws PidUnavailableException if parsing the pid from the name of the
   * RuntimeMXBean fails
   * 
   * @see java.lang.management.RuntimeMXBean#getName()
   */
  public static int identifyPid() throws PidUnavailableException {
    return identifyPid(ManagementFactory.getRuntimeMXBean().getName());
  }
  
  /**
   * Returns the pid for this process using the specified name from 
   * RuntimeMXBean.
   * 
   * @throws PidUnavailableException if parsing the pid from the RuntimeMXBean 
   * name fails
   */
  public static int identifyPid(final String name) throws PidUnavailableException {
    try {
      final int index = name.indexOf("@");
      if (index < 0) {
        throw new PidUnavailableException("Unable to parse pid from " + name);
      }
      return Integer.valueOf(name.substring(0, index));
    } catch (NumberFormatException e) {
      throw new PidUnavailableException("Unable to parse pid from " + name, e);
    }
  }
  
  /**
   * Returns true if a process identified by the process id is
   * currently running on this host machine.
   * 
   * @param pid process id to check for
   * @return true if the pid matches a currently running process
   */
  public static boolean isProcessAlive(final int pid) {
    return internal.isProcessAlive(pid);
  }
  
  /**
   * Returns true if a process identified by the process id was
   * running on this host machine and has been terminated by this operation.
   * 
   * @param pid process id
   * @return true if the process was terminated by this operation
   */
  public static boolean killProcess(final int pid) {
    return internal.killProcess(pid);
  }

  public static int readPid(final File pidFile) throws IOException {
    BufferedReader reader = null;
    try {
      reader = new BufferedReader(new FileReader(pidFile));
      return Integer.parseInt(reader.readLine());
    }
    finally {
      IOUtils.close(reader);
    }
  }
  
  private static InternalProcessUtils initializeInternalProcessUtils() {
    // 1) prefer Attach because it filters out non-JVM processes
    try {
      Class.forName("com.sun.tools.attach.VirtualMachine");
      Class.forName("com.sun.tools.attach.VirtualMachineDescriptor");
      return new AttachProcessUtils();
    } catch (ClassNotFoundException e) {
      // fall through
    } catch (LinkageError e) {
      // fall through
    }
    
    // 2) try NativeCalls but make sure it doesn't throw UnsupportedOperationException
    try {
      // TODO: get rid of Class.forName usage if NativeCalls always safely loads
      Class.forName("com.gemstone.gemfire.internal.shared.NativeCalls");
      NativeProcessUtils inst = new NativeProcessUtils();
      boolean result = inst.isProcessAlive(identifyPid());
      if (result) {
        return inst;
      }
    } catch (ClassNotFoundException e) {
      // fall through
    } catch (LinkageError e) {
      // fall through
    } catch (PidUnavailableException e) {
      // fall through TODO:KIRK log warning??
    } catch (UnsupportedOperationException e) {
      // fall through
    }
    
    // 3) TODO: log warning and then proceed with no-op
    return new InternalProcessUtils() {
      @Override
      public boolean isProcessAlive(int pid) {
        return false;
      }
      @Override
      public boolean killProcess(int pid) {
        return false;
      }
    };
  }
  
  /**
   * Defines the SPI for ProcessUtils
   */
  interface InternalProcessUtils {
    public boolean isProcessAlive(int pid);
    public boolean killProcess(int pid);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy