001: /**************************************************************************************
002: * Copyright (c) Jonas Bon?r, Alexandre Vasseur. All rights reserved. *
003: * http://aspectwerkz.codehaus.org *
004: * ---------------------------------------------------------------------------------- *
005: * The software in this package is published under the terms of the LGPL license *
006: * a copy of which has been included with this distribution in the license.txt file. *
007: **************************************************************************************/package org.codehaus.aspectwerkz.hook;
008:
009: import com.sun.jdi.VirtualMachine;
010: import com.sun.jdi.Bootstrap;
011: import com.sun.jdi.connect.AttachingConnector;
012: import com.sun.jdi.connect.Connector;
013: import com.sun.jdi.connect.IllegalConnectorArgumentsException;
014:
015: import java.util.Map;
016: import java.util.Iterator;
017: import java.io.IOException;
018:
019: /**
020: * Isolation of JDWP dependancies to Plug online mode in a running / remote VM.
021: * See Plug.
022: *
023: * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur</a>
024: */
025: public class JDWPPlug {
026:
027: /**
028: * transport jdwp option
029: */
030: private final static String TRANSPORT_JDWP = "transport";
031:
032: /**
033: * address jdwp option
034: */
035: private final static String ADDRESS_JDWP = "address";
036:
037: /**
038: * Connects to a remote JVM using the jdwp options specified in jdwp
039: *
040: * @param jdwp
041: * @return VirtualMachine or null if failure
042: * @throws Exception
043: */
044: private VirtualMachine connect(Map jdwp) throws Exception {
045: String transport = (String) jdwp.get(TRANSPORT_JDWP);
046: String address = (String) jdwp.get(ADDRESS_JDWP);
047: String name = null;
048: if ("dt_socket".equals(transport)) {
049: name = "com.sun.jdi.SocketAttach";
050: } else if ("dt_shmem".equals(transport)) {
051: name = "com.sun.jdi.SharedMemoryAttach";
052: }
053: AttachingConnector connector = null;
054: for (Iterator i = Bootstrap.virtualMachineManager()
055: .attachingConnectors().iterator(); i.hasNext();) {
056: AttachingConnector aConnector = (AttachingConnector) i
057: .next();
058: if (aConnector.name().equals(name)) {
059: connector = aConnector;
060: break;
061: }
062: }
063: if (connector == null) {
064: throw new Exception("no AttachingConnector for transport: "
065: + transport);
066: }
067: Map args = connector.defaultArguments();
068: if ("dt_socket".equals(transport)) {
069: ((Connector.Argument) args.get("port")).setValue(address);
070: } else if ("dt_shmem".equals(transport)) {
071: ((Connector.Argument) args.get("name")).setValue(address);
072: }
073: try {
074: VirtualMachine vm = connector.attach(args);
075: return vm;
076: } catch (IllegalConnectorArgumentsException e) {
077: System.err.println("failed to attach to VM (" + transport
078: + ", " + address + "):");
079: e.printStackTrace();
080: for (Iterator i = e.argumentNames().iterator(); i.hasNext();) {
081: System.err.println("wrong or missing argument - "
082: + i.next());
083: }
084: return null;
085: } catch (IOException e) {
086: System.err.println("failed to attach to VM (" + transport
087: + ", " + address + "):");
088: e.printStackTrace();
089: return null;
090: }
091: }
092:
093: /**
094: * Resume the remote JVM, without hotswapping classes
095: *
096: * @param jdwp
097: * @throws Exception
098: */
099: public void resume(Map jdwp) throws Exception {
100: VirtualMachine vm = connect(jdwp);
101: if (vm != null) {
102: vm.resume();
103: vm.dispose();
104: }
105: }
106:
107: /**
108: * Prints information about the remote JVM and resume
109: *
110: * @param jdwp
111: * @throws Exception
112: */
113: public void info(Map jdwp) throws Exception {
114: VirtualMachine vm = connect(jdwp);
115: if (vm != null) {
116: System.out.println("java.vm.name = " + vm.name());
117: System.out.println("java.version = " + vm.version());
118: System.out.println(vm.description());
119: vm.resume();
120: vm.dispose();
121: }
122: }
123:
124: /**
125: * Hotswaps the java.lang.ClassLoader of the remote JVM and resume
126: *
127: * @param jdwp
128: * @throws Exception
129: */
130: public void hotswap(Map jdwp) throws Exception {
131: // @todo check it works at runtime not suspended
132: VirtualMachine vm = ClassLoaderPatcher
133: .hotswapClassLoader(
134: System
135: .getProperty(
136: ProcessStarter.CL_PRE_PROCESSOR_CLASSNAME_PROPERTY,
137: org.codehaus.aspectwerkz.hook.impl.ClassLoaderPreProcessorImpl.class
138: .getName()),
139: (String) jdwp.get(TRANSPORT_JDWP),
140: (String) jdwp.get(ADDRESS_JDWP));
141: if (vm != null) {
142: vm.resume();
143: vm.dispose();
144: }
145: }
146:
147: }
|