Pregunta

¿Cómo instalo la señal lógica de manejo de sun.misc.Signal si y sólo si está disponible?

Fondo La primera generación de mi código, lo que supone la disponibilidad de manipulación de la señal, se veía algo como esto:

class MyApp {
    public static void main(String[] args) {
        ...
        Signal.handle(term_sig, new SignalHandler() {
            public void handle(Signal sig) { ... }
        });
        ...
    }
}

Creo entender cómo prueba de forma reflexiva para el uso y los gestores de señales -. Class.forName("sun.misc.Signal"), Signal.handle llamada reflexivamente, y así sucesivamente

Mi impulso fue simplemente crear una instancia de otra clase interna anónima con la clase SignalHandler obtenido de forma dinámica, pero creo que eso es sólo una ilusión de sintaxis.

¿Fue útil?

Solución

Es necesario utilizar un proxy dinámico para implementar la interfaz SignalHandler. El resto es la reflexión básico.

Actualizar

Así es como se hace. Nota, he omitido el try-catch que las necesidades para envolver todo esto

        Class<?> handlerCl = Class.forName("sun.misc.SignalHandler");
        Class<?> signalCl = Class.forName("sun.misc.Signal");

        Constructor signalCtor = signalCl.getConstructor(String.class);
        Method signalHandle = signalCl.getMethod("handle", signalCl, handlerCl);

        // Create a proxy class that implements SignalHandler
        Class<?> proxyClass = Proxy.getProxyClass(signalCl.getClassLoader(),
            handlerCl);

        // This is used by the instance of proxyClass to dispatch method calls
        InvocationHandler invHandler = new InvocationHandler()
        {
            public Object invoke(Object proxy,
                Method method, Object[] args) throws Throwable
            {
                // proxy is the SignalHandler's "this" rederence
                // method will be the handle(Signal) method
                // args[0] will be an instance of Signal
                // If you're using this object for multiple signals, you'll
                // you'll need to use the "getName" method to determine which
                // signal you have caught.
                return null;
            }
        };

        // Get the constructor and create an instance of proxyClass
        Constructor<?> proxyCtor = proxyClass.getConstructor(InvocationHandler.class);
        Object handler = proxyCtor.newInstance(invHandler);

        // Create the signal and call Signal.handle to bind handler to signal
        Object signal = signalCtor.newInstance("TERM");
        signalHandle.invoke(null, signal, handler);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top