0N/A/*
2362N/A * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.tools.jconsole;
0N/A
0N/Aimport java.awt.*;
0N/Aimport java.awt.event.*;
0N/Aimport java.beans.*;
0N/Aimport java.io.*;
0N/Aimport java.net.*;
0N/Aimport java.util.*;
0N/Aimport java.util.List;
0N/A
0N/Aimport javax.swing.*;
0N/Aimport javax.swing.border.*;
0N/Aimport javax.swing.event.*;
0N/Aimport javax.swing.plaf.*;
0N/Aimport javax.security.auth.login.FailedLoginException;
0N/Aimport javax.net.ssl.SSLHandshakeException;
0N/A
0N/Aimport com.sun.tools.jconsole.JConsolePlugin;
0N/A
0N/Aimport sun.net.util.IPAddressUtil;
0N/A
0N/Aimport static sun.tools.jconsole.Utilities.*;
0N/A
0N/A@SuppressWarnings("serial")
0N/Apublic class JConsole extends JFrame
0N/A implements ActionListener, InternalFrameListener {
0N/A
0N/A static /*final*/ boolean IS_GTK;
0N/A static /*final*/ boolean IS_WIN;
0N/A
0N/A static {
0N/A // Apply the system L&F if it is GTK or Windows, and
0N/A // the L&F is not specified using a system property.
0N/A if (System.getProperty("swing.defaultlaf") == null) {
0N/A String systemLaF = UIManager.getSystemLookAndFeelClassName();
0N/A if (systemLaF.equals("com.sun.java.swing.plaf.gtk.GTKLookAndFeel") ||
0N/A systemLaF.equals("com.sun.java.swing.plaf.windows.WindowsLookAndFeel")) {
0N/A
0N/A try {
0N/A UIManager.setLookAndFeel(systemLaF);
0N/A } catch (Exception e) {
5335N/A System.err.println(Resources.format(Messages.JCONSOLE_COLON_, e.getMessage()));
0N/A }
0N/A }
0N/A }
0N/A
0N/A updateLafValues();
0N/A }
0N/A
0N/A
0N/A static void updateLafValues() {
0N/A String lafName = UIManager.getLookAndFeel().getClass().getName();
0N/A IS_GTK = lafName.equals("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
0N/A IS_WIN = lafName.equals("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
0N/A
0N/A //BorderedComponent.updateLafValues();
0N/A }
0N/A
0N/A
0N/A private final static String title =
5335N/A Messages.JAVA_MONITORING___MANAGEMENT_CONSOLE;
0N/A public final static String ROOT_URL =
0N/A "service:jmx:";
0N/A
0N/A private static int updateInterval = 4000;
0N/A private static String pluginPath = "";
0N/A
0N/A private JMenuBar menuBar;
0N/A private JMenuItem hotspotMI, connectMI, exitMI;
0N/A private WindowMenu windowMenu;
0N/A private JMenuItem tileMI, cascadeMI, minimizeAllMI, restoreAllMI;
0N/A private JMenuItem userGuideMI, aboutMI;
0N/A
0N/A private JButton connectButton;
0N/A private JDesktopPane desktop;
0N/A private ConnectDialog connectDialog;
0N/A private CreateMBeanDialog createDialog;
0N/A
0N/A private ArrayList<VMInternalFrame> windows =
0N/A new ArrayList<VMInternalFrame>();
0N/A
0N/A private int frameLoc = 5;
0N/A static boolean debug;
0N/A
0N/A public JConsole(boolean hotspot) {
0N/A super(title);
0N/A
0N/A setRootPane(new FixedJRootPane());
0N/A setAccessibleDescription(this,
5335N/A Messages.JCONSOLE_ACCESSIBLE_DESCRIPTION);
0N/A setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
0N/A
0N/A menuBar = new JMenuBar();
0N/A setJMenuBar(menuBar);
0N/A
0N/A // TODO: Use Actions !
0N/A
5335N/A JMenu connectionMenu = new JMenu(Messages.CONNECTION);
5335N/A connectionMenu.setMnemonic(Resources.getMnemonicInt(Messages.CONNECTION));
0N/A menuBar.add(connectionMenu);
0N/A if(hotspot) {
5335N/A hotspotMI = new JMenuItem(Messages.HOTSPOT_MBEANS_ELLIPSIS);
5335N/A hotspotMI.setMnemonic(Resources.getMnemonicInt(Messages.HOTSPOT_MBEANS_ELLIPSIS));
0N/A hotspotMI.setAccelerator(KeyStroke.
0N/A getKeyStroke(KeyEvent.VK_H,
0N/A InputEvent.CTRL_MASK));
0N/A hotspotMI.addActionListener(this);
0N/A connectionMenu.add(hotspotMI);
0N/A
0N/A connectionMenu.addSeparator();
0N/A }
0N/A
5335N/A connectMI = new JMenuItem(Messages.NEW_CONNECTION_ELLIPSIS);
5335N/A connectMI.setMnemonic(Resources.getMnemonicInt(Messages.NEW_CONNECTION_ELLIPSIS));
0N/A connectMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,
0N/A InputEvent.CTRL_MASK));
0N/A connectMI.addActionListener(this);
0N/A connectionMenu.add(connectMI);
0N/A
0N/A connectionMenu.addSeparator();
0N/A
5335N/A exitMI = new JMenuItem(Messages.EXIT);
5335N/A exitMI.setMnemonic(Resources.getMnemonicInt(Messages.EXIT));
0N/A exitMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4,
0N/A InputEvent.ALT_MASK));
0N/A exitMI.addActionListener(this);
0N/A connectionMenu.add(exitMI);
0N/A
0N/A
5335N/A JMenu helpMenu = new JMenu(Messages.HELP_MENU_TITLE);
5335N/A helpMenu.setMnemonic(Resources.getMnemonicInt(Messages.HELP_MENU_TITLE));
0N/A menuBar.add(helpMenu);
0N/A
0N/A if (AboutDialog.isBrowseSupported()) {
5335N/A userGuideMI = new JMenuItem(Messages.HELP_MENU_USER_GUIDE_TITLE);
5335N/A userGuideMI.setMnemonic(Resources.getMnemonicInt(Messages.HELP_MENU_USER_GUIDE_TITLE));
0N/A userGuideMI.addActionListener(this);
0N/A helpMenu.add(userGuideMI);
0N/A helpMenu.addSeparator();
0N/A }
5335N/A aboutMI = new JMenuItem(Messages.HELP_MENU_ABOUT_TITLE);
5335N/A aboutMI.setMnemonic(Resources.getMnemonicInt(Messages.HELP_MENU_ABOUT_TITLE));
0N/A aboutMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0));
0N/A aboutMI.addActionListener(this);
0N/A helpMenu.add(aboutMI);
0N/A }
0N/A
0N/A public JDesktopPane getDesktopPane() {
0N/A return desktop;
0N/A }
0N/A
0N/A public List<VMInternalFrame> getInternalFrames() {
0N/A return windows;
0N/A }
0N/A
0N/A private void createMDI() {
0N/A // Restore title - we now show connection name on internal frames
0N/A setTitle(title);
0N/A
0N/A Container cp = getContentPane();
0N/A Component oldCenter =
0N/A ((BorderLayout)cp.getLayout()).
0N/A getLayoutComponent(BorderLayout.CENTER);
0N/A
5335N/A windowMenu = new WindowMenu(Messages.WINDOW);
5335N/A windowMenu.setMnemonic(Resources.getMnemonicInt(Messages.WINDOW));
0N/A // Add Window menu before Help menu
0N/A menuBar.add(windowMenu, menuBar.getComponentCount() - 1);
0N/A
0N/A desktop = new JDesktopPane();
0N/A desktop.setBackground(new Color(235, 245, 255));
0N/A
0N/A cp.add(desktop, BorderLayout.CENTER);
0N/A
0N/A if (oldCenter instanceof VMPanel) {
0N/A addFrame((VMPanel)oldCenter);
0N/A }
0N/A }
0N/A
0N/A private class WindowMenu extends JMenu {
0N/A VMInternalFrame[] windowMenuWindows = new VMInternalFrame[0];
0N/A int separatorPosition;
0N/A
0N/A // The width value of viewR is used to truncate long menu items.
0N/A // The rest are placeholders and are ignored for this purpose.
0N/A Rectangle viewR = new Rectangle(0, 0, 400, 20);
0N/A Rectangle textR = new Rectangle(0, 0, 0, 0);
0N/A Rectangle iconR = new Rectangle(0, 0, 0, 0);
0N/A
0N/A WindowMenu(String text) {
0N/A super(text);
0N/A
5335N/A cascadeMI = new JMenuItem(Messages.CASCADE);
5335N/A cascadeMI.setMnemonic(Resources.getMnemonicInt(Messages.CASCADE));
0N/A cascadeMI.addActionListener(JConsole.this);
0N/A add(cascadeMI);
0N/A
5335N/A tileMI = new JMenuItem(Messages.TILE);
5335N/A tileMI.setMnemonic(Resources.getMnemonicInt(Messages.TILE));
0N/A tileMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T,
0N/A InputEvent.CTRL_MASK));
0N/A tileMI.addActionListener(JConsole.this);
0N/A add(tileMI);
0N/A
5335N/A minimizeAllMI = new JMenuItem(Messages.MINIMIZE_ALL);
5335N/A minimizeAllMI.setMnemonic(Resources.getMnemonicInt(Messages.MINIMIZE_ALL));
0N/A minimizeAllMI.addActionListener(JConsole.this);
0N/A add(minimizeAllMI);
0N/A
5335N/A restoreAllMI = new JMenuItem(Messages.RESTORE_ALL);
5335N/A restoreAllMI.setMnemonic(Resources.getMnemonicInt(Messages.RESTORE_ALL));
0N/A restoreAllMI.addActionListener(JConsole.this);
0N/A add(restoreAllMI);
0N/A
0N/A separatorPosition = getMenuComponentCount();
0N/A }
0N/A
0N/A private void add(VMInternalFrame vmIF) {
0N/A if (separatorPosition == getMenuComponentCount()) {
0N/A addSeparator();
0N/A }
0N/A
0N/A int index = -1;
0N/A int position = separatorPosition + 1;
0N/A int n = windowMenuWindows.length;
0N/A
0N/A for (int i = 0; i < n; i++) {
0N/A if (windowMenuWindows[i] != null) {
0N/A // Slot is in use, try next
0N/A position++;
0N/A } else {
0N/A // Found a free slot
0N/A index = i;
0N/A break;
0N/A }
0N/A }
0N/A
0N/A if (index == -1) {
0N/A // Create a slot at the end
0N/A VMInternalFrame[] newArray = new VMInternalFrame[n + 1];
0N/A System.arraycopy(windowMenuWindows, 0, newArray, 0, n);
0N/A windowMenuWindows = newArray;
0N/A index = n;
0N/A }
0N/A
0N/A windowMenuWindows[index] = vmIF;
0N/A
0N/A String indexString = "" + (index+1);
0N/A String vmName = vmIF.getVMPanel().getDisplayName();
0N/A // Maybe truncate menu item string and end with "..."
0N/A String text =
0N/A SwingUtilities.layoutCompoundLabel(this,
0N/A getGraphics().getFontMetrics(getFont()),
0N/A indexString + " " + vmName,
0N/A null, 0, 0, 0, 0,
0N/A viewR, iconR, textR, 0);
0N/A JMenuItem mi = new JMenuItem(text);
0N/A if (text.endsWith("...")) {
0N/A mi.setToolTipText(vmName);
0N/A }
0N/A
0N/A // Set mnemonic using last digit of number
0N/A int nDigits = indexString.length();
0N/A mi.setMnemonic(indexString.charAt(nDigits-1));
0N/A mi.setDisplayedMnemonicIndex(nDigits-1);
0N/A
0N/A mi.putClientProperty("JConsole.vmIF", vmIF);
0N/A mi.addActionListener(JConsole.this);
0N/A vmIF.putClientProperty("JConsole.menuItem", mi);
0N/A add(mi, position);
0N/A }
0N/A
0N/A private void remove(VMInternalFrame vmIF) {
0N/A for (int i = 0; i < windowMenuWindows.length; i++) {
0N/A if (windowMenuWindows[i] == vmIF) {
0N/A windowMenuWindows[i] = null;
0N/A }
0N/A }
0N/A JMenuItem mi = (JMenuItem)vmIF.getClientProperty("JConsole.menuItem");
0N/A remove(mi);
0N/A mi.putClientProperty("JConsole.vmIF", null);
0N/A vmIF.putClientProperty("JConsole.menuItem", null);
0N/A
0N/A if (separatorPosition == getMenuComponentCount() - 1) {
0N/A remove(getMenuComponent(getMenuComponentCount() - 1));
0N/A }
0N/A }
0N/A }
0N/A
0N/A public void actionPerformed(ActionEvent ev) {
0N/A Object src = ev.getSource();
0N/A if (src == hotspotMI) {
0N/A showCreateMBeanDialog();
0N/A }
0N/A
0N/A if (src == connectButton || src == connectMI) {
0N/A VMPanel vmPanel = null;
0N/A JInternalFrame vmIF = desktop.getSelectedFrame();
0N/A if (vmIF instanceof VMInternalFrame) {
0N/A vmPanel = ((VMInternalFrame)vmIF).getVMPanel();
0N/A }
0N/A String hostName = "";
0N/A String url = "";
0N/A if (vmPanel != null) {
0N/A hostName = vmPanel.getHostName();
0N/A if(vmPanel.getUrl() != null)
0N/A url = vmPanel.getUrl();
0N/A }
0N/A showConnectDialog(url, hostName, 0, null, null, null);
0N/A } else if (src == tileMI) {
0N/A tileWindows();
0N/A } else if (src == cascadeMI) {
0N/A cascadeWindows();
0N/A } else if (src == minimizeAllMI) {
0N/A for (VMInternalFrame vmIF : windows) {
0N/A try {
0N/A vmIF.setIcon(true);
0N/A } catch (PropertyVetoException ex) {
0N/A // Ignore
0N/A }
0N/A }
0N/A } else if (src == restoreAllMI) {
0N/A for (VMInternalFrame vmIF : windows) {
0N/A try {
0N/A vmIF.setIcon(false);
0N/A } catch (PropertyVetoException ex) {
0N/A // Ignore
0N/A }
0N/A }
0N/A } else if (src == exitMI) {
0N/A System.exit(0);
0N/A } else if (src == userGuideMI) {
0N/A AboutDialog.browseUserGuide(this);
0N/A } else if (src == aboutMI) {
0N/A AboutDialog.showAboutDialog(this);
0N/A } else if (src instanceof JMenuItem) {
0N/A JMenuItem mi = (JMenuItem)src;
0N/A VMInternalFrame vmIF = (VMInternalFrame)mi.
0N/A getClientProperty("JConsole.vmIF");
0N/A if (vmIF != null) {
0N/A try {
0N/A vmIF.setIcon(false);
0N/A vmIF.setSelected(true);
0N/A } catch (PropertyVetoException ex) {
0N/A // Ignore
0N/A }
0N/A vmIF.moveToFront();
0N/A }
0N/A }
0N/A }
0N/A
0N/A
0N/A public void tileWindows() {
0N/A int w = -1;
0N/A int h = -1;
0N/A int n = 0;
0N/A for (VMInternalFrame vmIF : windows) {
0N/A if (!vmIF.isIcon()) {
0N/A n++;
0N/A if (w == -1) {
0N/A try {
0N/A vmIF.setMaximum(true);
0N/A w = vmIF.getWidth();
0N/A h = vmIF.getHeight();
0N/A } catch (PropertyVetoException ex) {
0N/A // Ignore
0N/A }
0N/A }
0N/A }
0N/A }
0N/A if (n > 0 && w > 0 && h > 0) {
0N/A int rows = (int)Math.ceil(Math.sqrt(n));
0N/A int cols = n / rows;
0N/A if (rows * cols < n) cols++;
0N/A int x = 0;
0N/A int y = 0;
0N/A w /= cols;
0N/A h /= rows;
0N/A int col = 0;
0N/A for (VMInternalFrame vmIF : windows) {
0N/A if (!vmIF.isIcon()) {
0N/A try {
0N/A vmIF.setMaximum(n==1);
0N/A } catch (PropertyVetoException ex) {
0N/A // Ignore
0N/A }
0N/A if (n > 1) {
0N/A vmIF.setBounds(x, y, w, h);
0N/A }
0N/A if (col < cols-1) {
0N/A col++;
0N/A x += w;
0N/A } else {
0N/A col = 0;
0N/A x = 0;
0N/A y += h;
0N/A }
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A public void cascadeWindows() {
0N/A int n = 0;
0N/A int w = -1;
0N/A int h = -1;
0N/A for (VMInternalFrame vmIF : windows) {
0N/A if (!vmIF.isIcon()) {
0N/A try {
0N/A vmIF.setMaximum(false);
0N/A } catch (PropertyVetoException ex) {
0N/A // Ignore
0N/A }
0N/A n++;
0N/A vmIF.pack();
0N/A if (w == -1) {
0N/A try {
0N/A w = vmIF.getWidth();
0N/A h = vmIF.getHeight();
0N/A vmIF.setMaximum(true);
0N/A w = vmIF.getWidth() - w;
0N/A h = vmIF.getHeight() - h;
0N/A vmIF.pack();
0N/A } catch (PropertyVetoException ex) {
0N/A // Ignore
0N/A }
0N/A }
0N/A }
0N/A }
0N/A int x = 0;
0N/A int y = 0;
0N/A int dX = (n > 1) ? (w / (n - 1)) : 0;
0N/A int dY = (n > 1) ? (h / (n - 1)) : 0;
0N/A for (VMInternalFrame vmIF : windows) {
0N/A if (!vmIF.isIcon()) {
0N/A vmIF.setLocation(x, y);
0N/A vmIF.moveToFront();
0N/A x += dX;
0N/A y += dY;
0N/A }
0N/A }
0N/A }
0N/A
0N/A // Call on EDT
0N/A void addHost(String hostName, int port,
0N/A String userName, String password) {
0N/A addHost(hostName, port, userName, password, false);
0N/A }
0N/A
0N/A // Call on EDT
0N/A void addVmid(LocalVirtualMachine lvm) {
0N/A addVmid(lvm, false);
0N/A }
0N/A
0N/A // Call on EDT
0N/A void addVmid(final LocalVirtualMachine lvm, final boolean tile) {
0N/A new Thread("JConsole.addVmid") {
0N/A public void run() {
0N/A try {
0N/A addProxyClient(ProxyClient.getProxyClient(lvm), tile);
0N/A } catch (final SecurityException ex) {
0N/A failed(ex, null, null, null);
0N/A } catch (final IOException ex) {
0N/A failed(ex, null, null, null);
0N/A }
0N/A }
0N/A }.start();
0N/A }
0N/A
0N/A // Call on EDT
0N/A void addUrl(final String url,
0N/A final String userName,
0N/A final String password,
0N/A final boolean tile) {
0N/A new Thread("JConsole.addUrl") {
0N/A public void run() {
0N/A try {
0N/A addProxyClient(ProxyClient.getProxyClient(url, userName, password),
0N/A tile);
0N/A } catch (final MalformedURLException ex) {
0N/A failed(ex, url, userName, password);
0N/A } catch (final SecurityException ex) {
0N/A failed(ex, url, userName, password);
0N/A } catch (final IOException ex) {
0N/A failed(ex, url, userName, password);
0N/A }
0N/A }
0N/A }.start();
0N/A }
0N/A
0N/A
0N/A // Call on EDT
0N/A void addHost(final String hostName, final int port,
0N/A final String userName, final String password,
0N/A final boolean tile) {
0N/A new Thread("JConsole.addHost") {
0N/A public void run() {
0N/A try {
0N/A addProxyClient(ProxyClient.getProxyClient(hostName, port,
0N/A userName, password),
0N/A tile);
0N/A } catch (final IOException ex) {
0N/A dbgStackTrace(ex);
0N/A SwingUtilities.invokeLater(new Runnable() {
0N/A public void run() {
0N/A showConnectDialog(null, hostName, port,
0N/A userName, password, errorMessage(ex));
0N/A }
0N/A });
0N/A }
0N/A }
0N/A }.start();
0N/A }
0N/A
0N/A
0N/A // Call on worker thread
0N/A void addProxyClient(final ProxyClient proxyClient, final boolean tile) {
0N/A SwingUtilities.invokeLater(new Runnable() {
0N/A public void run() {
0N/A VMPanel vmPanel = new VMPanel(proxyClient, updateInterval);
0N/A addFrame(vmPanel);
0N/A
0N/A if (tile) {
0N/A SwingUtilities.invokeLater(new Runnable() {
0N/A public void run() {
0N/A tileWindows();
0N/A }
0N/A });
0N/A }
0N/A vmPanel.connect();
0N/A }
0N/A });
0N/A }
0N/A
0N/A
0N/A // Call on worker thread
0N/A private void failed(final Exception ex,
0N/A final String url,
0N/A final String userName,
0N/A final String password) {
0N/A SwingUtilities.invokeLater(new Runnable() {
0N/A public void run() {
0N/A dbgStackTrace(ex);
0N/A showConnectDialog(url,
0N/A null,
0N/A -1,
0N/A userName,
0N/A password,
0N/A errorMessage(ex));
0N/A }
0N/A });
0N/A }
0N/A
0N/A
0N/A private VMInternalFrame addFrame(VMPanel vmPanel) {
0N/A final VMInternalFrame vmIF = new VMInternalFrame(vmPanel);
0N/A
0N/A for (VMInternalFrame f : windows) {
0N/A try {
0N/A f.setMaximum(false);
0N/A } catch (PropertyVetoException ex) {
0N/A // Ignore
0N/A }
0N/A }
0N/A desktop.add(vmIF);
0N/A
0N/A vmIF.setLocation(frameLoc, frameLoc);
0N/A frameLoc += 30;
0N/A vmIF.setVisible(true);
0N/A windows.add(vmIF);
0N/A if (windows.size() == 1) {
0N/A try {
0N/A vmIF.setMaximum(true);
0N/A } catch (PropertyVetoException ex) {
0N/A // Ignore
0N/A }
0N/A }
0N/A vmIF.addInternalFrameListener(this);
0N/A windowMenu.add(vmIF);
0N/A
0N/A return vmIF;
0N/A }
0N/A
0N/A private void showConnectDialog(String url,
0N/A String hostName,
0N/A int port,
0N/A String userName,
0N/A String password,
0N/A String msg) {
0N/A if (connectDialog == null) {
0N/A connectDialog = new ConnectDialog(this);
0N/A }
0N/A connectDialog.setConnectionParameters(url,
0N/A hostName,
0N/A port,
0N/A userName,
0N/A password,
0N/A msg);
0N/A
0N/A connectDialog.refresh();
0N/A connectDialog.setVisible(true);
0N/A try {
0N/A // Bring to front of other dialogs
0N/A connectDialog.setSelected(true);
0N/A } catch (PropertyVetoException e) {
0N/A }
0N/A }
0N/A
0N/A private void showCreateMBeanDialog() {
0N/A if (createDialog == null) {
0N/A createDialog = new CreateMBeanDialog(this);
0N/A }
0N/A createDialog.setVisible(true);
0N/A try {
0N/A // Bring to front of other dialogs
0N/A createDialog.setSelected(true);
0N/A } catch (PropertyVetoException e) {
0N/A }
0N/A }
0N/A
0N/A private void removeVMInternalFrame(VMInternalFrame vmIF) {
0N/A windowMenu.remove(vmIF);
0N/A desktop.remove(vmIF);
0N/A desktop.repaint();
0N/A vmIF.getVMPanel().cleanUp();
0N/A vmIF.dispose();
0N/A }
0N/A
0N/A private boolean isProxyClientUsed(ProxyClient client) {
0N/A for(VMInternalFrame frame : windows) {
0N/A ProxyClient cli = frame.getVMPanel().getProxyClient(false);
0N/A if(client == cli)
0N/A return true;
0N/A }
0N/A return false;
0N/A }
0N/A
0N/A static boolean isValidRemoteString(String txt) {
0N/A boolean valid = false;
0N/A if (txt != null) {
0N/A txt = txt.trim();
0N/A if (txt.startsWith(ROOT_URL)) {
0N/A if (txt.length() > ROOT_URL.length()) {
0N/A valid = true;
0N/A }
0N/A } else {
0N/A //---------------------------------------
0N/A // Supported host and port combinations:
0N/A // hostname:port
0N/A // IPv4Address:port
0N/A // [IPv6Address]:port
0N/A //---------------------------------------
0N/A
0N/A // Is literal IPv6 address?
0N/A //
0N/A if (txt.startsWith("[")) {
0N/A int index = txt.indexOf("]:");
0N/A if (index != -1) {
0N/A // Extract literal IPv6 address
0N/A //
0N/A String address = txt.substring(1, index);
0N/A if (IPAddressUtil.isIPv6LiteralAddress(address)) {
0N/A // Extract port
0N/A //
0N/A try {
0N/A String portStr = txt.substring(index + 2);
0N/A int port = Integer.parseInt(portStr);
0N/A if (port >= 0 && port <= 0xFFFF) {
0N/A valid = true;
0N/A }
0N/A } catch (NumberFormatException ex) {
0N/A valid = false;
0N/A }
0N/A }
0N/A }
0N/A } else {
0N/A String[] s = txt.split(":");
0N/A if (s.length == 2) {
0N/A try {
0N/A int port = Integer.parseInt(s[1]);
0N/A if (port >= 0 && port <= 0xFFFF) {
0N/A valid = true;
0N/A }
0N/A } catch (NumberFormatException ex) {
0N/A valid = false;
0N/A }
0N/A }
0N/A }
0N/A }
0N/A }
0N/A return valid;
0N/A }
0N/A
0N/A private String errorMessage(Exception ex) {
5335N/A String msg = Messages.CONNECTION_FAILED;
0N/A if (ex instanceof IOException || ex instanceof SecurityException) {
0N/A Throwable cause = null;
0N/A Throwable c = ex.getCause();
0N/A while (c != null) {
0N/A cause = c;
0N/A c = c.getCause();
0N/A }
0N/A if (cause instanceof ConnectException) {
0N/A return msg + ": " + cause.getMessage();
0N/A } else if (cause instanceof UnknownHostException) {
5335N/A return Resources.format(Messages.UNKNOWN_HOST, cause.getMessage());
0N/A } else if (cause instanceof NoRouteToHostException) {
0N/A return msg + ": " + cause.getMessage();
0N/A } else if (cause instanceof FailedLoginException) {
0N/A return msg + ": " + cause.getMessage();
0N/A } else if (cause instanceof SSLHandshakeException) {
0N/A return msg + ": "+ cause.getMessage();
0N/A }
0N/A } else if (ex instanceof MalformedURLException) {
5335N/A return Resources.format(Messages.INVALID_URL, ex.getMessage());
0N/A }
0N/A return msg + ": " + ex.getMessage();
0N/A }
0N/A
0N/A
0N/A // InternalFrameListener interface
0N/A
0N/A public void internalFrameClosing(InternalFrameEvent e) {
0N/A VMInternalFrame vmIF = (VMInternalFrame)e.getInternalFrame();
0N/A removeVMInternalFrame(vmIF);
0N/A windows.remove(vmIF);
0N/A ProxyClient client = vmIF.getVMPanel().getProxyClient(false);
0N/A if(!isProxyClientUsed(client))
0N/A client.markAsDead();
0N/A if (windows.size() == 0) {
0N/A showConnectDialog("", "", 0, null, null, null);
0N/A }
0N/A }
0N/A
0N/A public void internalFrameOpened(InternalFrameEvent e) {}
0N/A public void internalFrameClosed(InternalFrameEvent e) {}
0N/A public void internalFrameIconified(InternalFrameEvent e) {}
0N/A public void internalFrameDeiconified(InternalFrameEvent e) {}
0N/A public void internalFrameActivated(InternalFrameEvent e) {}
0N/A public void internalFrameDeactivated(InternalFrameEvent e) {}
0N/A
0N/A
0N/A private static void usage() {
5335N/A System.err.println(Resources.format(Messages.ZZ_USAGE_TEXT, "jconsole"));
0N/A }
0N/A
0N/A private static void mainInit(final List<String> urls,
0N/A final List<String> hostNames,
0N/A final List<Integer> ports,
0N/A final List<LocalVirtualMachine> vmids,
0N/A final ProxyClient proxyClient,
0N/A final boolean noTile,
0N/A final boolean hotspot) {
0N/A
0N/A
0N/A // Always create Swing GUI on the Event Dispatching Thread
0N/A SwingUtilities.invokeLater(new Runnable() {
0N/A public void run() {
0N/A JConsole jConsole = new JConsole(hotspot);
0N/A
0N/A // Center the window on screen, taking into account screen
0N/A // size and insets.
0N/A Toolkit toolkit = Toolkit.getDefaultToolkit();
0N/A GraphicsConfiguration gc = jConsole.getGraphicsConfiguration();
0N/A Dimension scrSize = toolkit.getScreenSize();
0N/A Insets scrInsets = toolkit.getScreenInsets(gc);
0N/A Rectangle scrBounds =
0N/A new Rectangle(scrInsets.left, scrInsets.top,
0N/A scrSize.width - scrInsets.left - scrInsets.right,
0N/A scrSize.height - scrInsets.top - scrInsets.bottom);
0N/A int w = Math.min(900, scrBounds.width);
0N/A int h = Math.min(750, scrBounds.height);
0N/A jConsole.setBounds(scrBounds.x + (scrBounds.width - w) / 2,
0N/A scrBounds.y + (scrBounds.height - h) / 2,
0N/A w, h);
0N/A
0N/A jConsole.setVisible(true);
0N/A jConsole.createMDI();
0N/A
0N/A for (int i = 0; i < hostNames.size(); i++) {
0N/A jConsole.addHost(hostNames.get(i), ports.get(i),
0N/A null, null,
0N/A (i == hostNames.size() - 1) ?
0N/A !noTile : false);
0N/A }
0N/A
0N/A for (int i = 0; i < urls.size(); i++) {
0N/A jConsole.addUrl(urls.get(i),
0N/A null,
0N/A null,
0N/A (i == urls.size() - 1) ?
0N/A !noTile : false);
0N/A }
0N/A
0N/A for (int i = 0; i < vmids.size(); i++) {
0N/A jConsole.addVmid(vmids.get(i),
0N/A (i == vmids.size() - 1) ?
0N/A !noTile : false);
0N/A }
0N/A
0N/A if (vmids.size() == 0 &&
0N/A hostNames.size() == 0 &&
0N/A urls.size() == 0) {
0N/A jConsole.showConnectDialog(null,
0N/A null,
0N/A 0,
0N/A null,
0N/A null,
0N/A null);
0N/A }
0N/A }
0N/A });
0N/A }
0N/A
0N/A public static void main(String[] args) {
0N/A boolean noTile = false, hotspot = false;
0N/A int argIndex = 0;
0N/A ProxyClient proxyClient = null;
0N/A
0N/A if (System.getProperty("jconsole.showOutputViewer") != null) {
0N/A OutputViewer.init();
0N/A }
0N/A
0N/A while (args.length - argIndex > 0 && args[argIndex].startsWith("-")) {
0N/A String arg = args[argIndex++];
0N/A if (arg.equals("-h") ||
0N/A arg.equals("-help") ||
0N/A arg.equals("-?")) {
0N/A
0N/A usage();
0N/A return;
0N/A } else if (arg.startsWith("-interval=")) {
0N/A try {
0N/A updateInterval = Integer.parseInt(arg.substring(10)) *
0N/A 1000;
0N/A } catch (NumberFormatException ex) {
0N/A usage();
0N/A return;
0N/A }
0N/A } else if (arg.equals("-pluginpath")) {
0N/A if (argIndex < args.length && !args[argIndex].startsWith("-")) {
0N/A pluginPath = args[argIndex++];
0N/A } else {
0N/A // Invalid argument
0N/A usage();
0N/A return;
0N/A }
0N/A } else if (arg.equals("-notile")) {
0N/A noTile = true;
0N/A } else if (arg.equals("-version")) {
0N/A Version.print(System.err);
0N/A return;
0N/A } else if (arg.equals("-debug")) {
0N/A debug = true;
0N/A } else if (arg.equals("-fullversion")) {
0N/A Version.printFullVersion(System.err);
0N/A return;
0N/A } else {
0N/A // Unknown switch
0N/A usage();
0N/A return;
0N/A }
0N/A }
0N/A
0N/A if (System.getProperty("jconsole.showUnsupported") != null) {
0N/A hotspot = true;
0N/A }
0N/A
0N/A List<String> urls = new ArrayList<String>();
0N/A List<String> hostNames = new ArrayList<String>();
0N/A List<Integer> ports = new ArrayList<Integer>();
0N/A List<LocalVirtualMachine> vms = new ArrayList<LocalVirtualMachine>();
0N/A
0N/A for (int i = argIndex; i < args.length; i++) {
0N/A String arg = args[i];
0N/A if (isValidRemoteString(arg)) {
0N/A if (arg.startsWith(ROOT_URL)) {
0N/A urls.add(arg);
0N/A } else if (arg.matches(".*:[0-9]*")) {
0N/A int p = arg.lastIndexOf(':');
0N/A hostNames.add(arg.substring(0, p));
0N/A try {
0N/A ports.add(Integer.parseInt(arg.substring(p+1)));
0N/A } catch (NumberFormatException ex) {
0N/A usage();
0N/A return;
0N/A }
0N/A }
0N/A } else {
0N/A if (!isLocalAttachAvailable()) {
0N/A System.err.println("Local process monitoring is not supported");
0N/A return;
0N/A }
0N/A try {
0N/A int vmid = Integer.parseInt(arg);
0N/A LocalVirtualMachine lvm =
0N/A LocalVirtualMachine.getLocalVirtualMachine(vmid);
0N/A if (lvm == null) {
0N/A System.err.println("Invalid process id:" + vmid);
0N/A return;
0N/A }
0N/A vms.add(lvm);
0N/A } catch (NumberFormatException ex) {
0N/A usage();
0N/A return;
0N/A }
0N/A }
0N/A }
0N/A
0N/A mainInit(urls, hostNames, ports, vms, proxyClient, noTile, hotspot);
0N/A }
0N/A
0N/A public static boolean isDebug() {
0N/A return debug;
0N/A }
0N/A
0N/A private static void dbgStackTrace(Exception ex) {
0N/A if (debug) {
0N/A ex.printStackTrace();
0N/A }
0N/A }
0N/A
0N/A private static final boolean localAttachmentSupported;
0N/A static {
0N/A boolean supported;
0N/A try {
0N/A Class.forName("com.sun.tools.attach.VirtualMachine");
0N/A Class.forName("sun.management.ConnectorAddressLink");
0N/A supported = true;
0N/A } catch (NoClassDefFoundError x) {
0N/A supported = false;
0N/A } catch (ClassNotFoundException x) {
0N/A supported = false;
0N/A }
0N/A localAttachmentSupported = supported;
0N/A }
0N/A
0N/A public static boolean isLocalAttachAvailable() {
0N/A return localAttachmentSupported;
0N/A }
0N/A
0N/A
0N/A private static ServiceLoader<JConsolePlugin> pluginService = null;
0N/A
0N/A // Return a list of newly instantiated JConsolePlugin objects
0N/A static synchronized List<JConsolePlugin> getPlugins() {
0N/A if (pluginService == null) {
0N/A // First time loading and initializing the plugins
0N/A initPluginService(pluginPath);
0N/A } else {
0N/A // reload the plugin so that new instances will be created
0N/A pluginService.reload();
0N/A }
0N/A
0N/A List<JConsolePlugin> plugins = new ArrayList<JConsolePlugin>();
0N/A for (JConsolePlugin p : pluginService) {
0N/A plugins.add(p);
0N/A }
0N/A return plugins;
0N/A }
0N/A
0N/A private static void initPluginService(String pluginPath) {
0N/A if (pluginPath.length() > 0) {
0N/A try {
0N/A ClassLoader pluginCL = new URLClassLoader(pathToURLs(pluginPath));
0N/A ServiceLoader<JConsolePlugin> plugins =
0N/A ServiceLoader.load(JConsolePlugin.class, pluginCL);
0N/A // validate all plugins
0N/A for (JConsolePlugin p : plugins) {
0N/A if (isDebug()) {
0N/A System.out.println("Plugin " + p.getClass() + " loaded.");
0N/A }
0N/A }
0N/A pluginService = plugins;
0N/A } catch (ServiceConfigurationError e) {
0N/A // Error occurs during initialization of plugin
5335N/A System.out.println(Resources.format(Messages.FAIL_TO_LOAD_PLUGIN,
0N/A e.getMessage()));
0N/A } catch (MalformedURLException e) {
0N/A if (JConsole.isDebug()) {
0N/A e.printStackTrace();
0N/A }
5335N/A System.out.println(Resources.format(Messages.INVALID_PLUGIN_PATH,
0N/A e.getMessage()));
0N/A }
0N/A }
0N/A
0N/A if (pluginService == null) {
0N/A initEmptyPlugin();
0N/A }
0N/A }
0N/A
0N/A private static void initEmptyPlugin() {
0N/A ClassLoader pluginCL = new URLClassLoader(new URL[0]);
0N/A pluginService = ServiceLoader.load(JConsolePlugin.class, pluginCL);
0N/A }
0N/A
0N/A /**
0N/A * Utility method for converting a search path string to an array
0N/A * of directory and JAR file URLs.
0N/A *
0N/A * @param path the search path string
0N/A * @return the resulting array of directory and JAR file URLs
0N/A */
0N/A private static URL[] pathToURLs(String path) throws MalformedURLException {
0N/A String[] names = path.split(File.pathSeparator);
0N/A URL[] urls = new URL[names.length];
0N/A int count = 0;
0N/A for (String f : names) {
0N/A URL url = fileToURL(new File(f));
0N/A urls[count++] = url;
0N/A }
0N/A return urls;
0N/A }
0N/A
0N/A /**
0N/A * Returns the directory or JAR file URL corresponding to the specified
0N/A * local file name.
0N/A *
0N/A * @param file the File object
0N/A * @return the resulting directory or JAR file URL, or null if unknown
0N/A */
0N/A private static URL fileToURL(File file) throws MalformedURLException {
0N/A String name;
0N/A try {
0N/A name = file.getCanonicalPath();
0N/A } catch (IOException e) {
0N/A name = file.getAbsolutePath();
0N/A }
0N/A name = name.replace(File.separatorChar, '/');
0N/A if (!name.startsWith("/")) {
0N/A name = "/" + name;
0N/A }
0N/A // If the file does not exist, then assume that it's a directory
0N/A if (!file.isFile()) {
0N/A name = name + "/";
0N/A }
0N/A return new URL("file", "", name);
0N/A }
0N/A
0N/A
0N/A private static class FixedJRootPane extends JRootPane {
0N/A public void updateUI() {
0N/A updateLafValues();
0N/A super.updateUI();
0N/A }
0N/A
0N/A /**
0N/A * The revalidate method seems to be the only one that gets
0N/A * called whenever there is a change of L&F or change of theme
0N/A * in Windows L&F and GTK L&F.
0N/A */
0N/A @Override
0N/A public void revalidate() {
0N/A // Workaround for Swing bug where the titledborder in both
0N/A // GTK and Windows L&F's use calculated colors instead of
0N/A // the highlight/shadow colors from the theme.
0N/A //
0N/A // Putting null removes any previous override and causes a
0N/A // fallback to the current L&F's value.
0N/A UIManager.put("TitledBorder.border", null);
0N/A Border border = UIManager.getBorder("TitledBorder.border");
0N/A if (border instanceof BorderUIResource.EtchedBorderUIResource) {
0N/A Color highlight = UIManager.getColor("ToolBar.highlight");
0N/A Color shadow = UIManager.getColor("ToolBar.shadow");
0N/A border = new BorderUIResource.EtchedBorderUIResource(highlight,
0N/A shadow);
0N/A UIManager.put("TitledBorder.border", border);
0N/A }
0N/A
0N/A if (IS_GTK) {
0N/A // Workaround for Swing bug where the titledborder in
0N/A // GTK L&F use hardcoded color and font for the title
0N/A // instead of getting them from the theme.
0N/A UIManager.put("TitledBorder.titleColor",
0N/A UIManager.getColor("Label.foreground"));
0N/A UIManager.put("TitledBorder.font",
0N/A UIManager.getFont("Label.font"));
0N/A }
0N/A super.revalidate();
0N/A }
0N/A }
0N/A}