alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (Agent.java)

This example Java source code file (Agent.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

agentconfigurationerror, class, couldn\'t, exception, ioexception, jmx, jmxconnectorserver, management, method, net, network, properties, reflection, runtimeexception, snmp_port, string, stringbuffer, unsupported, unsupportedoperationexception, util

The Agent.java Java example source code

/*
 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package sun.management;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;

import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXServiceURL;

import static sun.management.AgentConfigurationError.*;
import sun.management.jmxremote.ConnectorBootstrap;
import sun.management.jdp.JdpController;
import sun.management.jdp.JdpException;
import sun.misc.VMSupport;

/**
 * This Agent is started by the VM when -Dcom.sun.management.snmp or
 * -Dcom.sun.management.jmxremote is set. This class will be loaded by the
 * system class loader. Also jmx framework could be started by jcmd
 */
public class Agent {
    // management properties

    private static Properties mgmtProps;
    private static ResourceBundle messageRB;
    private static final String CONFIG_FILE =
            "com.sun.management.config.file";
    private static final String SNMP_PORT =
            "com.sun.management.snmp.port";
    private static final String JMXREMOTE =
            "com.sun.management.jmxremote";
    private static final String JMXREMOTE_PORT =
            "com.sun.management.jmxremote.port";
    private static final String RMI_PORT =
            "com.sun.management.jmxremote.rmi.port";
    private static final String ENABLE_THREAD_CONTENTION_MONITORING =
            "com.sun.management.enableThreadContentionMonitoring";
    private static final String LOCAL_CONNECTOR_ADDRESS_PROP =
            "com.sun.management.jmxremote.localConnectorAddress";
    private static final String SNMP_ADAPTOR_BOOTSTRAP_CLASS_NAME =
            "sun.management.snmp.AdaptorBootstrap";

    private static final String JDP_DEFAULT_ADDRESS = "224.0.23.178";
    private static final int JDP_DEFAULT_PORT = 7095;

    // The only active agent allowed
    private static JMXConnectorServer jmxServer = null;

    // Parse string com.sun.management.prop=xxx,com.sun.management.prop=yyyy
    // and return property set if args is null or empty
    // return empty property set
    private static Properties parseString(String args) {
        Properties argProps = new Properties();
        if (args != null) {
            for (String option : args.split(",")) {
                String s[] = option.split("=", 2);
                String name = s[0].trim();
                String value = (s.length > 1) ? s[1].trim() : "";

                if (!name.startsWith("com.sun.management.")) {
                    error(INVALID_OPTION, name);
                }

                argProps.setProperty(name, value);
            }
        }

        return argProps;
    }

    // invoked by -javaagent or -Dcom.sun.management.agent.class
    public static void premain(String args) throws Exception {
        agentmain(args);
    }

    // invoked by attach mechanism
    public static void agentmain(String args) throws Exception {
        if (args == null || args.length() == 0) {
            args = JMXREMOTE;           // default to local management
        }

        Properties arg_props = parseString(args);

        // Read properties from the config file
        Properties config_props = new Properties();
        String fname = arg_props.getProperty(CONFIG_FILE);
        readConfiguration(fname, config_props);

        // Arguments override config file
        config_props.putAll(arg_props);
        startAgent(config_props);
    }

    // jcmd ManagementAgent.start_local entry point
    // Also called due to command-line via startAgent()
    private static synchronized void startLocalManagementAgent() {
        Properties agentProps = VMSupport.getAgentProperties();

        // start local connector if not started
        if (agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP) == null) {
            JMXConnectorServer cs = ConnectorBootstrap.startLocalConnectorServer();
            String address = cs.getAddress().toString();
            // Add the local connector address to the agent properties
            agentProps.put(LOCAL_CONNECTOR_ADDRESS_PROP, address);

            try {
                // export the address to the instrumentation buffer
                ConnectorAddressLink.export(address);
            } catch (Exception x) {
                // Connector server started but unable to export address
                // to instrumentation buffer - non-fatal error.
                warning(EXPORT_ADDRESS_FAILED, x.getMessage());
            }
        }
    }

    // jcmd ManagementAgent.start entry point
    // This method starts the remote JMX agent and starts neither
    // the local JMX agent nor the SNMP agent
    // @see #startLocalManagementAgent and also @see #startAgent.
    private static synchronized void startRemoteManagementAgent(String args) throws Exception {
        if (jmxServer != null) {
            throw new RuntimeException(getText(INVALID_STATE, "Agent already started"));
        }

        Properties argProps = parseString(args);
        Properties configProps = new Properties();

        // Load the management properties from the config file
        // if config file is not specified readConfiguration implicitly
        // reads <java.home>/lib/management/management.properties

        String fname = System.getProperty(CONFIG_FILE);
        readConfiguration(fname, configProps);

        // management properties can be overridden by system properties
        // which take precedence
        Properties sysProps = System.getProperties();
        synchronized (sysProps) {
            configProps.putAll(sysProps);
        }

        // if user specifies config file into command line for either
        // jcmd utilities or attach command it overrides properties set in
        // command line at the time of VM start
        String fnameUser = argProps.getProperty(CONFIG_FILE);
        if (fnameUser != null) {
            readConfiguration(fnameUser, configProps);
        }

        // arguments specified in command line of jcmd utilities
        // override both system properties and one set by config file
        // specified in jcmd command line
        configProps.putAll(argProps);

        // jcmd doesn't allow to change ThreadContentionMonitoring, but user
        // can specify this property inside config file, so enable optional
        // monitoring functionality if this property is set
        final String enableThreadContentionMonitoring =
                configProps.getProperty(ENABLE_THREAD_CONTENTION_MONITORING);

        if (enableThreadContentionMonitoring != null) {
            ManagementFactory.getThreadMXBean().
                    setThreadContentionMonitoringEnabled(true);
        }

        String jmxremotePort = configProps.getProperty(JMXREMOTE_PORT);
        if (jmxremotePort != null) {
            jmxServer = ConnectorBootstrap.
                    startRemoteConnectorServer(jmxremotePort, configProps);

            startDiscoveryService(configProps);
        }
    }

    private static synchronized void stopRemoteManagementAgent() throws Exception {

        JdpController.stopDiscoveryService();

        if (jmxServer != null) {
            ConnectorBootstrap.unexportRegistry();

            // Attempt to stop already stopped agent
            // Don't cause any errors.
            jmxServer.stop();
            jmxServer = null;
        }
    }

    private static void startAgent(Properties props) throws Exception {
        String snmpPort = props.getProperty(SNMP_PORT);
        String jmxremote = props.getProperty(JMXREMOTE);
        String jmxremotePort = props.getProperty(JMXREMOTE_PORT);

        // Enable optional monitoring functionality if requested
        final String enableThreadContentionMonitoring =
                props.getProperty(ENABLE_THREAD_CONTENTION_MONITORING);
        if (enableThreadContentionMonitoring != null) {
            ManagementFactory.getThreadMXBean().
                    setThreadContentionMonitoringEnabled(true);
        }

        try {
            if (snmpPort != null) {
                loadSnmpAgent(snmpPort, props);
            }

            /*
             * If the jmxremote.port property is set then we start the
             * RMIConnectorServer for remote M&M.
             *
             * If the jmxremote or jmxremote.port properties are set then
             * we start a RMIConnectorServer for local M&M. The address
             * of this "local" server is exported as a counter to the jstat
             * instrumentation buffer.
             */
            if (jmxremote != null || jmxremotePort != null) {
                if (jmxremotePort != null) {
                    jmxServer = ConnectorBootstrap.
                            startRemoteConnectorServer(jmxremotePort, props);
                    startDiscoveryService(props);
                }
                startLocalManagementAgent();
            }

        } catch (AgentConfigurationError e) {
            error(e.getError(), e.getParams());
        } catch (Exception e) {
            error(e);
        }
    }

    private static void startDiscoveryService(Properties props)
            throws IOException {
        // Start discovery service if requested
        String discoveryPort = props.getProperty("com.sun.management.jdp.port");
        String discoveryAddress = props.getProperty("com.sun.management.jdp.address");
        String discoveryShouldStart = props.getProperty("com.sun.management.jmxremote.autodiscovery");

        // Decide whether we should start autodicovery service.
        // To start autodiscovery following conditions should be met:
        // autodiscovery==true OR (autodicovery==null AND jdp.port != NULL)

        boolean shouldStart = false;
        if (discoveryShouldStart == null){
            shouldStart = (discoveryPort != null);
        }
        else{
            try{
               shouldStart = Boolean.parseBoolean(discoveryShouldStart);
            } catch (NumberFormatException e) {
                throw new AgentConfigurationError("Couldn't parse autodiscovery argument");
            }
        }

        if (shouldStart) {
            // port and address are required arguments and have no default values
            InetAddress address;
            try {
                address = (discoveryAddress == null) ?
                        InetAddress.getByName(JDP_DEFAULT_ADDRESS) : InetAddress.getByName(discoveryAddress);
            } catch (UnknownHostException e) {
                throw new AgentConfigurationError("Unable to broadcast to requested address", e);
            }

            int port = JDP_DEFAULT_PORT;
            if (discoveryPort != null) {
               try {
                  port = Integer.parseInt(discoveryPort);
               } catch (NumberFormatException e) {
                 throw new AgentConfigurationError("Couldn't parse JDP port argument");
               }
            }

            // Rebuilding service URL to broadcast it
            String jmxremotePort = props.getProperty(JMXREMOTE_PORT);
            String rmiPort = props.getProperty(RMI_PORT);

            JMXServiceURL url = jmxServer.getAddress();
            String hostname = url.getHost();

            String jmxUrlStr = (rmiPort != null)
                    ? String.format(
                    "service:jmx:rmi://%s:%s/jndi/rmi://%s:%s/jmxrmi",
                    hostname, rmiPort, hostname, jmxremotePort)
                    : String.format(
                    "service:jmx:rmi:///jndi/rmi://%s:%s/jmxrmi", hostname, jmxremotePort);

            String instanceName = props.getProperty("com.sun.management.jdp.name");

            try{
               JdpController.startDiscoveryService(address, port, instanceName, jmxUrlStr);
            }
            catch(JdpException e){
                throw new AgentConfigurationError("Couldn't start JDP service", e);
            }
        }
    }

    public static Properties loadManagementProperties() {
        Properties props = new Properties();

        // Load the management properties from the config file

        String fname = System.getProperty(CONFIG_FILE);
        readConfiguration(fname, props);

        // management properties can be overridden by system properties
        // which take precedence
        Properties sysProps = System.getProperties();
        synchronized (sysProps) {
            props.putAll(sysProps);
        }

        return props;
    }

    public static synchronized Properties getManagementProperties() {
        if (mgmtProps == null) {
            String configFile = System.getProperty(CONFIG_FILE);
            String snmpPort = System.getProperty(SNMP_PORT);
            String jmxremote = System.getProperty(JMXREMOTE);
            String jmxremotePort = System.getProperty(JMXREMOTE_PORT);

            if (configFile == null && snmpPort == null
                    && jmxremote == null && jmxremotePort == null) {
                // return if out-of-the-management option is not specified
                return null;
            }
            mgmtProps = loadManagementProperties();
        }
        return mgmtProps;
    }

    private static void loadSnmpAgent(String snmpPort, Properties props) {
        try {
            // invoke the following through reflection:
            //     AdaptorBootstrap.initialize(snmpPort, props);
            final Class<?> adaptorClass =
                    Class.forName(SNMP_ADAPTOR_BOOTSTRAP_CLASS_NAME, true, null);
            final Method initializeMethod =
                    adaptorClass.getMethod("initialize",
                    String.class, Properties.class);
            initializeMethod.invoke(null, snmpPort, props);
        } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException x) {
            // snmp runtime doesn't exist - initialization fails
            throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT, x);
        } catch (InvocationTargetException x) {
            final Throwable cause = x.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            } else if (cause instanceof Error) {
                throw (Error) cause;
            }
            // should not happen...
            throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT, cause);
        }
    }

    // read config file and initialize the properties
    private static void readConfiguration(String fname, Properties p) {
        if (fname == null) {
            String home = System.getProperty("java.home");
            if (home == null) {
                throw new Error("Can't find java.home ??");
            }
            StringBuffer defaultFileName = new StringBuffer(home);
            defaultFileName.append(File.separator).append("lib");
            defaultFileName.append(File.separator).append("management");
            defaultFileName.append(File.separator).append("management.properties");
            // Set file name
            fname = defaultFileName.toString();
        }
        final File configFile = new File(fname);
        if (!configFile.exists()) {
            error(CONFIG_FILE_NOT_FOUND, fname);
        }

        InputStream in = null;
        try {
            in = new FileInputStream(configFile);
            BufferedInputStream bin = new BufferedInputStream(in);
            p.load(bin);
        } catch (FileNotFoundException e) {
            error(CONFIG_FILE_OPEN_FAILED, e.getMessage());
        } catch (IOException e) {
            error(CONFIG_FILE_OPEN_FAILED, e.getMessage());
        } catch (SecurityException e) {
            error(CONFIG_FILE_ACCESS_DENIED, fname);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    error(CONFIG_FILE_CLOSE_FAILED, fname);
                }
            }
        }
    }

    public static void startAgent() throws Exception {
        String prop = System.getProperty("com.sun.management.agent.class");

        // -Dcom.sun.management.agent.class not set so read management
        // properties and start agent
        if (prop == null) {
            // initialize management properties
            Properties props = getManagementProperties();
            if (props != null) {
                startAgent(props);
            }
            return;
        }

        // -Dcom.sun.management.agent.class=<agent classname>:
        String[] values = prop.split(":");
        if (values.length < 1 || values.length > 2) {
            error(AGENT_CLASS_INVALID, "\"" + prop + "\"");
        }
        String cname = values[0];
        String args = (values.length == 2 ? values[1] : null);

        if (cname == null || cname.length() == 0) {
            error(AGENT_CLASS_INVALID, "\"" + prop + "\"");
        }

        if (cname != null) {
            try {
                // Instantiate the named class.
                // invoke the premain(String args) method
                Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(cname);
                Method premain = clz.getMethod("premain",
                        new Class<?>[]{String.class});
                premain.invoke(null, /* static */
                        new Object[]{args});
            } catch (ClassNotFoundException ex) {
                error(AGENT_CLASS_NOT_FOUND, "\"" + cname + "\"");
            } catch (NoSuchMethodException ex) {
                error(AGENT_CLASS_PREMAIN_NOT_FOUND, "\"" + cname + "\"");
            } catch (SecurityException ex) {
                error(AGENT_CLASS_ACCESS_DENIED);
            } catch (Exception ex) {
                String msg = (ex.getCause() == null
                        ? ex.getMessage()
                        : ex.getCause().getMessage());
                error(AGENT_CLASS_FAILED, msg);
            }
        }
    }

    public static void error(String key) {
        String keyText = getText(key);
        System.err.print(getText("agent.err.error") + ": " + keyText);
        throw new RuntimeException(keyText);
    }

    public static void error(String key, String[] params) {
        if (params == null || params.length == 0) {
            error(key);
        } else {
            StringBuffer message = new StringBuffer(params[0]);
            for (int i = 1; i < params.length; i++) {
                message.append(" " + params[i]);
            }
            error(key, message.toString());
        }
    }

    public static void error(String key, String message) {
        String keyText = getText(key);
        System.err.print(getText("agent.err.error") + ": " + keyText);
        System.err.println(": " + message);
        throw new RuntimeException(keyText);
    }

    public static void error(Exception e) {
        e.printStackTrace();
        System.err.println(getText(AGENT_EXCEPTION) + ": " + e.toString());
        throw new RuntimeException(e);
    }

    public static void warning(String key, String message) {
        System.err.print(getText("agent.err.warning") + ": " + getText(key));
        System.err.println(": " + message);
    }

    private static void initResource() {
        try {
            messageRB =
                    ResourceBundle.getBundle("sun.management.resources.agent");
        } catch (MissingResourceException e) {
            throw new Error("Fatal: Resource for management agent is missing");
        }
    }

    public static String getText(String key) {
        if (messageRB == null) {
            initResource();
        }
        try {
            return messageRB.getString(key);
        } catch (MissingResourceException e) {
            return "Missing management agent resource bundle: key = \"" + key + "\"";
        }
    }

    public static String getText(String key, String... args) {
        if (messageRB == null) {
            initResource();
        }
        String format = messageRB.getString(key);
        if (format == null) {
            format = "missing resource key: key = \"" + key + "\", "
                    + "arguments = \"{0}\", \"{1}\", \"{2}\"";
        }
        return MessageFormat.format(format, (Object[]) args);
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java Agent.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.