Path: blob/master/src/jdk.jconsole/share/classes/sun/tools/jconsole/JConsole.java
40948 views
/*1* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.tools.jconsole;2627import java.awt.*;28import java.awt.event.*;29import java.beans.*;30import java.io.*;31import java.net.*;32import java.util.*;33import java.util.List;3435import javax.swing.*;36import javax.swing.border.*;37import javax.swing.event.*;38import javax.swing.plaf.*;39import javax.security.auth.login.FailedLoginException;40import javax.net.ssl.SSLHandshakeException;4142import com.sun.tools.jconsole.JConsolePlugin;4344import sun.net.util.IPAddressUtil;4546import static sun.tools.jconsole.Utilities.*;4748@SuppressWarnings("serial")49public class JConsole extends JFrame50implements ActionListener, InternalFrameListener {5152static /*final*/ boolean IS_GTK;53static /*final*/ boolean IS_WIN;5455static {56// Apply the system L&F if it is GTK or Windows, and57// the L&F is not specified using a system property.58if (System.getProperty("swing.defaultlaf") == null) {59String systemLaF = UIManager.getSystemLookAndFeelClassName();60if (systemLaF.equals("com.sun.java.swing.plaf.gtk.GTKLookAndFeel") ||61systemLaF.equals("com.sun.java.swing.plaf.windows.WindowsLookAndFeel")) {6263try {64UIManager.setLookAndFeel(systemLaF);65} catch (Exception e) {66System.err.println(Resources.format(Messages.JCONSOLE_COLON_, e.getMessage()));67}68}69}7071updateLafValues();72}737475static void updateLafValues() {76String lafName = UIManager.getLookAndFeel().getClass().getName();77IS_GTK = lafName.equals("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");78IS_WIN = lafName.equals("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");7980//BorderedComponent.updateLafValues();81}828384private static final String title =85Messages.JAVA_MONITORING___MANAGEMENT_CONSOLE;86public static final String ROOT_URL =87"service:jmx:";8889private static int updateInterval = 4000;90private static String pluginPath = "";9192private JMenuBar menuBar;93private JMenuItem hotspotMI, connectMI, exitMI;94private WindowMenu windowMenu;95private JMenuItem tileMI, cascadeMI, minimizeAllMI, restoreAllMI;96private JMenuItem userGuideMI, aboutMI;9798private JButton connectButton;99private JDesktopPane desktop;100private ConnectDialog connectDialog;101private CreateMBeanDialog createDialog;102103private ArrayList<VMInternalFrame> windows =104new ArrayList<VMInternalFrame>();105106private int frameLoc = 5;107static boolean debug;108109public JConsole(boolean hotspot) {110super(title);111112setRootPane(new FixedJRootPane());113setAccessibleDescription(this,114Messages.JCONSOLE_ACCESSIBLE_DESCRIPTION);115setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);116117menuBar = new JMenuBar();118setJMenuBar(menuBar);119120// TODO: Use Actions !121122JMenu connectionMenu = new JMenu(Messages.CONNECTION);123connectionMenu.setMnemonic(Resources.getMnemonicInt(Messages.CONNECTION));124menuBar.add(connectionMenu);125if(hotspot) {126hotspotMI = new JMenuItem(Messages.HOTSPOT_MBEANS_ELLIPSIS);127hotspotMI.setMnemonic(Resources.getMnemonicInt(Messages.HOTSPOT_MBEANS_ELLIPSIS));128hotspotMI.setAccelerator(KeyStroke.129getKeyStroke(KeyEvent.VK_H,130InputEvent.CTRL_DOWN_MASK));131hotspotMI.addActionListener(this);132connectionMenu.add(hotspotMI);133134connectionMenu.addSeparator();135}136137connectMI = new JMenuItem(Messages.NEW_CONNECTION_ELLIPSIS);138connectMI.setMnemonic(Resources.getMnemonicInt(Messages.NEW_CONNECTION_ELLIPSIS));139connectMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,140InputEvent.CTRL_DOWN_MASK));141connectMI.addActionListener(this);142connectionMenu.add(connectMI);143144connectionMenu.addSeparator();145146exitMI = new JMenuItem(Messages.EXIT);147exitMI.setMnemonic(Resources.getMnemonicInt(Messages.EXIT));148exitMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4,149InputEvent.ALT_DOWN_MASK));150exitMI.addActionListener(this);151connectionMenu.add(exitMI);152153154JMenu helpMenu = new JMenu(Messages.HELP_MENU_TITLE);155helpMenu.setMnemonic(Resources.getMnemonicInt(Messages.HELP_MENU_TITLE));156menuBar.add(helpMenu);157158if (AboutDialog.isBrowseSupported()) {159userGuideMI = new JMenuItem(Messages.HELP_MENU_USER_GUIDE_TITLE);160userGuideMI.setMnemonic(Resources.getMnemonicInt(Messages.HELP_MENU_USER_GUIDE_TITLE));161userGuideMI.addActionListener(this);162helpMenu.add(userGuideMI);163helpMenu.addSeparator();164}165aboutMI = new JMenuItem(Messages.HELP_MENU_ABOUT_TITLE);166aboutMI.setMnemonic(Resources.getMnemonicInt(Messages.HELP_MENU_ABOUT_TITLE));167aboutMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0));168aboutMI.addActionListener(this);169helpMenu.add(aboutMI);170}171172public JDesktopPane getDesktopPane() {173return desktop;174}175176public List<VMInternalFrame> getInternalFrames() {177return windows;178}179180private void createMDI() {181// Restore title - we now show connection name on internal frames182setTitle(title);183184Container cp = getContentPane();185Component oldCenter =186((BorderLayout)cp.getLayout()).187getLayoutComponent(BorderLayout.CENTER);188189windowMenu = new WindowMenu(Messages.WINDOW);190windowMenu.setMnemonic(Resources.getMnemonicInt(Messages.WINDOW));191// Add Window menu before Help menu192menuBar.add(windowMenu, menuBar.getComponentCount() - 1);193194desktop = new JDesktopPane();195desktop.setBackground(new Color(235, 245, 255));196197cp.add(desktop, BorderLayout.CENTER);198199if (oldCenter instanceof VMPanel) {200addFrame((VMPanel)oldCenter);201}202}203204private class WindowMenu extends JMenu {205VMInternalFrame[] windowMenuWindows = new VMInternalFrame[0];206int separatorPosition;207208// The width value of viewR is used to truncate long menu items.209// The rest are placeholders and are ignored for this purpose.210Rectangle viewR = new Rectangle(0, 0, 400, 20);211Rectangle textR = new Rectangle(0, 0, 0, 0);212Rectangle iconR = new Rectangle(0, 0, 0, 0);213214WindowMenu(String text) {215super(text);216217cascadeMI = new JMenuItem(Messages.CASCADE);218cascadeMI.setMnemonic(Resources.getMnemonicInt(Messages.CASCADE));219cascadeMI.addActionListener(JConsole.this);220add(cascadeMI);221222tileMI = new JMenuItem(Messages.TILE);223tileMI.setMnemonic(Resources.getMnemonicInt(Messages.TILE));224tileMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T,225InputEvent.CTRL_DOWN_MASK));226tileMI.addActionListener(JConsole.this);227add(tileMI);228229minimizeAllMI = new JMenuItem(Messages.MINIMIZE_ALL);230minimizeAllMI.setMnemonic(Resources.getMnemonicInt(Messages.MINIMIZE_ALL));231minimizeAllMI.addActionListener(JConsole.this);232add(minimizeAllMI);233234restoreAllMI = new JMenuItem(Messages.RESTORE_ALL);235restoreAllMI.setMnemonic(Resources.getMnemonicInt(Messages.RESTORE_ALL));236restoreAllMI.addActionListener(JConsole.this);237add(restoreAllMI);238239separatorPosition = getMenuComponentCount();240}241242private void add(VMInternalFrame vmIF) {243if (separatorPosition == getMenuComponentCount()) {244addSeparator();245}246247int index = -1;248int position = separatorPosition + 1;249int n = windowMenuWindows.length;250251for (int i = 0; i < n; i++) {252if (windowMenuWindows[i] != null) {253// Slot is in use, try next254position++;255} else {256// Found a free slot257index = i;258break;259}260}261262if (index == -1) {263// Create a slot at the end264VMInternalFrame[] newArray = new VMInternalFrame[n + 1];265System.arraycopy(windowMenuWindows, 0, newArray, 0, n);266windowMenuWindows = newArray;267index = n;268}269270windowMenuWindows[index] = vmIF;271272String indexString = "" + (index+1);273String vmName = vmIF.getVMPanel().getDisplayName();274// Maybe truncate menu item string and end with "..."275String text =276SwingUtilities.layoutCompoundLabel(this,277getGraphics().getFontMetrics(getFont()),278indexString + " " + vmName,279null, 0, 0, 0, 0,280viewR, iconR, textR, 0);281JMenuItem mi = new JMenuItem(text);282if (text.endsWith("...")) {283mi.setToolTipText(vmName);284}285286// Set mnemonic using last digit of number287int nDigits = indexString.length();288mi.setMnemonic(indexString.charAt(nDigits-1));289mi.setDisplayedMnemonicIndex(nDigits-1);290291mi.putClientProperty("JConsole.vmIF", vmIF);292mi.addActionListener(JConsole.this);293vmIF.putClientProperty("JConsole.menuItem", mi);294add(mi, position);295}296297private void remove(VMInternalFrame vmIF) {298for (int i = 0; i < windowMenuWindows.length; i++) {299if (windowMenuWindows[i] == vmIF) {300windowMenuWindows[i] = null;301}302}303JMenuItem mi = (JMenuItem)vmIF.getClientProperty("JConsole.menuItem");304remove(mi);305mi.putClientProperty("JConsole.vmIF", null);306vmIF.putClientProperty("JConsole.menuItem", null);307308if (separatorPosition == getMenuComponentCount() - 1) {309remove(getMenuComponent(getMenuComponentCount() - 1));310}311}312}313314public void actionPerformed(ActionEvent ev) {315Object src = ev.getSource();316if (src == hotspotMI) {317showCreateMBeanDialog();318}319320if (src == connectButton || src == connectMI) {321VMPanel vmPanel = null;322JInternalFrame vmIF = desktop.getSelectedFrame();323if (vmIF instanceof VMInternalFrame) {324vmPanel = ((VMInternalFrame)vmIF).getVMPanel();325}326String hostName = "";327String url = "";328if (vmPanel != null) {329hostName = vmPanel.getHostName();330if(vmPanel.getUrl() != null)331url = vmPanel.getUrl();332}333showConnectDialog(url, hostName, 0, null, null, null);334} else if (src == tileMI) {335tileWindows();336} else if (src == cascadeMI) {337cascadeWindows();338} else if (src == minimizeAllMI) {339for (VMInternalFrame vmIF : windows) {340try {341vmIF.setIcon(true);342} catch (PropertyVetoException ex) {343// Ignore344}345}346} else if (src == restoreAllMI) {347for (VMInternalFrame vmIF : windows) {348try {349vmIF.setIcon(false);350} catch (PropertyVetoException ex) {351// Ignore352}353}354} else if (src == exitMI) {355System.exit(0);356} else if (src == userGuideMI) {357AboutDialog.browseUserGuide(this);358} else if (src == aboutMI) {359AboutDialog.showAboutDialog(this);360} else if (src instanceof JMenuItem) {361JMenuItem mi = (JMenuItem)src;362VMInternalFrame vmIF = (VMInternalFrame)mi.363getClientProperty("JConsole.vmIF");364if (vmIF != null) {365try {366vmIF.setIcon(false);367vmIF.setSelected(true);368} catch (PropertyVetoException ex) {369// Ignore370}371vmIF.moveToFront();372}373}374}375376377public void tileWindows() {378int w = -1;379int h = -1;380int n = 0;381for (VMInternalFrame vmIF : windows) {382if (!vmIF.isIcon()) {383n++;384if (w == -1) {385try {386vmIF.setMaximum(true);387w = vmIF.getWidth();388h = vmIF.getHeight();389} catch (PropertyVetoException ex) {390// Ignore391}392}393}394}395if (n > 0 && w > 0 && h > 0) {396int rows = (int)Math.ceil(Math.sqrt(n));397int cols = n / rows;398if (rows * cols < n) cols++;399int x = 0;400int y = 0;401w /= cols;402h /= rows;403int col = 0;404for (VMInternalFrame vmIF : windows) {405if (!vmIF.isIcon()) {406try {407vmIF.setMaximum(n==1);408} catch (PropertyVetoException ex) {409// Ignore410}411if (n > 1) {412vmIF.setBounds(x, y, w, h);413}414if (col < cols-1) {415col++;416x += w;417} else {418col = 0;419x = 0;420y += h;421}422}423}424}425}426427public void cascadeWindows() {428int n = 0;429int w = -1;430int h = -1;431for (VMInternalFrame vmIF : windows) {432if (!vmIF.isIcon()) {433try {434vmIF.setMaximum(false);435} catch (PropertyVetoException ex) {436// Ignore437}438n++;439vmIF.pack();440if (w == -1) {441try {442w = vmIF.getWidth();443h = vmIF.getHeight();444vmIF.setMaximum(true);445w = vmIF.getWidth() - w;446h = vmIF.getHeight() - h;447vmIF.pack();448} catch (PropertyVetoException ex) {449// Ignore450}451}452}453}454int x = 0;455int y = 0;456int dX = (n > 1) ? (w / (n - 1)) : 0;457int dY = (n > 1) ? (h / (n - 1)) : 0;458for (VMInternalFrame vmIF : windows) {459if (!vmIF.isIcon()) {460vmIF.setLocation(x, y);461vmIF.moveToFront();462x += dX;463y += dY;464}465}466}467468// Call on EDT469void addHost(String hostName, int port,470String userName, String password) {471addHost(hostName, port, userName, password, false);472}473474// Call on EDT475void addVmid(LocalVirtualMachine lvm) {476addVmid(lvm, false);477}478479// Call on EDT480void addVmid(final LocalVirtualMachine lvm, final boolean tile) {481new Thread("JConsole.addVmid") {482public void run() {483try {484addProxyClient(ProxyClient.getProxyClient(lvm), tile);485} catch (final SecurityException ex) {486failed(ex, null, null, null);487} catch (final IOException ex) {488failed(ex, null, null, null);489}490}491}.start();492}493494// Call on EDT495void addUrl(final String url,496final String userName,497final String password,498final boolean tile) {499new Thread("JConsole.addUrl") {500public void run() {501try {502addProxyClient(ProxyClient.getProxyClient(url, userName, password),503tile);504} catch (final MalformedURLException ex) {505failed(ex, url, userName, password);506} catch (final SecurityException ex) {507failed(ex, url, userName, password);508} catch (final IOException ex) {509failed(ex, url, userName, password);510}511}512}.start();513}514515516// Call on EDT517void addHost(final String hostName, final int port,518final String userName, final String password,519final boolean tile) {520new Thread("JConsole.addHost") {521public void run() {522try {523addProxyClient(ProxyClient.getProxyClient(hostName, port,524userName, password),525tile);526} catch (final IOException ex) {527dbgStackTrace(ex);528SwingUtilities.invokeLater(new Runnable() {529public void run() {530showConnectDialog(null, hostName, port,531userName, password, errorMessage(ex));532}533});534}535}536}.start();537}538539540// Call on worker thread541void addProxyClient(final ProxyClient proxyClient, final boolean tile) {542SwingUtilities.invokeLater(new Runnable() {543public void run() {544VMPanel vmPanel = new VMPanel(proxyClient, updateInterval);545addFrame(vmPanel);546547if (tile) {548SwingUtilities.invokeLater(new Runnable() {549public void run() {550tileWindows();551}552});553}554vmPanel.connect();555}556});557}558559560// Call on worker thread561private void failed(final Exception ex,562final String url,563final String userName,564final String password) {565SwingUtilities.invokeLater(new Runnable() {566public void run() {567dbgStackTrace(ex);568showConnectDialog(url,569null,570-1,571userName,572password,573errorMessage(ex));574}575});576}577578579private VMInternalFrame addFrame(VMPanel vmPanel) {580final VMInternalFrame vmIF = new VMInternalFrame(vmPanel);581582for (VMInternalFrame f : windows) {583try {584f.setMaximum(false);585} catch (PropertyVetoException ex) {586// Ignore587}588}589desktop.add(vmIF);590591vmIF.setLocation(frameLoc, frameLoc);592frameLoc += 30;593vmIF.setVisible(true);594windows.add(vmIF);595if (windows.size() == 1) {596try {597vmIF.setMaximum(true);598} catch (PropertyVetoException ex) {599// Ignore600}601}602vmIF.addInternalFrameListener(this);603windowMenu.add(vmIF);604605return vmIF;606}607608private void showConnectDialog(String url,609String hostName,610int port,611String userName,612String password,613String msg) {614if (connectDialog == null) {615connectDialog = new ConnectDialog(this);616}617connectDialog.setConnectionParameters(url,618hostName,619port,620userName,621password,622msg);623624connectDialog.refresh();625connectDialog.setVisible(true);626try {627// Bring to front of other dialogs628connectDialog.setSelected(true);629} catch (PropertyVetoException e) {630}631}632633private void showCreateMBeanDialog() {634if (createDialog == null) {635createDialog = new CreateMBeanDialog(this);636}637createDialog.setVisible(true);638try {639// Bring to front of other dialogs640createDialog.setSelected(true);641} catch (PropertyVetoException e) {642}643}644645private void removeVMInternalFrame(VMInternalFrame vmIF) {646windowMenu.remove(vmIF);647desktop.remove(vmIF);648desktop.repaint();649vmIF.getVMPanel().cleanUp();650vmIF.dispose();651}652653private boolean isProxyClientUsed(ProxyClient client) {654for(VMInternalFrame frame : windows) {655ProxyClient cli = frame.getVMPanel().getProxyClient(false);656if(client == cli)657return true;658}659return false;660}661662static boolean isValidRemoteString(String txt) {663boolean valid = false;664if (txt != null) {665txt = txt.trim();666if (txt.startsWith(ROOT_URL)) {667if (txt.length() > ROOT_URL.length()) {668valid = true;669}670} else {671//---------------------------------------672// Supported host and port combinations:673// hostname:port674// IPv4Address:port675// [IPv6Address]:port676//---------------------------------------677678// Is literal IPv6 address?679//680if (txt.startsWith("[")) {681int index = txt.indexOf("]:");682if (index != -1) {683// Extract literal IPv6 address684//685String address = txt.substring(1, index);686if (IPAddressUtil.isIPv6LiteralAddress(address)) {687// Extract port688//689try {690String portStr = txt.substring(index + 2);691int port = Integer.parseInt(portStr);692if (port >= 0 && port <= 0xFFFF) {693valid = true;694}695} catch (NumberFormatException ex) {696valid = false;697}698}699}700} else {701String[] s = txt.split(":");702if (s.length == 2) {703try {704int port = Integer.parseInt(s[1]);705if (port >= 0 && port <= 0xFFFF) {706valid = true;707}708} catch (NumberFormatException ex) {709valid = false;710}711}712}713}714}715return valid;716}717718private String errorMessage(Exception ex) {719String msg = Messages.CONNECTION_FAILED;720if (ex instanceof IOException || ex instanceof SecurityException) {721Throwable cause = null;722Throwable c = ex.getCause();723while (c != null) {724cause = c;725c = c.getCause();726}727if (cause instanceof ConnectException) {728return msg + ": " + cause.getMessage();729} else if (cause instanceof UnknownHostException) {730return Resources.format(Messages.UNKNOWN_HOST, cause.getMessage());731} else if (cause instanceof NoRouteToHostException) {732return msg + ": " + cause.getMessage();733} else if (cause instanceof FailedLoginException) {734return msg + ": " + cause.getMessage();735} else if (cause instanceof SSLHandshakeException) {736return msg + ": "+ cause.getMessage();737}738} else if (ex instanceof MalformedURLException) {739return Resources.format(Messages.INVALID_URL, ex.getMessage());740}741return msg + ": " + ex.getMessage();742}743744745// InternalFrameListener interface746747public void internalFrameClosing(InternalFrameEvent e) {748VMInternalFrame vmIF = (VMInternalFrame)e.getInternalFrame();749removeVMInternalFrame(vmIF);750windows.remove(vmIF);751ProxyClient client = vmIF.getVMPanel().getProxyClient(false);752if(!isProxyClientUsed(client))753client.markAsDead();754if (windows.size() == 0) {755showConnectDialog("", "", 0, null, null, null);756}757}758759public void internalFrameOpened(InternalFrameEvent e) {}760public void internalFrameClosed(InternalFrameEvent e) {}761public void internalFrameIconified(InternalFrameEvent e) {}762public void internalFrameDeiconified(InternalFrameEvent e) {}763public void internalFrameActivated(InternalFrameEvent e) {}764public void internalFrameDeactivated(InternalFrameEvent e) {}765766767private static void usage() {768System.err.println(Resources.format(Messages.ZZ_USAGE_TEXT, "jconsole"));769}770771private static void mainInit(final List<String> urls,772final List<String> hostNames,773final List<Integer> ports,774final List<LocalVirtualMachine> vmids,775final ProxyClient proxyClient,776final boolean noTile,777final boolean hotspot) {778779780// Always create Swing GUI on the Event Dispatching Thread781SwingUtilities.invokeLater(new Runnable() {782public void run() {783JConsole jConsole = new JConsole(hotspot);784785// Center the window on screen, taking into account screen786// size and insets.787Toolkit toolkit = Toolkit.getDefaultToolkit();788GraphicsConfiguration gc = jConsole.getGraphicsConfiguration();789Dimension scrSize = toolkit.getScreenSize();790Insets scrInsets = toolkit.getScreenInsets(gc);791Rectangle scrBounds =792new Rectangle(scrInsets.left, scrInsets.top,793scrSize.width - scrInsets.left - scrInsets.right,794scrSize.height - scrInsets.top - scrInsets.bottom);795int w = Math.min(900, scrBounds.width);796int h = Math.min(750, scrBounds.height);797jConsole.setBounds(scrBounds.x + (scrBounds.width - w) / 2,798scrBounds.y + (scrBounds.height - h) / 2,799w, h);800801jConsole.setVisible(true);802jConsole.createMDI();803804for (int i = 0; i < hostNames.size(); i++) {805jConsole.addHost(hostNames.get(i), ports.get(i),806null, null,807(i == hostNames.size() - 1) ?808!noTile : false);809}810811for (int i = 0; i < urls.size(); i++) {812jConsole.addUrl(urls.get(i),813null,814null,815(i == urls.size() - 1) ?816!noTile : false);817}818819for (int i = 0; i < vmids.size(); i++) {820jConsole.addVmid(vmids.get(i),821(i == vmids.size() - 1) ?822!noTile : false);823}824825if (vmids.size() == 0 &&826hostNames.size() == 0 &&827urls.size() == 0) {828jConsole.showConnectDialog(null,829null,8300,831null,832null,833null);834}835}836});837}838839public static void main(String[] args) {840boolean noTile = false, hotspot = false;841int argIndex = 0;842ProxyClient proxyClient = null;843844if (System.getProperty("jconsole.showOutputViewer") != null) {845OutputViewer.init();846}847848while (args.length - argIndex > 0 && args[argIndex].startsWith("-")) {849String arg = args[argIndex++];850if (arg.equals("-h") ||851arg.equals("-help") ||852arg.equals("-?")) {853854usage();855return;856} else if (arg.startsWith("-interval=")) {857try {858updateInterval = Integer.parseInt(arg.substring(10)) *8591000;860if (updateInterval <= 0) {861usage();862return;863}864} catch (NumberFormatException ex) {865usage();866return;867}868} else if (arg.equals("-pluginpath")) {869if (argIndex < args.length && !args[argIndex].startsWith("-")) {870pluginPath = args[argIndex++];871} else {872// Invalid argument873usage();874return;875}876} else if (arg.equals("-notile")) {877noTile = true;878} else if (arg.equals("-version")) {879Version.print(System.err);880return;881} else if (arg.equals("-debug")) {882debug = true;883} else if (arg.equals("-fullversion")) {884Version.printFullVersion(System.err);885return;886} else {887// Unknown switch888usage();889return;890}891}892893if (System.getProperty("jconsole.showUnsupported") != null) {894hotspot = true;895}896897List<String> urls = new ArrayList<String>();898List<String> hostNames = new ArrayList<String>();899List<Integer> ports = new ArrayList<Integer>();900List<LocalVirtualMachine> vms = new ArrayList<LocalVirtualMachine>();901902for (int i = argIndex; i < args.length; i++) {903String arg = args[i];904if (isValidRemoteString(arg)) {905if (arg.startsWith(ROOT_URL)) {906urls.add(arg);907} else if (arg.matches(".*:[0-9]*")) {908int p = arg.lastIndexOf(':');909hostNames.add(arg.substring(0, p));910try {911ports.add(Integer.parseInt(arg.substring(p+1)));912} catch (NumberFormatException ex) {913usage();914return;915}916}917} else {918if (!isLocalAttachAvailable()) {919System.err.println("Local process monitoring is not supported");920return;921}922try {923int vmid = Integer.parseInt(arg);924LocalVirtualMachine lvm =925LocalVirtualMachine.getLocalVirtualMachine(vmid);926if (lvm == null) {927System.err.println("Invalid process id:" + vmid);928return;929}930vms.add(lvm);931} catch (NumberFormatException ex) {932usage();933return;934}935}936}937938mainInit(urls, hostNames, ports, vms, proxyClient, noTile, hotspot);939}940941public static boolean isDebug() {942return debug;943}944945private static void dbgStackTrace(Exception ex) {946if (debug) {947ex.printStackTrace();948}949}950951/**952* local attach is supported in this implementation as jdk.jconsole953* requires jdk.attach and jdk.management.agent954*/955public static boolean isLocalAttachAvailable() {956return true;957}958959960private static ServiceLoader<JConsolePlugin> pluginService = null;961962// Return a list of newly instantiated JConsolePlugin objects963static synchronized List<JConsolePlugin> getPlugins() {964if (pluginService == null) {965// First time loading and initializing the plugins966initPluginService(pluginPath);967} else {968// reload the plugin so that new instances will be created969pluginService.reload();970}971972List<JConsolePlugin> plugins = new ArrayList<JConsolePlugin>();973for (JConsolePlugin p : pluginService) {974plugins.add(p);975}976return plugins;977}978979private static void initPluginService(String pluginPath) {980if (pluginPath.length() > 0) {981try {982ClassLoader pluginCL = new URLClassLoader(pathToURLs(pluginPath));983ServiceLoader<JConsolePlugin> plugins =984ServiceLoader.load(JConsolePlugin.class, pluginCL);985// validate all plugins986for (JConsolePlugin p : plugins) {987if (isDebug()) {988System.out.println("Plugin " + p.getClass() + " loaded.");989}990}991pluginService = plugins;992} catch (ServiceConfigurationError e) {993// Error occurs during initialization of plugin994System.out.println(Resources.format(Messages.FAIL_TO_LOAD_PLUGIN,995e.getMessage()));996} catch (MalformedURLException e) {997if (JConsole.isDebug()) {998e.printStackTrace();999}1000System.out.println(Resources.format(Messages.INVALID_PLUGIN_PATH,1001e.getMessage()));1002}1003}10041005if (pluginService == null) {1006initEmptyPlugin();1007}1008}10091010private static void initEmptyPlugin() {1011ClassLoader pluginCL = new URLClassLoader(new URL[0]);1012pluginService = ServiceLoader.load(JConsolePlugin.class, pluginCL);1013}10141015/**1016* Utility method for converting a search path string to an array1017* of directory and JAR file URLs.1018*1019* @param path the search path string1020* @return the resulting array of directory and JAR file URLs1021*/1022private static URL[] pathToURLs(String path) throws MalformedURLException {1023String[] names = path.split(File.pathSeparator);1024URL[] urls = new URL[names.length];1025int count = 0;1026for (String f : names) {1027URL url = fileToURL(new File(f));1028urls[count++] = url;1029}1030return urls;1031}10321033/**1034* Returns the directory or JAR file URL corresponding to the specified1035* local file name.1036*1037* @param file the File object1038* @return the resulting directory or JAR file URL, or null if unknown1039*/1040private static URL fileToURL(File file) throws MalformedURLException {1041String name;1042try {1043name = file.getCanonicalPath();1044} catch (IOException e) {1045name = file.getAbsolutePath();1046}1047name = name.replace(File.separatorChar, '/');1048if (!name.startsWith("/")) {1049name = "/" + name;1050}1051// If the file does not exist, then assume that it's a directory1052if (!file.isFile()) {1053name = name + "/";1054}1055return new URL("file", "", name);1056}105710581059private static class FixedJRootPane extends JRootPane {1060public void updateUI() {1061updateLafValues();1062super.updateUI();1063}10641065/**1066* The revalidate method seems to be the only one that gets1067* called whenever there is a change of L&F or change of theme1068* in Windows L&F and GTK L&F.1069*/1070@Override1071public void revalidate() {1072// Workaround for Swing bug where the titledborder in both1073// GTK and Windows L&F's use calculated colors instead of1074// the highlight/shadow colors from the theme.1075//1076// Putting null removes any previous override and causes a1077// fallback to the current L&F's value.1078UIManager.put("TitledBorder.border", null);1079Border border = UIManager.getBorder("TitledBorder.border");1080if (border instanceof BorderUIResource.EtchedBorderUIResource) {1081Color highlight = UIManager.getColor("ToolBar.highlight");1082Color shadow = UIManager.getColor("ToolBar.shadow");1083border = new BorderUIResource.EtchedBorderUIResource(highlight,1084shadow);1085UIManager.put("TitledBorder.border", border);1086}10871088if (IS_GTK) {1089// Workaround for Swing bug where the titledborder in1090// GTK L&F use hardcoded color and font for the title1091// instead of getting them from the theme.1092UIManager.put("TitledBorder.titleColor",1093UIManager.getColor("Label.foreground"));1094UIManager.put("TitledBorder.font",1095UIManager.getFont("Label.font"));1096}1097super.revalidate();1098}1099}1100}110111021103