diff --git a/InTrace-VisualVM/build.xml b/InTrace-VisualVM/build.xml
new file mode 100644
index 0000000..c4f7265
--- /dev/null
+++ b/InTrace-VisualVM/build.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+ Builds, tests, and runs the project org.intrace.visualvm.
+
+
diff --git a/InTrace-VisualVM/manifest.mf b/InTrace-VisualVM/manifest.mf
new file mode 100644
index 0000000..8dc9c8d
--- /dev/null
+++ b/InTrace-VisualVM/manifest.mf
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+OpenIDE-Module: org.intrace.visualvm
+OpenIDE-Module-Install: org/intrace/visualvm/Installer.class
+OpenIDE-Module-Layer: org/intrace/visualvm/layer.xml
+OpenIDE-Module-Localizing-Bundle: org/intrace/visualvm/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+OpenIDE-Module-Name: InTrace: VisualVM Plugin
diff --git a/InTrace-VisualVM/nbproject/build-impl.xml b/InTrace-VisualVM/nbproject/build-impl.xml
new file mode 100644
index 0000000..65a9e86
--- /dev/null
+++ b/InTrace-VisualVM/nbproject/build-impl.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/InTrace-VisualVM/nbproject/platform.properties b/InTrace-VisualVM/nbproject/platform.properties
new file mode 100644
index 0000000..6221694
--- /dev/null
+++ b/InTrace-VisualVM/nbproject/platform.properties
@@ -0,0 +1,5 @@
+cluster.path=\
+ ${nbplatform.active.dir}/platform:\
+ ${nbplatform.active.dir}/profiler:\
+ ${nbplatform.active.dir}/visualvm
+nbplatform.active=VisualVM_1.2.2
diff --git a/InTrace-VisualVM/nbproject/project.properties b/InTrace-VisualVM/nbproject/project.properties
new file mode 100644
index 0000000..9fc050a
--- /dev/null
+++ b/InTrace-VisualVM/nbproject/project.properties
@@ -0,0 +1,3 @@
+cp.extra=${tools.jar}
+javac.source=1.6
+javac.compilerargs=-Xlint -Xlint:-serial
diff --git a/InTrace-VisualVM/nbproject/project.xml b/InTrace-VisualVM/nbproject/project.xml
new file mode 100644
index 0000000..acd7dd1
--- /dev/null
+++ b/InTrace-VisualVM/nbproject/project.xml
@@ -0,0 +1,72 @@
+
+
+ org.netbeans.modules.apisupport.project
+
+
+ org.intrace.visualvm
+
+
+
+ com.sun.tools.visualvm.application
+
+
+
+ 0-1
+ 1.2
+
+
+
+ com.sun.tools.visualvm.attach
+
+ 0-1
+ 1.1
+
+
+
+ com.sun.tools.visualvm.core
+
+
+
+ 0-1
+ 1.3
+
+
+
+ com.sun.tools.visualvm.host
+
+
+
+ 0-1
+ 1.0
+
+
+
+ com.sun.tools.visualvm.tools
+
+
+
+ 0-1
+ 1.1
+
+
+
+ org.openide.modules
+
+
+
+ 7.13.1
+
+
+
+ org.openide.util
+
+
+
+ 7.31.1.1
+
+
+
+
+
+
+
diff --git a/InTrace-VisualVM/release/modules/ext/intrace-agent.jar b/InTrace-VisualVM/release/modules/ext/intrace-agent.jar
new file mode 100644
index 0000000..3531c86
Binary files /dev/null and b/InTrace-VisualVM/release/modules/ext/intrace-agent.jar differ
diff --git a/InTrace-VisualVM/release/modules/ext/intrace-client-cui.jar b/InTrace-VisualVM/release/modules/ext/intrace-client-cui.jar
new file mode 100644
index 0000000..8d9e3c7
Binary files /dev/null and b/InTrace-VisualVM/release/modules/ext/intrace-client-cui.jar differ
diff --git a/InTrace-VisualVM/release/modules/ext/intrace-client-gui-linux.jar b/InTrace-VisualVM/release/modules/ext/intrace-client-gui-linux.jar
new file mode 100644
index 0000000..615c195
Binary files /dev/null and b/InTrace-VisualVM/release/modules/ext/intrace-client-gui-linux.jar differ
diff --git a/InTrace-VisualVM/release/modules/ext/intrace-client-gui-win.jar b/InTrace-VisualVM/release/modules/ext/intrace-client-gui-win.jar
new file mode 100644
index 0000000..ee11b78
Binary files /dev/null and b/InTrace-VisualVM/release/modules/ext/intrace-client-gui-win.jar differ
diff --git a/InTrace-VisualVM/src/org/intrace/visualvm/Bundle.properties b/InTrace-VisualVM/src/org/intrace/visualvm/Bundle.properties
new file mode 100644
index 0000000..3fb8fa9
--- /dev/null
+++ b/InTrace-VisualVM/src/org/intrace/visualvm/Bundle.properties
@@ -0,0 +1 @@
+OpenIDE-Module-Name=InTrace: Visual VM Plugin
diff --git a/InTrace-VisualVM/src/org/intrace/visualvm/Installer.java b/InTrace-VisualVM/src/org/intrace/visualvm/Installer.java
new file mode 100644
index 0000000..217ced7
--- /dev/null
+++ b/InTrace-VisualVM/src/org/intrace/visualvm/Installer.java
@@ -0,0 +1,20 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.intrace.visualvm;
+
+import org.intrace.visualvm.view.InTraceViewProvider;
+import org.openide.modules.ModuleInstall;
+
+/**
+ * Manages a module's lifecycle. Remember that an installer is optional and
+ * often not needed at all.
+ */
+public class Installer extends ModuleInstall {
+
+ @Override
+ public void restored() {
+ InTraceViewProvider.initialize();
+ }
+}
diff --git a/InTrace-VisualVM/src/org/intrace/visualvm/Locator.java b/InTrace-VisualVM/src/org/intrace/visualvm/Locator.java
new file mode 100644
index 0000000..11f100f
--- /dev/null
+++ b/InTrace-VisualVM/src/org/intrace/visualvm/Locator.java
@@ -0,0 +1,50 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.intrace.visualvm;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import org.openide.modules.InstalledFileLocator;
+
+/**
+ *
+ * @author mch50
+ */
+public class Locator {
+
+ public static final String agentPath;
+ public static final String clientPath;
+
+ static {
+ File locatedFile = InstalledFileLocator.getDefault().locate("modules/ext/intrace-agent.jar", null, false); // NOI18N
+ if (locatedFile != null) {
+ agentPath = locatedFile.getAbsolutePath();
+ } else {
+ agentPath = null;
+ }
+
+ String osName = System.getProperty("os.name", "unknown");
+ if (osName.contains("Windows")) {
+ locatedFile = InstalledFileLocator.getDefault().locate("modules/ext/intrace-client-gui-win.jar", null, false); // NOI18N
+ if (locatedFile != null) {
+ clientPath = locatedFile.getAbsolutePath();
+ } else {
+ clientPath = null;
+ }
+ }
+ else if (osName.contains("Linux")) {
+ locatedFile = InstalledFileLocator.getDefault().locate("modules/ext/intrace-client-gui-linux.jar", null, false); // NOI18N
+ if (locatedFile != null) {
+ clientPath = locatedFile.getAbsolutePath();
+ } else {
+ clientPath = null;
+ }
+ }
+ else {
+ clientPath = null;
+ }
+ }
+}
diff --git a/InTrace-VisualVM/src/org/intrace/visualvm/actions/Bundle.properties b/InTrace-VisualVM/src/org/intrace/visualvm/actions/Bundle.properties
new file mode 100644
index 0000000..eea8ea3
--- /dev/null
+++ b/InTrace-VisualVM/src/org/intrace/visualvm/actions/Bundle.properties
@@ -0,0 +1 @@
+InTraceApplicationAction.title=InTrace Application...
\ No newline at end of file
diff --git a/InTrace-VisualVM/src/org/intrace/visualvm/actions/InTraceApplicationAction.java b/InTrace-VisualVM/src/org/intrace/visualvm/actions/InTraceApplicationAction.java
new file mode 100644
index 0000000..32edbd4
--- /dev/null
+++ b/InTrace-VisualVM/src/org/intrace/visualvm/actions/InTraceApplicationAction.java
@@ -0,0 +1,43 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.intrace.visualvm.actions;
+
+import com.sun.tools.visualvm.application.Application;
+import com.sun.tools.visualvm.application.jvm.Jvm;
+import com.sun.tools.visualvm.application.jvm.JvmFactory;
+import com.sun.tools.visualvm.core.ui.DataSourceWindowManager;
+import com.sun.tools.visualvm.core.ui.actions.SingleDataSourceAction;
+import java.awt.event.ActionEvent;
+import org.intrace.visualvm.impl.InTraceDataSource;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author mch50
+ */
+public class InTraceApplicationAction extends SingleDataSourceAction {
+
+ @Override
+ protected void actionPerformed(Application app, ActionEvent actionEvent) {
+ InTraceDataSource dataSource = new InTraceDataSource(app);
+ DataSourceWindowManager.sharedInstance().openDataSource(dataSource);
+ }
+
+ @Override
+ protected boolean isEnabled(Application app) {
+ Jvm jvm = JvmFactory.getJVMFor(app);
+ return app.isLocalApplication() && jvm.isAttachable() && jvm.isGetSystemPropertiesSupported();
+ }
+
+ public static synchronized InTraceApplicationAction newInstance() {
+ return new InTraceApplicationAction();
+ }
+
+ private InTraceApplicationAction() {
+ super(Application.class);
+ putValue(NAME, NbBundle.getMessage(InTraceApplicationAction.class, "InTraceApplicationAction.title")); // NOI18N
+ }
+}
diff --git a/InTrace-VisualVM/src/org/intrace/visualvm/impl/InTraceDataSource.java b/InTrace-VisualVM/src/org/intrace/visualvm/impl/InTraceDataSource.java
new file mode 100644
index 0000000..e51f683
--- /dev/null
+++ b/InTrace-VisualVM/src/org/intrace/visualvm/impl/InTraceDataSource.java
@@ -0,0 +1,23 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.intrace.visualvm.impl;
+
+import com.sun.tools.visualvm.application.Application;
+import com.sun.tools.visualvm.core.datasource.DataSource;
+
+/**
+ *
+ * @author mch50
+ */
+public class InTraceDataSource extends DataSource {
+
+ public final Application app;
+
+ public InTraceDataSource(Application app) {
+ super(app);
+ this.app = app;
+ }
+}
diff --git a/InTrace-VisualVM/src/org/intrace/visualvm/impl/InTraceLoader.java b/InTrace-VisualVM/src/org/intrace/visualvm/impl/InTraceLoader.java
new file mode 100644
index 0000000..1abbf2f
--- /dev/null
+++ b/InTrace-VisualVM/src/org/intrace/visualvm/impl/InTraceLoader.java
@@ -0,0 +1,89 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.intrace.visualvm.impl;
+
+import com.sun.tools.attach.VirtualMachine;
+import com.sun.tools.visualvm.application.Application;
+import com.sun.tools.visualvm.application.jvm.Jvm;
+import com.sun.tools.visualvm.application.jvm.JvmFactory;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.intrace.visualvm.Locator;
+import org.openide.util.Exceptions;
+
+/**
+ *
+ * @author mch50
+ */
+public class InTraceLoader {
+
+ public static interface StatusHandler {
+
+ public void handleStatus(String statusLine);
+ }
+
+ public static void loadAgent(Application app, StatusHandler handler) {
+ Jvm jvm = JvmFactory.getJVMFor(app);
+ if (app.isLocalApplication() && jvm.isAttachable() && jvm.isGetSystemPropertiesSupported()) {
+ try {
+ VirtualMachine vm = VirtualMachine.attach(String.valueOf(app.getPid()));
+ handler.handleStatus("Attached to JVM (PID: " + app.getPid() + ")");
+ vm.loadAgent(Locator.agentPath, "");
+ handler.handleStatus("InTrace Agent loaded");
+ } catch (Exception ex) {
+ handler.handleStatus("Exception thrown:\n" + throwableToString(ex));
+ Exceptions.printStackTrace(ex);
+ }
+ }
+ }
+
+ public static void launchClient(final StatusHandler handler) {
+ Runnable launchClientThread = new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ List command = new ArrayList();
+ command.add("java");
+ command.add("-jar");
+ command.add(Locator.clientPath);
+
+ ProcessBuilder builder = new ProcessBuilder(command);
+
+ System.out.println("Directory : " + System.getenv("temp"));
+ builder.start();
+
+ handler.handleStatus("InTrace Client launched");
+ } catch (Exception ex) {
+ handler.handleStatus("Exception thrown:\n" + throwableToString(ex));
+ Exceptions.printStackTrace(ex);
+ }
+ }
+ };
+ new Thread(launchClientThread).start();
+ }
+
+ private static String throwableToString(Throwable throwable) {
+ StringBuilder throwToStr = new StringBuilder();
+ if (throwable == null) {
+ throwToStr.append("null");
+ } else {
+ StringWriter strWriter = new StringWriter();
+ PrintWriter writer = new PrintWriter(strWriter);
+ throwable.printStackTrace(writer);
+ throwToStr.append(strWriter.toString());
+ }
+ return throwToStr.toString();
+ }
+}
diff --git a/InTrace-VisualVM/src/org/intrace/visualvm/layer.xml b/InTrace-VisualVM/src/org/intrace/visualvm/layer.xml
new file mode 100644
index 0000000..035037b
--- /dev/null
+++ b/InTrace-VisualVM/src/org/intrace/visualvm/layer.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/InTrace-VisualVM/src/org/intrace/visualvm/view/InTraceView.java b/InTrace-VisualVM/src/org/intrace/visualvm/view/InTraceView.java
new file mode 100644
index 0000000..9fb6664
--- /dev/null
+++ b/InTrace-VisualVM/src/org/intrace/visualvm/view/InTraceView.java
@@ -0,0 +1,144 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.intrace.visualvm.view;
+
+import com.sun.tools.visualvm.core.ui.DataSourceView;
+import com.sun.tools.visualvm.core.ui.components.DataViewComponent;
+import java.awt.BorderLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.BorderFactory;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import org.intrace.visualvm.Locator;
+import org.intrace.visualvm.impl.InTraceLoader;
+import org.intrace.visualvm.impl.InTraceDataSource;
+import org.openide.util.Utilities;
+
+/**
+ *
+ * @author mch50
+ */
+public class InTraceView extends DataSourceView {
+
+ private final InTraceDataSource application;
+
+ private JTextArea textArea;
+ private DataViewComponent dvc;
+
+ //Reusing an image from the sources:
+ private static final String IMAGE_PATH = "com/sun/tools/visualvm/coredump/resources/coredump.png"; // NOI18N
+
+ public InTraceView(InTraceDataSource application) {
+ super(application, "InTrace", new ImageIcon(Utilities.loadImage(IMAGE_PATH, true)).getImage(), 60, false);
+ this.application = application;
+ }
+
+ @Override
+ protected DataViewComponent createComponent() {
+
+ //Data area for master view:
+ JPanel generalDataArea = new JPanel();
+ generalDataArea.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));
+ generalDataArea.setOpaque(false);
+
+ JButton loadAgentButton = new JButton("Load InTrace Agent");
+ loadAgentButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ InTraceLoader.loadAgent(application.app, new InTraceLoader.StatusHandler() {
+ @Override
+ public void handleStatus(String statusLine) {
+ appendText(statusLine);
+ }
+ });
+ }
+ });
+
+ JButton launchClient = new JButton("Launch InTrace Client");
+ launchClient.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ InTraceLoader.launchClient(new InTraceLoader.StatusHandler() {
+ @Override
+ public void handleStatus(String statusLine) {
+ appendText(statusLine);
+ }
+ });
+ }
+ });
+
+ JButton clearStatus = new JButton("Clear Status Text");
+ clearStatus.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ clearText();
+ }
+ });
+
+ generalDataArea.add(loadAgentButton);
+ generalDataArea.add(launchClient);
+ generalDataArea.add(clearStatus);
+
+ //Master view:
+ DataViewComponent.MasterView masterView = new DataViewComponent.MasterView
+ ("Control", null, generalDataArea);
+
+ //Configuration of master view:
+ DataViewComponent.MasterViewConfiguration masterConfiguration =
+ new DataViewComponent.MasterViewConfiguration(false);
+
+ //Add the master view and configuration view to the component:
+ dvc = new DataViewComponent(masterView, masterConfiguration);
+
+ //Add detail view to the component:
+
+ JPanel statusArea = new JPanel();
+ statusArea.setOpaque(false);
+ statusArea.setLayout(new BorderLayout());
+
+ textArea = new JTextArea(5, 20);
+ JScrollPane scrollPane = new JScrollPane(textArea);
+ scrollPane.setVerticalScrollBarPolicy(
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ textArea.setEditable(false);
+ textArea.setLineWrap(true);
+ textArea.setMargin(new Insets(10,10,10,10));
+
+ statusArea.add(scrollPane, BorderLayout.CENTER);
+
+ dvc.addDetailsView(new DataViewComponent.DetailsView(
+ "Status", null, 10, statusArea, null), DataViewComponent.BOTTOM_LEFT);
+
+ appendText("Agent Path: " + Locator.agentPath);
+ appendText("Client Path: " + Locator.clientPath);
+ if (Locator.clientPath == null) {
+ appendText("Warning: The Client is only supported on Windows " +
+ "and Linux");
+ }
+ else {
+ appendText("Ready");
+ }
+
+ return dvc;
+ }
+
+ private void appendText(String str) {
+ if (textArea != null) {
+ textArea.append(str + "\n");
+ }
+ }
+
+ private void clearText() {
+ if (textArea != null) {
+ textArea.setText("");
+ }
+ }
+}
diff --git a/InTrace-VisualVM/src/org/intrace/visualvm/view/InTraceViewProvider.java b/InTrace-VisualVM/src/org/intrace/visualvm/view/InTraceViewProvider.java
new file mode 100644
index 0000000..648543a
--- /dev/null
+++ b/InTrace-VisualVM/src/org/intrace/visualvm/view/InTraceViewProvider.java
@@ -0,0 +1,39 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.intrace.visualvm.view;
+
+import com.sun.tools.visualvm.core.ui.DataSourceView;
+import com.sun.tools.visualvm.core.ui.DataSourceViewProvider;
+import com.sun.tools.visualvm.core.ui.DataSourceViewsManager;
+import org.intrace.visualvm.impl.InTraceDataSource;
+
+/**
+ *
+ * @author mch50
+ */
+public class InTraceViewProvider extends DataSourceViewProvider {
+
+ private static DataSourceViewProvider instance = new InTraceViewProvider();
+
+ @Override
+ public boolean supportsViewFor(InTraceDataSource application) {
+ //Always shown:
+ return true;
+ }
+
+ @Override
+ public synchronized DataSourceView createView(final InTraceDataSource application) {
+ return new InTraceView(application);
+ }
+
+ public static void initialize() {
+ DataSourceViewsManager.sharedInstance().addViewProvider(instance, InTraceDataSource.class);
+ }
+
+ static void unregister() {
+ DataSourceViewsManager.sharedInstance().removeViewProvider(instance);
+ }
+}
diff --git a/binaries/jars/latest_development/org-intrace-visualvm.nbm b/binaries/jars/latest_development/org-intrace-visualvm.nbm
new file mode 100644
index 0000000..c2c1bd1
Binary files /dev/null and b/binaries/jars/latest_development/org-intrace-visualvm.nbm differ