VisualVM does it really nice, each full main class name is displayed in the left side-bar navigation. How are these names retrieved? The Attach API offers all running JVMs with a display name, however, some display names seem a little bit bloated, for instance Eclipse:
C:\Program Files\Eclipse\plugins/org.eclipse.equinox.launcher_1.1.0.v20100507.jar -os win32 -ws win32 -arch x86_64 -showsplash -launcher C:\Program Files\Eclipse\eclipse.exe -name Eclipse --launcher.library C:\Program Files\Eclipse\plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.1.R36x_v20100810\eclipse_1309.dll -startup C:\Program Files\Eclipse\plugins/org.eclipse.equinox.launcher_1.1.0.v20100507.jar -exitdata 1084_58 -product org.eclipse.epp.package.jee.product -vm C:\Windows\system32\javaw.exe -vmargs -Dosgi.requiredJavaVersion=1.5 -Xms40m -Xmx512m -XX:MaxPermSize=256m -jar C:\Program Files\Eclipse\plugins/org.eclipse.equinox.launcher_1.1.0.v20100507.jar
Where VisualVM shortens it with: org.eclipse.equinox.launcher.Main
How do they retrieve it? From the current JVM its easy to obtain all threads main classes.
After looking at the VisualVM source it does something like this:
MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost("//localhost");
List<MonitoredVm> monitoredVms = new ArrayList<MonitoredVm>();
Set<Integer> vms = monitoredHost.activeVms();
for (Integer vm : vms) {
monitoredVms.add(monitoredHost.getMonitoredVm(new VmIdentifier(vm.toString())));
}
for (MonitoredVm monitoredVm : monitoredVms) {
System.out.println(MonitoredVmUtil.commandLine(monitoredVm))
}