Package net.djpowell.liverepl.client

Source Code of net.djpowell.liverepl.client.Main

package net.djpowell.liverepl.client;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.UnknownHostException;
import java.util.logging.Logger;

import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;

public class Main {

    // bind to localhost to keep things more secure
    public static final InetAddress LOCALHOST;
    static {
        try {
            LOCALHOST = InetAddress.getByAddress(new byte[] {127, 0, 0, 1});
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        }
    }
   
    private static int getFreePort(InetAddress host) {
        // open a server socket on a random port, then close it
        // so that we can tell the server to listen on that port
        // and we will know which port to connect to
        try {
            ServerSocket server = new ServerSocket(0, 0, host);
            int port = server.getLocalPort();
            server.close();
            return port;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
   
    private static void listPids() {
        System.out.println();
        System.out.println("liverepl");
        System.out.println("Usage: liverepl <pid>");
        System.out.println();
        System.out.println("List of Java processes");
        System.out.format("%1$-6s %2$.60s%n", "pid", "Details");
        for (VirtualMachineDescriptor vmd : VirtualMachine.list()) {
            System.out.format("%1$-6s %2$.60s%n", vmd.id(), vmd.displayName());
        }
    }
   
    public static void main(String[] args) throws Exception {
        // Usage: <clojurepath> <agentjarpath> <serverjarpath> <jvmpid> <classloaderid>
        if (args.length < 4) {
            listPids();
            System.exit(0);
        }
        String clojurepath = args[0];
        String agentpath = args[1];
        String serverpath = args[2];
        String pid = args[3];
        String classLoaderId;
        if (args.length < 5) {
            classLoaderId = "L";
            System.out.println();
            System.out.println("List of ClassLoaders for process #" + pid);
        } else {
            classLoaderId = args[4];
        }
       
        TRC.fine("Attaching to pid: " + pid);
        final VirtualMachine vm = VirtualMachine.attach(pid);
       
        int port = getFreePort(LOCALHOST);
        // start the agent, which will create the server socket, then return
        String agentArgs = String.valueOf(port) + "\n" + clojurepath + "\n" + serverpath + "\n" + classLoaderId;
        vm.loadAgent(agentpath, agentArgs);

        boolean listClassLoaders = "L".equals(classLoaderId);
        // start the code that will connect to the server socket
        Console.main(LOCALHOST, port, !listClassLoaders);

        // the server will shutdown when the client disconnects
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                try {
                    vm.detach();
                } catch (RuntimeException e) {
                    throw e;
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }
   
    private static final Logger TRC = Logger.getLogger(Main.class.getName());

}
TOP

Related Classes of net.djpowell.liverepl.client.Main

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.