001 package org.crsh.util; 002 003 import org.slf4j.Logger; 004 import org.slf4j.LoggerFactory; 005 006 import java.lang.reflect.Constructor; 007 import java.lang.reflect.InvocationHandler; 008 import java.lang.reflect.Method; 009 import java.lang.reflect.Proxy; 010 011 /** 012 * Use sun.misc.Handler proprietary API for handling INT signal. This class use reflection and does not 013 * import sun.misc.* package. 014 * 015 * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> 016 */ 017 public class InterruptHandler { 018 019 /** . */ 020 private final Runnable runnable; 021 022 /** . */ 023 private final Logger log = LoggerFactory.getLogger(InterruptHandler.class); 024 025 private final InvocationHandler handler = new InvocationHandler() { 026 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 027 Class<?>[] parameterTypes = method.getParameterTypes(); 028 if (method.getName().equals("hashCode") && parameterTypes.length == 0) { 029 return System.identityHashCode(runnable); 030 } else if (method.getName().equals("equals") && parameterTypes.length == 1 && parameterTypes[0] == Object.class) { 031 return runnable.equals(args[0]); 032 } else if (method.getName().equals("toString") && parameterTypes.length == 0) { 033 return runnable.toString(); 034 } else if (method.getName().equals("handle")) { 035 runnable.run(); 036 return null; 037 } else { 038 throw new UnsupportedOperationException("Method " + method + " not implemented"); 039 } 040 } 041 }; 042 043 public InterruptHandler(Runnable runnable) { 044 this.runnable = runnable; 045 } 046 047 public void install() { 048 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 049 Class<?> signalHandlerClass; 050 Class<?> signalClass; 051 Method handle; 052 Object INT; 053 try { 054 signalHandlerClass = cl.loadClass("sun.misc.SignalHandler"); 055 signalClass = cl.loadClass("sun.misc.Signal"); 056 handle = signalClass.getDeclaredMethod("handle", signalClass, signalHandlerClass); 057 Constructor ctor = signalClass.getConstructor(String.class); 058 INT = ctor.newInstance("INT"); 059 } 060 catch (Exception e) { 061 return; 062 } 063 064 // 065 Object proxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[]{signalHandlerClass}, handler); 066 067 // 068 try { 069 handle.invoke(null, INT, proxy); 070 } 071 catch (Exception e) { 072 log.error("Could not install signal handler", e); 073 } 074 } 075 }