| // ======================================================================== |
| // Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. |
| // ======================================================================== |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // and Apache License v2.0 which accompanies this distribution. |
| // |
| // The Eclipse Public License is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // The Apache License v2.0 is available at |
| // http://www.opensource.org/licenses/apache2.0.php |
| // |
| // You may elect to redistribute this code under either of these licenses. |
| // ======================================================================== |
| |
| [[using-jmx]] |
| === Using JMX with Jetty |
| |
| Jetty JMX integration uses the platform MBean server implementation that Java VM provides. |
| The integration is based on the `ObjectMBean` implementation of `DynamicMBean`. |
| This implementation allows you to wrap an arbitrary POJO in an MBean and annotate it appropriately to expose it via JMX. |
| See xref:jetty-jmx-annotations[]. |
| |
| The `MBeanContainer` implementation of the `Container.Listener` interface coordinates creation of MBeans. |
| The Jetty Server and it's components use a link:{JDURL}/org/eclipse/jetty/util/component/Container.html[Container] to maintain a containment tree of components and to support notification of changes to that tree. |
| The `MBeanContainer` class listens for Container events and creates and destroys MBeans as required to wrap all Jetty components. |
| |
| You can access the MBeans that Jetty publishes both through built-in Java VM connector via JConsole or JMC, or by registering a remote JMX connector and using a remote JMX agent to monitor Jetty. |
| |
| [[configuring-jmx]] |
| ==== Configuring JMX |
| |
| This guide describes how to initialize and configure the Jetty JMX integration. |
| |
| To monitor an application using JMX, perform the following steps: |
| |
| * Configure the application to instantiate an MBean container. |
| * Instrument objects to be MBeans. |
| * Provide access for JMX agents to MBeans. |
| |
| [[accessing-jetty-mbeans]] |
| ===== Using JConsole to Access Jetty MBeans |
| |
| The simplest way to access the MBeans that Jetty publishes is to use the http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html[JConsole utility] the Java Virtual Machine supplies. |
| See xref:jetty-jconsole[] for instructions on how to configure JVM for use with JConsole or JMC. |
| |
| To access Jetty MBeans via JConsole or JMC, you must: |
| |
| * Enable the registration of Jetty MBeans into the platform MBeanServer. |
| * Enable a `JMXConnectorServer` so that JConsole/JMC can connect and visualize the MBeans. |
| |
| [[registering-jetty-mbeans]] |
| ===== Registering Jetty MBeans |
| |
| Configuring Jetty JMX integration differs for standalone and embedded Jetty. |
| |
| [[jmx-standalone-jetty]] |
| ====== Standalone Jetty |
| |
| JMX is not enabled by default in the Jetty distribution. |
| To enable JMX in the Jetty distribution, run the following, where `{$jetty.home}` is the directory where you have the Jetty distribution located (see link:#startup-base-and-home[the documentation for Jetty base vs. home examples]): |
| |
| [source, screen, subs="{sub-order}"] |
| .... |
| $ java -jar {$jetty.home}/start.jar --add-to-start=jmx |
| .... |
| |
| Running the above command will append the available configurable elements of the JMX module to the `{$jetty.base}/start.ini` file. |
| If you are managing separate ini files for your modules in the distribution, use `--add-to-start.d=jmx` instead. |
| |
| If you wish to add remote access for JMX, you will also need to enable the JMX-Remote module: |
| |
| [source, screen, subs="{sub-order}"] |
| .... |
| $ java -jar {$jetty.home}/start.jar --add-to-start=jmx-remote |
| .... |
| |
| [[jmx-embedded-jetty]] |
| ====== Embedded Jetty |
| |
| When running Jetty embedded into an application, create and configure an MBeanContainer instance as follows: |
| |
| [source, java] |
| ---- |
| |
| Server server = new Server(); |
| |
| // Setup JMX |
| MBeanContainer mbContainer=new MBeanContainer(ManagementFactory.getPlatformMBeanServer()); |
| server.addEventListener(mbContainer); |
| server.addBean(mbContainer); |
| |
| // Add loggers MBean to server (will be picked up by MBeanContainer above) |
| server.addBean(Log.getLog()); |
| |
| ---- |
| |
| Notice that Jetty creates the `MBeanContainer` immediately after creating the Server, and immediately after registering it as an `EventListener` of the Server object (which is also a Container object). |
| |
| Because logging is initialized prior to the `MBeanContainer` (even before the Server itself), it is necessary to register the logger manually via `server.addBean()` so that the loggers may show up in the JMX tree. |
| |
| [[jmx-using-jetty-maven-plugin]] |
| ===== Using the Jetty Maven Plugin with JMX |
| |
| If you are using the link:#jetty-maven-plugin[Jetty Maven plugin] you should copy the `/etc/jetty-jmx.xml` file into your webapp project somewhere, such as `/src/etc,` then add a `<jettyconfig>` element to the plugin `<configuration>`: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <plugin> |
| <groupid>org.eclipse.jetty</groupid> |
| <artifactid>jetty-maven-plugin</artifactid> |
| <version>{VERSION}</version> |
| <configuration> |
| <scanintervalseconds>10</scanintervalseconds> |
| <jettyXml>src/etc/jetty-jmx.xml</jettyXml> |
| </configuration> |
| </plugin> |
| ---- |
| |
| |
| [[enabling-jmxconnectorserver-for-remote-access]] |
| ==== Enabling JMXConnectorServer for Remote Access |
| |
| There are two ways of enabling remote connectivity so that JConsole or JMC can connect to visualize MBeans. |
| |
| * Use the `com.sun.management.jmxremote` system property on the command line. |
| Unfortunately, this solution does not work well with firewalls and is not flexible. |
| * Use Jetty's `ConnectorServer` class. |
| To enable use of this class, uncomment the correspondent portion in `/etc/jetty-jmx.xml,` like this: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <New id="ConnectorServer" class="org.eclipse.jetty.jmx.ConnectorServer"> |
| <Arg> |
| <New class="javax.management.remote.JMXServiceURL"> |
| <Arg type="java.lang.String">rmi</Arg> |
| <Arg type="java.lang.String" /> |
| <Arg type="java.lang.Integer"><SystemProperty name="jetty.jmxrmiport" default="1099"/></Arg> |
| <Arg type="java.lang.String">/jndi/rmi://<SystemProperty name="jetty.jmxrmihost" default="localhost"/>:<SystemProperty name="jetty.jmxrmiport" default="1099"/>/jmxrmi</Arg> |
| </New> |
| </Arg> |
| <Arg>org.eclipse.jetty.jmx:name=rmiconnectorserver</Arg> |
| <Call name="start" /> |
| </New> |
| |
| ---- |
| |
| This configuration snippet starts an `RMIRegistry` and a `JMXConnectorServer` both on port 1099 (by default), so that firewalls should open just that one port to allow connections from JConsole or JMC. |
| |
| [[securing-remote-access]] |
| ==== Securing Remote Access |
| |
| `JMXConnectorServer` several options to restrict access. |
| For a complete guide to controlling authentication and authorization in JMX, see https://blogs.oracle.com/lmalventosa/entry/jmx_authentication_authorization[Authentication and Authorization in JMX RMI connectors] in Luis-Miguel Alventosa's blog. |
| |
| To restrict access to the `JMXConnectorServer`, you can use this configuration, where the `jmx.password` and `jmx.access` files have the format specified in the blog entry above: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| |
| <New id="ConnectorServer" class="org.eclipse.jetty.jmx.ConnectorServer"> |
| <Arg> |
| <New class="javax.management.remote.JMXServiceURL"> |
| <Arg type="java.lang.String">rmi</Arg> |
| <Arg type="java.lang.String" /> |
| <Arg type="java.lang.Integer"><SystemProperty name="jetty.jmxrmiport" default="1099"/></Arg> |
| <Arg type="java.lang.String">/jndi/rmi://<SystemProperty name="jetty.jmxrmihost" default="localhost"/>:<SystemProperty name="jetty.jmxrmiport" default="1099"/>/jmxrmi</Arg> |
| </New> |
| </Arg> |
| <Arg> |
| <Map> |
| <Entry> |
| <Item>jmx.remote.x.password.file</Item> |
| <Item> |
| <New class="java.lang.String"><Arg><Property name="jetty.home" default="." />/resources/jmx.password</Arg></New> |
| </Item> |
| </Entry> |
| <Entry> |
| <Item>jmx.remote.x.access.file</Item> |
| <Item> |
| <New class="java.lang.String"><Arg><Property name="jetty.home" default="." />/resources/jmx.access</Arg></New> |
| </Item> |
| </Entry> |
| </Map> |
| </Arg> |
| <Arg>org.eclipse.jetty.jmx:name=rmiconnectorserver</Arg> |
| <Call name="start" /> |
| </New> |
| |
| |
| ---- |
| |
| [[custom-monitor-applcation]] |
| ==== Custom Monitor Application |
| |
| Using the JMX API, you can also write a custom application to monitor your Jetty server. |
| To allow this application to connect to your Jetty server, you need to uncomment the last section of the `/etc/jetty-jmx.xml` configuration file and optionally modify the endpoint name. |
| Doing so creates a JMX HTTP connector and registers a JMX URL that outputs to the `Stderr` log. |
| |
| You should provide the URL that appears in the log to your monitor application in order to create an `MBeanServerConnection.` |
| You can use the same URL to connect to your Jetty instance from a remote machine using JConsole or JMC. |
| See the link:{GITBROWSEURL}/jetty-jmx/src/main/config/etc/jetty-jmx.xml[configuration file] for more details. |