View Javadoc

    1   /***************************************************************************************
    2    * Copyright (c) Jonas Bon?r, Alexandre Vasseur. All rights reserved.                 *
    3    * http://aspectwerkz.codehaus.org                                                    *
    4    * ---------------------------------------------------------------------------------- *
    5    * The software in this package is published under the terms of the LGPL license      *
    6    * a copy of which has been included with this distribution in the license.txt file.  *
    7    **************************************************************************************/
    8   package org.codehaus.aspectwerkz.hook;
    9
    10  import com.sun.jdi.VirtualMachine;
    11  import com.sun.jdi.Bootstrap;
    12  import com.sun.jdi.connect.AttachingConnector;
    13  import com.sun.jdi.connect.Connector;
    14  import com.sun.jdi.connect.IllegalConnectorArgumentsException;
    15
    16  import java.util.Map;
    17  import java.util.Iterator;
    18  import java.io.IOException;
    19
    20  /***
    21   * Isolation of JDWP dependancies to Plug online mode in a running / remote VM.
    22   * See Plug.
    23   *
    24   * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur</a>
    25   */
    26  public class JDWPPlug {
    27
    28      /***
    29       * transport jdwp option
    30       */
    31      private final static String TRANSPORT_JDWP = "transport";
    32
    33      /***
    34       * address jdwp option
    35       */
    36      private final static String ADDRESS_JDWP = "address";
    37
    38      /***
    39       * Connects to a remote JVM using the jdwp options specified in jdwp
    40       *
    41       * @param jdwp
    42       * @return VirtualMachine or null if failure
    43       * @throws Exception
    44       */
    45      private VirtualMachine connect(Map jdwp) throws Exception {
    46          String transport = (String) jdwp.get(TRANSPORT_JDWP);
    47          String address = (String) jdwp.get(ADDRESS_JDWP);
    48          String name = null;
    49          if ("dt_socket".equals(transport)) {
    50              name = "com.sun.jdi.SocketAttach";
    51          } else if ("dt_shmem".equals(transport)) {
    52              name = "com.sun.jdi.SharedMemoryAttach";
    53          }
    54          AttachingConnector connector = null;
    55          for (Iterator i = Bootstrap.virtualMachineManager().attachingConnectors().iterator(); i.hasNext();) {
    56              AttachingConnector aConnector = (AttachingConnector) i.next();
    57              if (aConnector.name().equals(name)) {
    58                  connector = aConnector;
    59                  break;
    60              }
    61          }
    62          if (connector == null) {
    63              throw new Exception("no AttachingConnector for transport: " + transport);
    64          }
    65          Map args = connector.defaultArguments();
    66          if ("dt_socket".equals(transport)) {
    67              ((Connector.Argument) args.get("port")).setValue(address);
    68          } else if ("dt_shmem".equals(transport)) {
    69              ((Connector.Argument) args.get("name")).setValue(address);
    70          }
    71          try {
    72              VirtualMachine vm = connector.attach(args);
    73              return vm;
    74          } catch (IllegalConnectorArgumentsException e) {
    75              System.err.println("failed to attach to VM (" + transport + ", " + address + "):");
    76              e.printStackTrace();
    77              for (Iterator i = e.argumentNames().iterator(); i.hasNext();) {
    78                  System.err.println("wrong or missing argument - " + i.next());
    79              }
    80              return null;
    81          } catch (IOException e) {
    82              System.err.println("failed to attach to VM (" + transport + ", " + address + "):");
    83              e.printStackTrace();
    84              return null;
    85          }
    86      }
    87
    88      /***
    89       * Resume the remote JVM, without hotswapping classes
    90       *
    91       * @param jdwp
    92       * @throws Exception
    93       */
    94      public void resume(Map jdwp) throws Exception {
    95          VirtualMachine vm = connect(jdwp);
    96          if (vm != null) {
    97              vm.resume();
    98              vm.dispose();
    99          }
    100     }
    101
    102     /***
    103      * Prints information about the remote JVM and resume
    104      *
    105      * @param jdwp
    106      * @throws Exception
    107      */
    108     public void info(Map jdwp) throws Exception {
    109         VirtualMachine vm = connect(jdwp);
    110         if (vm != null) {
    111             System.out.println("java.vm.name = " + vm.name());
    112             System.out.println("java.version = " + vm.version());
    113             System.out.println(vm.description());
    114             vm.resume();
    115             vm.dispose();
    116         }
    117     }
    118
    119     /***
    120      * Hotswaps the java.lang.ClassLoader of the remote JVM and resume
    121      *
    122      * @param jdwp
    123      * @throws Exception
    124      */
    125     public void hotswap(Map jdwp) throws Exception {
    126         // @todo check it works at runtime not suspended
    127         VirtualMachine vm = ClassLoaderPatcher.hotswapClassLoader(
    128                 System.getProperty(
    129                         ProcessStarter.CL_PRE_PROCESSOR_CLASSNAME_PROPERTY,
    130                         org.codehaus.aspectwerkz.hook.impl.ClassLoaderPreProcessorImpl.class.getName()
    131                 ), (String) jdwp
    132                             .get(TRANSPORT_JDWP), (String) jdwp.get(ADDRESS_JDWP)
    133         );
    134         if (vm != null) {
    135             vm.resume();
    136             vm.dispose();
    137         }
    138     }
    139
    140
    141 }