diff --git a/TestProject/.classpath b/TestProject/.classpath index 8776106..980cac0 100644 --- a/TestProject/.classpath +++ b/TestProject/.classpath @@ -1,7 +1,7 @@ - + diff --git a/TestProject/lib/traceagent.jar b/TestProject/lib/traceagent.jar index 914b1d1..7bb9377 100644 Binary files a/TestProject/lib/traceagent.jar and b/TestProject/lib/traceagent.jar differ diff --git a/org.intrace.agentloader/.classpath b/org.intrace.agentloader/.classpath new file mode 100644 index 0000000..f479401 --- /dev/null +++ b/org.intrace.agentloader/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.intrace.agentloader/.project b/org.intrace.agentloader/.project new file mode 100644 index 0000000..285a4ce --- /dev/null +++ b/org.intrace.agentloader/.project @@ -0,0 +1,17 @@ + + + org.intrace.agentloader + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/org.intrace.agentloader/.settings/org.eclipse.jdt.core.prefs b/org.intrace.agentloader/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..0b83909 --- /dev/null +++ b/org.intrace.agentloader/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Sat Apr 10 10:43:19 BST 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/org.intrace.agentloader/build.xml b/org.intrace.agentloader/build.xml new file mode 100644 index 0000000..e677299 --- /dev/null +++ b/org.intrace.agentloader/build.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.intrace.agentloader/src/org/intrace/agentloader/AgentLoader.java b/org.intrace.agentloader/src/org/intrace/agentloader/AgentLoader.java new file mode 100644 index 0000000..96497eb --- /dev/null +++ b/org.intrace.agentloader/src/org/intrace/agentloader/AgentLoader.java @@ -0,0 +1,101 @@ +package org.intrace.agentloader; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.List; + +import com.sun.tools.attach.VirtualMachine; +import com.sun.tools.attach.VirtualMachineDescriptor; + +/** + * Command line agent loader. + */ +public class AgentLoader +{ + /** + * Cmd line tool. + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception + { + BufferedReader readIn = new BufferedReader(new InputStreamReader(System.in)); + String inLine = ""; + while (!"quit".equals(inLine)) + { + System.out.print("Enter command [attach/quit]: "); + inLine = readIn.readLine(); + + if ("attach".equals(inLine)) + { + attachToVM(readIn); + } + } + } + + private static void attachToVM(BufferedReader xiReadIn) + { + try + { + listProcIDs(); + System.out.print("Choose VM: "); + String inLine = xiReadIn.readLine(); + if (!"".equals(inLine)) + { + VirtualMachine vm = VirtualMachine.attach(inLine); + System.out.println("Attached to: " + vm.id()); + + while (!"done".equals(inLine)) + { + System.out.print("Enter command [load/done]: "); + inLine = xiReadIn.readLine(); + + if ("load".equals(inLine)) + { + loadAgent(xiReadIn, vm); + } + } + vm.detach(); + System.out.println("Detatched from: " + vm.id()); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + private static void loadAgent(BufferedReader xiReadIn, VirtualMachine vm) throws Exception + { + System.out.print("Enter path to agent jar (blank for windows default): "); + String agentPath = xiReadIn.readLine(); + String defaultAgentPath = "../TestProject/lib/traceagent.jar"; + if ("".equals(agentPath)) + { + agentPath = defaultAgentPath; + } + System.out.println("Agent Options"); + System.out.println("Leave blank for default: [regex-dcl.*"); + System.out.println("After loading you can only enabled/disable trace"); + System.out.print("Enter agent options: "); + String agentOptions = xiReadIn.readLine(); + String defaultAgentOpt = "[regex-dcl.*"; + if ("".equals(agentOptions)) + { + agentOptions = defaultAgentOpt; + } + vm.loadAgent(agentPath, agentOptions); + System.out.println("Loaded agent into: " + vm.toString()); + } + + private static void listProcIDs() + { + System.out.println("============== Begin List =============="); + List vmList = VirtualMachine.list(); + for (VirtualMachineDescriptor vm : vmList) + { + System.out.println(vm.displayName() + ":" + vm.id()); + } + System.out.println("============== End List =============="); + } +} diff --git a/org.intrace/.classpath b/org.intrace/.classpath index 6934935..4f15d8b 100644 --- a/org.intrace/.classpath +++ b/org.intrace/.classpath @@ -4,7 +4,6 @@ - diff --git a/org.intrace/build.xml b/org.intrace/build.xml index 7b5439e..5bc48c8 100644 --- a/org.intrace/build.xml +++ b/org.intrace/build.xml @@ -44,21 +44,10 @@ - - - - - - - - - - - - + @@ -69,7 +58,7 @@ - + diff --git a/org.intrace/src/org/intrace/agent/InstrumentedMethodWriter.java b/org.intrace/src/org/intrace/agent/InstrumentedMethodWriter.java index 7d715b8..d6575cc 100644 --- a/org.intrace/src/org/intrace/agent/InstrumentedMethodWriter.java +++ b/org.intrace/src/org/intrace/agent/InstrumentedMethodWriter.java @@ -16,7 +16,7 @@ import org.objectweb.asm.Type; */ public class InstrumentedMethodWriter extends MethodAdapter { - private static final String HELPER_CLASS = "gb/instrument/agent/AgentHelper"; + private static final String HELPER_CLASS = "org/intrace/agent/AgentHelper"; private final String className; private final String methodName; private final String methodDescriptor; diff --git a/org.intrace/src/org/intrace/client/gui/ClientStrings.java b/org.intrace/src/org/intrace/client/gui/ClientStrings.java new file mode 100644 index 0000000..b0a0230 --- /dev/null +++ b/org.intrace/src/org/intrace/client/gui/ClientStrings.java @@ -0,0 +1,26 @@ +package org.intrace.client.gui; + +public class ClientStrings +{ + public static final String ENABLE_INSTR = "Enable Instrumentation"; + public static final String DISABLE_INSTR = "Disable Instrumentation"; + public static final String SET_CLASSREGEX = "Set Class Regex..."; + public static final String ENABLE_ALLOWJARS = "Enable JAR Instrumentation"; + public static final String DISABLE_ALLOWJARS = "Disable JAR Instrumentation"; + public static final String ENABLE_SAVECLASSES = "Save Instrumented Classes"; + public static final String DISABLE_SAVECLASSES = "Don't Save Classes"; + public static final String ENABLE_VERBOSEMODE = "Enable Verbose Mode"; + public static final String DISABLE_VERBOSEMODE = "Disable Verbose Mode"; + public static final String ENABLE_EE_TRACE = "Enable Entry/Exit Trace"; + public static final String DISABLE_EE_TRACE = "Disable Entry/Exit Trace"; + public static final String ENABLE_BRANCH_TRACE = "Enable Branch Trace"; + public static final String DISABLE_BRANCH_TRACE = "Disable Branch Trace"; + public static final String ENABLE_ARGS_TRACE = "Enable Args Trace"; + public static final String DISABLE_ARGS_TRACE = "Disable Args Trace"; + public static final String ENABLE_STDOUT_TRACE = "Enable StdOut Trace"; + public static final String DISABLE_STDOUT_TRACE = "Disable StdOut Trace"; + public static final String ENABLE_FILE_TRACE = "Enable File Trace"; + public static final String DISABLE_FILE_TRACE = "Disable File Trace"; + public static final String ENABLE_NETWORK_TRACE = "Enable Network Trace"; + public static final String DISABLE_NETWORK_TRACE = "Disable Network Trace"; +} diff --git a/org.intrace/src/org/intrace/client/gui/NewConnectionWindow.java b/org.intrace/src/org/intrace/client/gui/NewConnectionWindow.java new file mode 100644 index 0000000..2b7633d --- /dev/null +++ b/org.intrace/src/org/intrace/client/gui/NewConnectionWindow.java @@ -0,0 +1,185 @@ +package org.intrace.client.gui; + +import java.net.InetSocketAddress; +import java.net.Socket; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +public class NewConnectionWindow +{ + private Shell sShell = null; // @jve:decl-index=0:visual-constraint="10,10" + private Text addressText = null; + private Text portText = null; + private Label addressLabel = null; + private Label portLabel = null; + private Button connectButton = null; + private Label statusLabel = null; + + private NewConnectionWindow instanceRef = this; // @jve:decl-index=0: + + public void open() + { + createSShell(); + sShell.open(); + Display display = Display.getDefault(); + while (!sShell.isDisposed()) + { + if (!display.readAndDispatch()) + display.sleep(); + } + display.dispose(); + } + + public void show() + { + sShell.setVisible(true); + sShell.setFocus(); + } + + public void hide() + { + sShell.setVisible(false); + } + + /** + * This method initializes sShell + */ + private void createSShell() + { + GridData gridData11 = new GridData(); + gridData11.horizontalAlignment = org.eclipse.swt.layout.GridData.CENTER; + gridData11.widthHint = 400; + GridData gridData2 = new GridData(); + gridData2.widthHint = 400; + GridData gridData1 = new GridData(); + gridData1.widthHint = 400; + GridData gridData = new GridData(); + gridData.grabExcessHorizontalSpace = true; + gridData.widthHint = 200; + gridData.horizontalAlignment = org.eclipse.swt.layout.GridData.CENTER; + GridLayout gridLayout = new GridLayout(); + gridLayout.numColumns = 2; + sShell = new Shell(SWT.CLOSE | SWT.TITLE | SWT.MIN); + sShell.setText("Trace Client"); + sShell.setLayout(gridLayout); + sShell.setSize(new Point(475, 126)); + sShell.addShellListener(new org.eclipse.swt.events.ShellAdapter() + { + public void shellClosed(org.eclipse.swt.events.ShellEvent e) + { + sShell.dispose(); + } + }); + addressLabel = new Label(sShell, SWT.NONE); + addressLabel.setText("Address:"); + addressText = new Text(sShell, SWT.BORDER); + addressText.setText("localhost"); + addressText.setLayoutData(gridData1); + portLabel = new Label(sShell, SWT.NONE); + portLabel.setText("Port:"); + portText = new Text(sShell, SWT.BORDER); + portText.setText("9123"); + portText.setLayoutData(gridData2); + @SuppressWarnings("unused") + Label filler = new Label(sShell, SWT.NONE); + connectButton = new Button(sShell, SWT.NONE); + connectButton.setText("Connect"); + connectButton.setLayoutData(gridData); + Label filler1 = new Label(sShell, SWT.NONE); + filler1.setText("Status:"); + statusLabel = new Label(sShell, SWT.WRAP | SWT.LEFT); + statusLabel.setText("Enter Details Above"); + statusLabel.setLayoutData(gridData11); + connectButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter() + { + public void mouseUp(org.eclipse.swt.events.MouseEvent e) + { + String host = addressText.getText(); + String port = portText.getText(); + connectToAgent(host, port); + } + }); + } + + private void connectToAgent(final String host, final String port) + { + if (host.length() == 0) + { + sShell.getDisplay().asyncExec(new Runnable() + { + @Override + public void run() + { + statusLabel.setText("Please enter an address"); + } + }); + } + else if (port.length() == 0) + { + sShell.getDisplay().asyncExec(new Runnable() + { + @Override + public void run() + { + statusLabel.setText("Please enter a port"); + } + }); + } + else + { + sShell.getDisplay().asyncExec(new Runnable() + { + @Override + public void run() + { + statusLabel.setText("Connecting..."); + new Thread(new Runnable() + { + @Override + public void run() + { + final Socket socket = new Socket(); + String statusMessage; + try + { + socket.connect(new InetSocketAddress(host, Integer.valueOf(port))); + statusMessage = "Connected"; + sShell.getDisplay().asyncExec(new Runnable() + { + @Override + public void run() + { + hide(); + TraceWindow traceWindow = new TraceWindow(instanceRef, socket); + traceWindow.open(); + } + }); + } + catch (Exception e) + { + statusMessage = e.toString(); + } + final String statusMessageRef = statusMessage; + sShell.getDisplay().asyncExec(new Runnable() + { + @Override + public void run() + { + statusLabel.setText(statusMessageRef); + } + }); + } + }).start(); + } + }); + } + } +} diff --git a/org.intrace/src/org/intrace/client/gui/TraceClient.java b/org.intrace/src/org/intrace/client/gui/TraceClient.java index 065368e..4d51c5a 100644 --- a/org.intrace/src/org/intrace/client/gui/TraceClient.java +++ b/org.intrace/src/org/intrace/client/gui/TraceClient.java @@ -7,7 +7,7 @@ public class TraceClient */ public static void main(String[] args) { - ConnectionDetails enterConnectionDetails = new ConnectionDetails(); + NewConnectionWindow enterConnectionDetails = new NewConnectionWindow(); enterConnectionDetails.open(); } diff --git a/org.intrace/src/org/intrace/client/gui/TraceWindow.java b/org.intrace/src/org/intrace/client/gui/TraceWindow.java index f57092f..bdd0d11 100644 --- a/org.intrace/src/org/intrace/client/gui/TraceWindow.java +++ b/org.intrace/src/org/intrace/client/gui/TraceWindow.java @@ -2,17 +2,10 @@ package org.intrace.client.gui; import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; -import java.net.InetSocketAddress; +import java.net.InetAddress; import java.net.Socket; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; @@ -25,56 +18,32 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; +import org.intrace.client.gui.helper.ControlConnectionThread; +import org.intrace.client.gui.helper.NetworkTraceReceiverThread; +import org.intrace.client.gui.helper.ParsedSettingsData; public class TraceWindow -{ - private final String ENABLE_INSTR = "Enable Instrumentation"; - private final String DISABLE_INSTR = "Disable Instrumentation"; - - private final String SET_CLASSREGEX = "Set Class Regex..."; - - private final String ENABLE_ALLOWJARS = "Enable JAR Instrumentation"; - private final String DISABLE_ALLOWJARS = "Disable JAR Instrumentation"; - - private final String ENABLE_SAVECLASSES = "Save Instrumented Classes"; - private final String DISABLE_SAVECLASSES = "Don't Save Classes"; - - private final String ENABLE_VERBOSEMODE = "Enable Verbose Mode"; - private final String DISABLE_VERBOSEMODE = "Disable Verbose Mode"; - - private final String ENABLE_EE_TRACE = "Enable Entry/Exit Trace"; - private final String DISABLE_EE_TRACE = "Disable Entry/Exit Trace"; - - private final String ENABLE_BRANCH_TRACE = "Enable Branch Trace"; - private final String DISABLE_BRANCH_TRACE = "Disable Branch Trace"; - - private final String ENABLE_ARGS_TRACE = "Enable Args Trace"; - private final String DISABLE_ARGS_TRACE = "Disable Args Trace"; - - private final String ENABLE_STDOUT_TRACE = "Enable StdOut Trace"; - private final String DISABLE_STDOUT_TRACE = "Disable StdOut Trace"; - - private final String ENABLE_FILE_TRACE = "Enable File Trace"; - private final String DISABLE_FILE_TRACE = "Disable File Trace"; - - private final String ENABLE_NETWORK_TRACE = "Enable Network Trace"; - private final String DISABLE_NETWORK_TRACE = "Disable Network Trace"; - - private ParsedSettingsData settingsData = new ParsedSettingsData(new HashMap()); // @jve:decl-index=0: - private final ExecutorService asyncExecutor = Executors.newSingleThreadExecutor(); // @jve:decl-index=0: - private TraceWindow instanceWindowRef = this; +{ + // Window refs + private TraceWindow traceDialogRef = this; + private NewConnectionWindow newConnectionDialogRef; + // Network details + private InetAddress remoteAddress; private boolean networkTraceEnabled = false; - private NetworkTraceThread networkThread; - private final ReceiveThread receiveThread; + // Threads + private NetworkTraceReceiverThread networkTraceThread; + private final ControlConnectionThread controlThread; + + // Settings + private ParsedSettingsData settingsData = new ParsedSettingsData(new HashMap()); // @jve:decl-index=0: + + // UI Elements private Shell sShell = null; private Button toggleEntryExitButton = null; - private Button Disconnect = null; - private Text statusTextArea = null; - - private ConnectionDetails instanceRef; - private Socket socket; + private Button disconnectButton = null; + private Text statusTextArea = null; private Button toggleStdOutButton = null; private Button toggleBranchButton = null; private Button toggleArgsButton = null; @@ -90,12 +59,13 @@ public class TraceWindow private Button toggleVerboseMode = null; private Button toggleFileOutputButton = null; private Button toggleNetworkTraceButton = null; - public TraceWindow(ConnectionDetails instanceRef, Socket socket) + + public TraceWindow(NewConnectionWindow instanceRef, Socket socket) { - this.instanceRef = instanceRef; - this.socket = socket; - receiveThread = new ReceiveThread(socket); - receiveThread.start(); + this.newConnectionDialogRef = instanceRef; + this.remoteAddress = socket.getInetAddress(); + controlThread = new ControlConnectionThread(socket, this); + controlThread.start(); } /** @@ -133,12 +103,12 @@ public class TraceWindow sShell = new Shell(); sShell.setText("Trace Window"); sShell.setLayout(gridLayout); - sShell.setSize(new Point(500, 500)); + sShell.setSize(new Point(700, 500)); instrumentSettingsLabel = new Label(sShell, SWT.NONE); instrumentSettingsLabel.setText("Instrumentation Settings:"); createComposite(); toggleInstrumentEnabled = new Button(sShell, SWT.LEFT); - toggleInstrumentEnabled.setText(ENABLE_INSTR); + toggleInstrumentEnabled.setText(ClientStrings.ENABLE_INSTR); toggleInstrumentEnabled.setLayoutData(gridData31); toggleInstrumentEnabled .addMouseListener(new org.eclipse.swt.events.MouseAdapter() @@ -149,18 +119,18 @@ public class TraceWindow } }); setClassRegexButton = new Button(sShell, SWT.LEFT); - setClassRegexButton.setText(SET_CLASSREGEX); + setClassRegexButton.setText(ClientStrings.SET_CLASSREGEX); setClassRegexButton.setLayoutData(gridData41); setClassRegexButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter() { public void mouseUp(org.eclipse.swt.events.MouseEvent e) { RegexInput regexInput = new RegexInput(); - regexInput.open(instanceWindowRef, settingsData.classRegex); + regexInput.open(traceDialogRef, settingsData.classRegex); } }); toggleAllowJarInstru = new Button(sShell, SWT.LEFT); - toggleAllowJarInstru.setText(ENABLE_ALLOWJARS); + toggleAllowJarInstru.setText(ClientStrings.ENABLE_ALLOWJARS); toggleAllowJarInstru.setLayoutData(gridData5); toggleAllowJarInstru.addMouseListener(new org.eclipse.swt.events.MouseAdapter() { @@ -170,7 +140,7 @@ public class TraceWindow } }); toggleSaveClassFiles = new Button(sShell, SWT.LEFT); - toggleSaveClassFiles.setText(ENABLE_SAVECLASSES); + toggleSaveClassFiles.setText(ClientStrings.ENABLE_SAVECLASSES); toggleSaveClassFiles.setLayoutData(gridData6); toggleSaveClassFiles.addMouseListener(new org.eclipse.swt.events.MouseAdapter() { @@ -180,7 +150,7 @@ public class TraceWindow } }); toggleVerboseMode = new Button(sShell, SWT.LEFT); - toggleVerboseMode.setText(ENABLE_VERBOSEMODE); + toggleVerboseMode.setText(ClientStrings.ENABLE_VERBOSEMODE); toggleVerboseMode.setLayoutData(gridData7); toggleVerboseMode.addMouseListener(new org.eclipse.swt.events.MouseAdapter() { @@ -189,7 +159,7 @@ public class TraceWindow toggleSetting(settingsData.verboseMode, "[verbose-true", "[verbose-false"); } }); - sShell.setMinimumSize(new Point(500, 500)); + sShell.setMinimumSize(new Point(700, 500)); traceSettingsLabel = new Label(sShell, SWT.NONE); traceSettingsLabel.setText("Trace Settings:"); sShell.addShellListener(new org.eclipse.swt.events.ShellAdapter() @@ -197,12 +167,12 @@ public class TraceWindow public void shellClosed(org.eclipse.swt.events.ShellEvent e) { disconnect(); + newConnectionDialogRef.show(); sShell.dispose(); - asyncExecutor.shutdownNow(); } }); toggleEntryExitButton = new Button(sShell, SWT.LEFT); - toggleEntryExitButton.setText(ENABLE_EE_TRACE); + toggleEntryExitButton.setText(ClientStrings.ENABLE_EE_TRACE); toggleEntryExitButton.setLayoutData(gridData2); toggleEntryExitButton .addMouseListener(new org.eclipse.swt.events.MouseAdapter() @@ -213,7 +183,7 @@ public class TraceWindow } }); toggleBranchButton = new Button(sShell, SWT.LEFT); - toggleBranchButton.setText(ENABLE_BRANCH_TRACE); + toggleBranchButton.setText(ClientStrings.ENABLE_BRANCH_TRACE); toggleBranchButton.setLayoutData(gridData1); toggleBranchButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter() { @@ -223,7 +193,7 @@ public class TraceWindow } }); toggleArgsButton = new Button(sShell, SWT.LEFT); - toggleArgsButton.setText(ENABLE_ARGS_TRACE); + toggleArgsButton.setText(ClientStrings.ENABLE_ARGS_TRACE); toggleArgsButton.setLayoutData(gridData21); outputSettingsLabel = new Label(sShell, SWT.NONE); outputSettingsLabel.setText("Output Modes:"); @@ -235,13 +205,13 @@ public class TraceWindow } }); toggleStdOutButton = new Button(sShell, SWT.LEFT); - toggleStdOutButton.setText(ENABLE_STDOUT_TRACE); + toggleStdOutButton.setText(ClientStrings.ENABLE_STDOUT_TRACE); toggleStdOutButton.setLayoutData(gridData4); toggleFileOutputButton = new Button(sShell, SWT.LEFT); - toggleFileOutputButton.setText(ENABLE_FILE_TRACE); + toggleFileOutputButton.setText(ClientStrings.ENABLE_FILE_TRACE); toggleFileOutputButton.setLayoutData(gridData11); toggleNetworkTraceButton = new Button(sShell, SWT.LEFT); - toggleNetworkTraceButton.setText(ENABLE_NETWORK_TRACE); + toggleNetworkTraceButton.setText(ClientStrings.ENABLE_NETWORK_TRACE); toggleNetworkTraceButton.setLayoutData(gridData22); toggleNetworkTraceButton .addMouseListener(new org.eclipse.swt.events.MouseAdapter() @@ -268,10 +238,10 @@ public class TraceWindow toggleSetting(settingsData.stdOutEnabled, "[trace-stdout-true", "[trace-stdout-false"); } }); - Disconnect = new Button(sShell, SWT.LEFT); - Disconnect.setText("Disconnect"); - Disconnect.setLayoutData(gridData); - Disconnect.addMouseListener(new org.eclipse.swt.events.MouseAdapter() + disconnectButton = new Button(sShell, SWT.LEFT); + disconnectButton.setText("Disconnect"); + disconnectButton.setLayoutData(gridData); + disconnectButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter() { public void mouseUp(org.eclipse.swt.events.MouseEvent e) { @@ -306,17 +276,19 @@ public class TraceWindow { createSShell(); sShell.open(); - statusTextArea.append("Connected!\n"); - try - { - sendMessage("getsettings"); - } - catch (IOException e) - { - sShell.close(); - } + addMessage("*** Connected!"); + controlThread.sendMessage("getsettings"); } + public void disconnect() + { + controlThread.disconnect(); + if (networkTraceThread != null) + { + networkTraceThread.disconnect(); + } + } + private void toggleNetworkTrace() { sShell.getDisplay().asyncExec(new Runnable() @@ -325,42 +297,28 @@ public class TraceWindow public void run() { disableButtons(); - asyncExecutor.execute(new Runnable() - { - @Override - public void run() - { - try - { - if (!networkTraceEnabled) - { - sendMessage("[trace-network"); - String networkTracePortStr = receiveThread.getMessage(); - int networkTracePort = Integer.parseInt(networkTracePortStr); - networkThread = new NetworkTraceThread(networkTracePort); - networkThread.start(); - networkTraceEnabled = true; - } - else - { - networkThread.stop(); - networkTraceEnabled = false; - } - sShell.getDisplay().asyncExec(new Runnable() - { - @Override - public void run() - { - updateButtonText(); - } - }); - } - catch (IOException e) - { - sShell.close(); - } + if (!networkTraceEnabled) + { + controlThread.sendMessage("[trace-network"); + String networkTracePortStr = controlThread.getMessage(); + int networkTracePort = Integer.parseInt(networkTracePortStr); + try + { + networkTraceThread = new NetworkTraceReceiverThread(remoteAddress, networkTracePort, traceDialogRef); + networkTraceThread.start(); + networkTraceEnabled = true; } - }); + catch (IOException ex) + { + addMessage("*** Failed to setup network trace: " + ex.toString()); + } + } + else + { + networkTraceThread.disconnect(); + networkTraceEnabled = false; + } + updateButtonText(); } }); } @@ -372,23 +330,9 @@ public class TraceWindow @Override public void run() { - disableButtons(); - asyncExecutor.execute(new Runnable() - { - @Override - public void run() - { - try - { - sendMessage("[regex-" + regex); - sendMessage("getsettings"); - } - catch (IOException e) - { - sShell.close(); - } - } - }); + disableButtons(); + controlThread.sendMessage("[regex-" + regex); + controlThread.sendMessage("getsettings"); } }); } @@ -400,30 +344,16 @@ public class TraceWindow @Override public void run() { - disableButtons(); - asyncExecutor.execute(new Runnable() - { - @Override - public void run() - { - try - { - if (settingValue) - { - sendMessage(disableCommand); - } - else - { - sendMessage(enableCommand); - } - sendMessage("getsettings"); - } - catch (IOException e) - { - sShell.close(); - } - } - }); + disableButtons(); + if (settingValue) + { + controlThread.sendMessage(disableCommand); + } + else + { + controlThread.sendMessage(enableCommand); + } + controlThread.sendMessage("getsettings"); } }); } @@ -458,181 +388,44 @@ public class TraceWindow private void updateButtonText() { - statusTextArea.append("Got Settings...\n"); + addMessage("*** Latest Settings Received"); - chooseText(toggleInstrumentEnabled, settingsData.instrEnabled, ENABLE_INSTR, DISABLE_INSTR); - chooseText(toggleAllowJarInstru, settingsData.allowJarsToBeTraced, ENABLE_ALLOWJARS, DISABLE_ALLOWJARS); - chooseText(toggleSaveClassFiles, settingsData.saveTracedClassfiles, ENABLE_SAVECLASSES, DISABLE_SAVECLASSES); - chooseText(toggleVerboseMode, settingsData.verboseMode, ENABLE_VERBOSEMODE, DISABLE_VERBOSEMODE); - chooseText(toggleEntryExitButton, settingsData.entryExitEnabled, ENABLE_EE_TRACE, DISABLE_EE_TRACE); - chooseText(toggleBranchButton, settingsData.branchEnabled, ENABLE_BRANCH_TRACE, DISABLE_BRANCH_TRACE); - chooseText(toggleArgsButton, settingsData.argsEnabled, ENABLE_ARGS_TRACE, DISABLE_ARGS_TRACE); - chooseText(toggleStdOutButton, settingsData.stdOutEnabled, ENABLE_STDOUT_TRACE, DISABLE_STDOUT_TRACE); - chooseText(toggleFileOutputButton, settingsData.fileOutEnabled, ENABLE_FILE_TRACE, DISABLE_FILE_TRACE); - chooseText(toggleNetworkTraceButton, networkTraceEnabled, ENABLE_NETWORK_TRACE, DISABLE_NETWORK_TRACE); + chooseText(toggleInstrumentEnabled, settingsData.instrEnabled, ClientStrings.ENABLE_INSTR, ClientStrings.DISABLE_INSTR); + chooseText(toggleAllowJarInstru, settingsData.allowJarsToBeTraced, ClientStrings.ENABLE_ALLOWJARS, ClientStrings.DISABLE_ALLOWJARS); + chooseText(toggleSaveClassFiles, settingsData.saveTracedClassfiles, ClientStrings.ENABLE_SAVECLASSES, ClientStrings.DISABLE_SAVECLASSES); + chooseText(toggleVerboseMode, settingsData.verboseMode, ClientStrings.ENABLE_VERBOSEMODE, ClientStrings.DISABLE_VERBOSEMODE); + chooseText(toggleEntryExitButton, settingsData.entryExitEnabled, ClientStrings.ENABLE_EE_TRACE, ClientStrings.DISABLE_EE_TRACE); + chooseText(toggleBranchButton, settingsData.branchEnabled, ClientStrings.ENABLE_BRANCH_TRACE, ClientStrings.DISABLE_BRANCH_TRACE); + chooseText(toggleArgsButton, settingsData.argsEnabled, ClientStrings.ENABLE_ARGS_TRACE, ClientStrings.DISABLE_ARGS_TRACE); + chooseText(toggleStdOutButton, settingsData.stdOutEnabled, ClientStrings.ENABLE_STDOUT_TRACE, ClientStrings.DISABLE_STDOUT_TRACE); + chooseText(toggleFileOutputButton, settingsData.fileOutEnabled, ClientStrings.ENABLE_FILE_TRACE, ClientStrings.DISABLE_FILE_TRACE); + chooseText(toggleNetworkTraceButton, networkTraceEnabled, ClientStrings.ENABLE_NETWORK_TRACE, ClientStrings.DISABLE_NETWORK_TRACE); setClassRegexButton.setEnabled(true); + } + + public void setConfig(final Map settingsMap) + { + sShell.getDisplay().asyncExec(new Runnable() + { + @Override + public void run() + { + addMessage("*** Fetch Settings"); + settingsData = new ParsedSettingsData(settingsMap); + updateButtonText(); + } + }); } - private void disconnect() + public void addMessage(final String message) { - try - { - socket.close(); - } - catch (IOException e) - { - // Throw away - } - instanceRef.show(); - } - - private void sendMessage(String xiString) throws IOException - { - OutputStream out = socket.getOutputStream(); - ObjectOutputStream objOut = new ObjectOutputStream(out); - objOut.writeObject(xiString); - objOut.flush(); - } - - private class ReceiveThread implements Runnable - { - private final Socket receiveSocket; - private final BlockingQueue queuedMessages = new LinkedBlockingQueue(); - public ReceiveThread(Socket socket) - { - receiveSocket = socket; - } - - public void start() - { - Thread t = new Thread(this); - t.setDaemon(true); - t.setName("Network Receive Thread"); - t.start(); - } - - public String getMessage() - { - try + sShell.getDisplay().asyncExec(new Runnable() + { + @Override + public void run() { - return queuedMessages.take(); + statusTextArea.append(message + "\n"); } - catch (InterruptedException e) - { - return null; - } - } - - @SuppressWarnings("unchecked") - @Override - public void run() - { - try - { - while (true) - { - ObjectInputStream objIn = new ObjectInputStream(receiveSocket.getInputStream()); - Object receivedMessage = (Object)objIn.readObject(); - if (receivedMessage instanceof Map) - { - Map settingsMap = (Map)receivedMessage; - handleConfig(settingsMap); - } - else - { - String strMessage = (String)receivedMessage; - if (!"OK".equals(strMessage)) - { - queuedMessages.put(strMessage); - } - } - } - } - catch (Exception e) - { - e.printStackTrace(); - sShell.getDisplay().asyncExec(new Runnable() - { - @Override - public void run() - { - if (!sShell.isDisposed()) - { - sShell.close(); - } - } - }); - } - } - - private void handleConfig(final Map settingsMap) - { - sShell.getDisplay().asyncExec(new Runnable() - { - @Override - public void run() - { - statusTextArea.append("Fetching Settings...\n"); - settingsData = new ParsedSettingsData(settingsMap); - updateButtonText(); - } - }); - } - } - - private class NetworkTraceThread implements Runnable - { - private final Socket traceSocket; - public NetworkTraceThread(int networkTracePort) throws IOException - { - traceSocket = new Socket(); - traceSocket.connect(new InetSocketAddress(socket.getInetAddress(), networkTracePort)); - } - - public void start() - { - Thread t = new Thread(this); - t.setDaemon(true); - t.setName("Network Trace"); - t.start(); - } - - public void stop() - { - try - { - traceSocket.close(); - } - catch (IOException e) - { - // Throw away - } - } - - @Override - public void run() - { - try - { - ObjectInputStream objIn = new ObjectInputStream(traceSocket.getInputStream()); - while (true) - { - final String traceLine = (String)objIn.readObject(); - sShell.getDisplay().asyncExec(new Runnable() - { - @Override - public void run() - { - statusTextArea.append(traceLine + "\n"); - } - }); - } - } - catch (Exception e) - { - sShell.close(); - } - } - + }); } } diff --git a/org.intrace/src/org/intrace/client/gui/helper/ControlConnectionThread.java b/org.intrace/src/org/intrace/client/gui/helper/ControlConnectionThread.java new file mode 100644 index 0000000..46a70fd --- /dev/null +++ b/org.intrace/src/org/intrace/client/gui/helper/ControlConnectionThread.java @@ -0,0 +1,135 @@ +package org.intrace.client.gui.helper; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.util.Map; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import org.intrace.client.gui.TraceWindow; + +public class ControlConnectionThread implements Runnable +{ + private final Socket socket; + private final TraceWindow window; + private final BlockingQueue incomingMessages = new LinkedBlockingQueue(); + private final BlockingQueue outgoingMessages = new LinkedBlockingQueue(); + private final ControlConnectionSenderThread senderThread = new ControlConnectionSenderThread(); + private Thread sendThread; + + public ControlConnectionThread(Socket socket, TraceWindow window) + { + this.window = window; + this.socket = socket; + } + + public void start() + { + Thread receiveThread = new Thread(this); + receiveThread.setDaemon(true); + receiveThread.setName("Control Receive Thread"); + receiveThread.start(); + + sendThread = new Thread(senderThread); + sendThread.setDaemon(true); + sendThread.setName("Control Sender Thread"); + sendThread.start(); + } + + public String getMessage() + { + try + { + return incomingMessages.take(); + } + catch (InterruptedException e) + { + return null; + } + } + + @SuppressWarnings("unchecked") + @Override + public void run() + { + try + { + while (true) + { + ObjectInputStream objIn = new ObjectInputStream(socket.getInputStream()); + Object receivedMessage = (Object)objIn.readObject(); + if (receivedMessage instanceof Map) + { + Map settingsMap = (Map)receivedMessage; + window.setConfig(settingsMap); + } + else + { + String strMessage = (String)receivedMessage; + if (!"OK".equals(strMessage)) + { + incomingMessages.put(strMessage); + } + } + } + } + catch (Exception e) + { + window.disconnect(); + } + } + + public void disconnect() + { + if (sendThread != null) + { + sendThread.interrupt(); + } + try + { + socket.close(); + } + catch (IOException e) + { + // Throw away + } + } + + public void sendMessage(String xiString) + { + try + { + outgoingMessages.put(xiString); + } + catch (InterruptedException e1) + { + // Throw away + } + } + + private class ControlConnectionSenderThread implements Runnable + { + @Override + public void run() + { + try + { + while (true) + { + String message = outgoingMessages.take(); + OutputStream out = socket.getOutputStream(); + ObjectOutputStream objOut = new ObjectOutputStream(out); + objOut.writeObject(message); + objOut.flush(); + } + } + catch (Exception e) + { + window.disconnect(); + } + } + } +} diff --git a/org.intrace/src/org/intrace/client/gui/helper/NetworkTraceReceiverThread.java b/org.intrace/src/org/intrace/client/gui/helper/NetworkTraceReceiverThread.java new file mode 100644 index 0000000..e95d34d --- /dev/null +++ b/org.intrace/src/org/intrace/client/gui/helper/NetworkTraceReceiverThread.java @@ -0,0 +1,60 @@ +package org.intrace.client.gui.helper; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; + +import org.intrace.client.gui.TraceWindow; + +public class NetworkTraceReceiverThread implements Runnable +{ + private final Socket traceSocket; + private final TraceWindow window; + public NetworkTraceReceiverThread(InetAddress address, int networkTracePort, TraceWindow window) throws IOException + { + this.window = window; + traceSocket = new Socket(); + traceSocket.connect(new InetSocketAddress(address, networkTracePort)); + } + + public void start() + { + Thread t = new Thread(this); + t.setDaemon(true); + t.setName("Network Trace Receiver"); + t.start(); + } + + @Override + public void run() + { + try + { + ObjectInputStream objIn = new ObjectInputStream(traceSocket.getInputStream()); + while (true) + { + String traceLine = (String)objIn.readObject(); + window.addMessage(traceLine); + } + } + catch (Exception e) + { + disconnect(); + } + } + + public void disconnect() + { + try + { + traceSocket.close(); + } + catch (IOException e) + { + // Do nothing + } + } + +} diff --git a/org.intrace/src/org/intrace/client/gui/helper/ParsedSettingsData.java b/org.intrace/src/org/intrace/client/gui/helper/ParsedSettingsData.java new file mode 100644 index 0000000..5b3ca91 --- /dev/null +++ b/org.intrace/src/org/intrace/client/gui/helper/ParsedSettingsData.java @@ -0,0 +1,108 @@ +package org.intrace.client.gui.helper; + + +import java.util.Map; + +import org.intrace.agent.AgentConfigConstants; +import org.intrace.output.trace.TraceConfigConstants; + +public class ParsedSettingsData +{ + public final String classRegex; + public final boolean instrEnabled; + public final boolean saveTracedClassfiles; + public final boolean verboseMode; + public final boolean allowJarsToBeTraced; + + public final boolean entryExitEnabled; + public final boolean branchEnabled; + public final boolean argsEnabled; + public final boolean stdOutEnabled; + public final boolean fileOutEnabled; + public ParsedSettingsData(Map settingsMap) + { + classRegex = settingsMap.get(AgentConfigConstants.CLASS_REGEX); + + if ("true".equals(settingsMap.get(AgentConfigConstants.TRACING_ENABLED))) + { + instrEnabled = true; + } + else + { + instrEnabled = false; + } + + if ("true".equals(settingsMap.get(AgentConfigConstants.SAVE_TRACED_CLASSFILES))) + { + saveTracedClassfiles = true; + } + else + { + saveTracedClassfiles = false; + } + + if ("true".equals(settingsMap.get(AgentConfigConstants.VERBOSE_MODE))) + { + verboseMode = true; + } + else + { + verboseMode = false; + } + + if ("true".equals(settingsMap.get(AgentConfigConstants.ALLOW_JARS_TO_BE_TRACED))) + { + allowJarsToBeTraced = true; + } + else + { + allowJarsToBeTraced = false; + } + + if ("true".equals(settingsMap.get(TraceConfigConstants.ENTRY_EXIT))) + { + entryExitEnabled = true; + } + else + { + entryExitEnabled = false; + } + + if ("true".equals(settingsMap.get(TraceConfigConstants.BRANCH))) + { + branchEnabled = true; + } + else + { + branchEnabled = false; + } + + if ("true".equals(settingsMap.get(TraceConfigConstants.ARG))) + { + argsEnabled = true; + } + else + { + argsEnabled = false; + } + + if ("true".equals(settingsMap.get(TraceConfigConstants.STD_OUT))) + { + stdOutEnabled = true; + } + else + { + stdOutEnabled = false; + } + + if ("true".equals(settingsMap.get(TraceConfigConstants.FILE_OUT))) + { + fileOutEnabled = true; + } + else + { + fileOutEnabled = false; + } + } + +} diff --git a/org.intrace/src/org/intrace/output/trace/NetworkTraceSenderThread.java b/org.intrace/src/org/intrace/output/trace/NetworkTraceSenderThread.java new file mode 100644 index 0000000..a0c6118 --- /dev/null +++ b/org.intrace/src/org/intrace/output/trace/NetworkTraceSenderThread.java @@ -0,0 +1,85 @@ +package org.intrace.output.trace; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Set; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +public class NetworkTraceSenderThread implements Runnable +{ + private final ServerSocket networkSocket; + private final BlockingQueue outgoingTrace = new LinkedBlockingQueue(100); + private Set set; + + public NetworkTraceSenderThread(ServerSocket networkSocket) + { + this.networkSocket = networkSocket; + } + + public void start(Set set) + { + this.set = set; + + Thread networkThread = new Thread(this); + networkThread.setDaemon(true); + networkThread.setName("Network Trace Sender"); + networkThread.start(); + } + + private void stop() + { + try + { + networkSocket.close(); + } + catch (IOException e) + { + // Throw away + } + set.remove(this); + System.out.println("## Network Trace Disconnected"); + } + + public void queueTrace(String traceLine) + { + try + { + outgoingTrace.put(traceLine); + } + catch (InterruptedException e) + { + // Throw away + } + } + + @Override + public void run() + { + Socket traceSendingSocket; + try + { + traceSendingSocket = networkSocket.accept(); + try + { + ObjectOutputStream traceWriter = new ObjectOutputStream(traceSendingSocket.getOutputStream()); + while (true) + { + String traceLine = outgoingTrace.take(); + traceWriter.writeObject(traceLine); + } + } + catch (Exception e) + { + traceSendingSocket.close(); + throw e; + } + } + catch (Exception e1) + { + stop(); + } + } +} diff --git a/org.intrace/src/org/intrace/output/trace/TraceOutput.java b/org.intrace/src/org/intrace/output/trace/TraceOutput.java index ada186f..baa59c8 100644 --- a/org.intrace/src/org/intrace/output/trace/TraceOutput.java +++ b/org.intrace/src/org/intrace/output/trace/TraceOutput.java @@ -30,7 +30,7 @@ public class TraceOutput implements IOutput final TraceSettings traceSettings = new TraceSettings(""); - private Map traceThreads = new ConcurrentHashMap(); + private Map traceThreads = new ConcurrentHashMap(); public String getResponse(String args) { @@ -59,7 +59,7 @@ public class TraceOutput implements IOutput try { networkSocket = new ServerSocket(0); - NetworkTraceThread traceThread = new NetworkTraceThread(networkSocket); + NetworkTraceSenderThread traceThread = new NetworkTraceSenderThread(networkSocket); traceThreads.put(traceThread, new Object()); @@ -105,10 +105,10 @@ public class TraceOutput implements IOutput writeFileTrace(traceString); } - Set networkThreads = traceThreads.keySet(); + Set networkThreads = traceThreads.keySet(); if (networkThreads.size() > 0) { - for (NetworkTraceThread thread : networkThreads) + for (NetworkTraceSenderThread thread : networkThreads) { thread.queueTrace(traceString); }