You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Christopher Schultz <ch...@christopherschultz.net> on 2019/12/17 21:10:36 UTC

Re: [tomcat] branch master updated: Refactor JMX remote RMI registry creation

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Rémy,

On 11/14/19 07:39, remm@apache.org wrote:
> This is an automated email from the ASF dual-hosted git
> repository.
> 
> remm pushed a commit to branch master in repository
> https://gitbox.apache.org/repos/asf/tomcat.git
> 
> 
> The following commit(s) were added to refs/heads/master by this
> push: new 1fc9f58  Refactor JMX remote RMI registry creation 
> 1fc9f58 is described below
> 
> commit 1fc9f589dbdd8295cf313b2667ab041c425f99c3 Author: remm
> <re...@apache.org> AuthorDate: Thu Nov 14 13:39:31 2019 +0100
> 
> Refactor JMX remote RMI registry creation

I think modern JVMs do everything the JmxRemoteLifecycleListener has
been doing for us for a while. Maybe it's time to remove it?

It's version-dependent (and everyone I know is still stuck on 1.8 or
lower), but perhaps we should just get rid of all this cruft and
replace it with JVM-supported configuration, at least in newer
versions of Tomcat.

  -Dcom.sun.management.jmxremote.port
  -Dcom.sun.management.jmxremote.rmi.port

Source:
https://docs.oracle.com/javase/9/management/monitoring-and-management-us
ing-jmx-technology.htm#JSMGM-GUID-F08985BB-629A-4FBF-A0CB-8762DF7590E0

If that anchor doesn't work after a while, or for other versions of
Java, it's the section titled "Remote Monitoring and Management".

This handles the ports. If you need to use a hostname other than
127.0.0.1 or whatever "localhost" ends up being on the server (say,
because you are connecting through an encrypted tunnel), then you can se
t:

  -Djava.rmi.server.hostname

This basically re-writes the hostname put into the RMI stubs sent to
the JMX client. Note that whatever you use is JVM-wide and so it must
make sense to both clients operating on the server AND on the
remote-client (which may be tricky).

This is one of many reasons I always recommend against using JMX
directly for monitoring. It's much, much easier to use the
JMXProxyServlet to traverse firewalls, etc. It's nice to see that JVMs
are now supporting real authentication systems (e.g. LADP,
client-TLS-cert, etc.) but it's a little too late for that IMHO.

You can also set the binding interface with:

  -Dcom.sun.management.jmxremote.host

That should accept anything you can give to
InetAddress.getByName()[1]. This isn't documented anywhere in the
"Monitoring and Management Using JMX Technology" page for some reason,
but it's there in the code.

Note that:

  -Dcom.sun.management.jmxremote

... is no longer necessary

(Note that I haven't actually tried any of this myself yet.)

Am I correct that modern JVMs no longer require the
JmxRemoteLivecycleListener?

- -chris

[1] I had a bear of a time finding this:
    https://bugs.openjdk.java.net/browse/JDK-6425769

http://mail.openjdk.java.net/pipermail/hotspot-dev/2015-November/020717.
html

> --- .../mbeans/JmxRemoteLifecycleListener.java         | 65
> ++++++++++++++++------ webapps/docs/changelog.xml
> |  7 +++ 2 files changed, 56 insertions(+), 16 deletions(-)
> 
> diff --git
> a/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java
> b/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java 
> index 3e472d0..77a785d 100644 ---
> a/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java 
> +++
> b/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java 
> @@ -25,10 +25,11 @@ import java.net.MalformedURLException; import
> java.net.ServerSocket; import java.net.Socket; import
> java.net.UnknownHostException; +import java.rmi.AccessException; 
> import java.rmi.AlreadyBoundException; +import
> java.rmi.NotBoundException; +import java.rmi.Remote; import
> java.rmi.RemoteException; -import
> java.rmi.registry.LocateRegistry; -import
> java.rmi.registry.Registry; import
> java.rmi.server.RMIClientSocketFactory; import
> java.rmi.server.RMIServerSocketFactory; import java.util.HashMap; 
> @@ -417,18 +418,6 @@ public class JmxRemoteLifecycleListener
> extends SSLHostConfig implements Lifecyc RMIClientSocketFactory
> registryCsf, RMIServerSocketFactory registrySsf, 
> RMIClientSocketFactory serverCsf, RMIServerSocketFactory serverSsf)
> {
> 
> -        // Create the RMI registry -        Registry registry; -
> try { -            registry = LocateRegistry.createRegistry( -
> theRmiRegistryPort, registryCsf, registrySsf); -        } catch
> (RemoteException e) { -            log.error(sm.getString( -
> "jmxRemoteLifecycleListener.createRegistryFailed", -
> serverName, Integer.toString(theRmiRegistryPort)), e); -
> return null; -        } - if (bindAddress == null) { bindAddress =
> "localhost"; } @@ -449,11 +438,20 @@ public class
> JmxRemoteLifecycleListener extends SSLHostConfig implements
> Lifecyc cs = new RMIConnectorServer(serviceUrl, theEnv, server, 
> ManagementFactory.getPlatformMBeanServer()); cs.start(); -
> registry.bind("jmxrmi", server.toStub()); +            Remote
> jmxServer = server.toStub(); +            // Create the RMI
> registry +            try { +                new
> JmxRegistry(theRmiRegistryPort, registryCsf, registrySsf, "jmxrmi",
> jmxServer); +            } catch (RemoteException e) { +
> log.error(sm.getString( +
> "jmxRemoteLifecycleListener.createRegistryFailed", +
> serverName, Integer.toString(theRmiRegistryPort)), e); +
> return null; +            } 
> log.info(sm.getString("jmxRemoteLifecycleListener.start", 
> Integer.toString(theRmiRegistryPort), 
> Integer.toString(theRmiServerPort), serverName)); -        } catch
> (IOException | AlreadyBoundException e) { +        } catch
> (IOException e) { log.error(sm.getString( 
> "jmxRemoteLifecycleListener.createServerFailed", serverName), e); 
> @@ -589,4 +587,39 @@ public class JmxRemoteLifecycleListener
> extends SSLHostConfig implements Lifecyc return true; } } + + +
> private static class JmxRegistry extends
> sun.rmi.registry.RegistryImpl { +        private static final long
> serialVersionUID = -3772054804656428217L; +        private final
> String jmxName; +        private final Remote jmxServer; +
> public JmxRegistry(int port, RMIClientSocketFactory csf, +
> RMIServerSocketFactory ssf, String jmxName, Remote jmxServer)
> throws RemoteException { +            super(port, csf, ssf); +
> this.jmxName = jmxName; +            this.jmxServer = jmxServer; +
> } +        @Override +        public Remote lookup(String name) +
> throws RemoteException, NotBoundException { +            return
> (jmxName.equals(name)) ? jmxServer : null; +        } +
> @Override +        public void bind(String name, Remote obj) +
> throws RemoteException, AlreadyBoundException, AccessException { +
> } +        @Override +        public void unbind(String name) +
> throws RemoteException, NotBoundException, AccessException { +
> } +        @Override +        public void rebind(String name,
> Remote obj) +                throws RemoteException,
> AccessException { +        } +        @Override +        public
> String[] list() throws RemoteException { +            return new
> String[] { jmxName }; +        } +    } + } diff --git
> a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index
> efc0ab6..9bbff4c 100644 --- a/webapps/docs/changelog.xml +++
> b/webapps/docs/changelog.xml @@ -45,6 +45,13 @@ issues do not "pop
> up" wrt. others). --> <section name="Tomcat 9.0.29 (markt)"
> rtext="in development"> +  <subsection name="Catalina"> +
> <changelog> +      <fix> +       Refactor JMX remote RMI registry
> creation. (remm) +      </fix> +    </changelog> +  </subsection> 
> </section> <section name="Tomcat 9.0.28 (markt)" rtext="release in
> progress"> <subsection name="Catalina">
> 
> 
> ---------------------------------------------------------------------
>
> 
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
> 
-----BEGIN PGP SIGNATURE-----
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl35REwACgkQHPApP6U8
pFgalg/+KXEqkcGk2sNSWOHch6VgmoSXTX/380xBc24c1nnN8o+JfMaBbvarRvGB
DHw8IbAs/h9yq1fw3Ym7yffh2ZJN9o6TZt38cDdfxWphB+Vr1cqr1UrgLaj2QTm2
22UOqlKYnHvGSo9fvNwQ+r8rT7Dz6YabSrrCec+ukaMvK848173+vpQN2mZ/+uLk
++/HnK0qhWAxzvfHe1/V5HbeQlhxBTHHPc21JaEIDxSFFp9dnBjvnz+tm60OHL0n
44XskeV7nAdWgdvtjeSzkJaCFAwQPvM0UbxH9pJMKs2K1W8EXsaGbM0Q4Jf5RoK8
4BqFA2VaH0y+w1nyH/Q9tsEcSLDxRu8mIyCPk9FjdQWGpCKK4zU2DntrlDqZY4aw
HEMjrCViBFeEwaUjEBb+7ScJtLVadTWW+j1a6VdonSHYyGn5LTsENDVIiNU0KGCu
VW1ce6We1nW2bqsbocAQosReCLPzjFCztW/A9fqsgk7liXHBGpqWqF/Jst1crL1x
JQSfFSX6No/GNGqi+Hv1BHsCBjU+iZ0u+3nil8Sh2SN9R4ewsliGidC30wxW7v1V
iOqGmqBCy/UMsZ4XDMaCWCKFDGHYtKhnTYwng7UpBEkeyEfIIbHdd3xIBo5sCvt6
olHHKPguC3ANm8d9QH2AWpbRTystFZsA7eGV652jxopvNNnxL/Q=
=ZkwZ
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: [tomcat] branch master updated: Refactor JMX remote RMI registry creation

Posted by Rémy Maucherat <re...@apache.org>.
On Tue, Dec 17, 2019 at 10:10 PM Christopher Schultz <
chris@christopherschultz.net> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
>
> Rémy,
>
> On 11/14/19 07:39, remm@apache.org wrote:
> > This is an automated email from the ASF dual-hosted git
> > repository.
> >
> > remm pushed a commit to branch master in repository
> > https://gitbox.apache.org/repos/asf/tomcat.git
> >
> >
> > The following commit(s) were added to refs/heads/master by this
> > push: new 1fc9f58  Refactor JMX remote RMI registry creation
> > 1fc9f58 is described below
> >
> > commit 1fc9f589dbdd8295cf313b2667ab041c425f99c3 Author: remm
> > <re...@apache.org> AuthorDate: Thu Nov 14 13:39:31 2019 +0100
> >
> > Refactor JMX remote RMI registry creation
>
> I think modern JVMs do everything the JmxRemoteLifecycleListener has
> been doing for us for a while. Maybe it's time to remove it?
>
> It's version-dependent (and everyone I know is still stuck on 1.8 or
> lower), but perhaps we should just get rid of all this cruft and
> replace it with JVM-supported configuration, at least in newer
> versions of Tomcat.
>
>   -Dcom.sun.management.jmxremote.port
>   -Dcom.sun.management.jmxremote.rmi.port
>
> Source:
> https://docs.oracle.com/javase/9/management/monitoring-and-management-us
> ing-jmx-technology.htm#JSMGM-GUID-F08985BB-629A-4FBF-A0CB-8762DF7590E0
> <https://docs.oracle.com/javase/9/management/monitoring-and-management-using-jmx-technology.htm#JSMGM-GUID-F08985BB-629A-4FBF-A0CB-8762DF7590E0>
>
> If that anchor doesn't work after a while, or for other versions of
> Java, it's the section titled "Remote Monitoring and Management".
>
> This handles the ports. If you need to use a hostname other than
> 127.0.0.1 or whatever "localhost" ends up being on the server (say,
> because you are connecting through an encrypted tunnel), then you can se
> t:
>
>   -Djava.rmi.server.hostname
>
> This basically re-writes the hostname put into the RMI stubs sent to
> the JMX client. Note that whatever you use is JVM-wide and so it must
> make sense to both clients operating on the server AND on the
> remote-client (which may be tricky).
>

The main usefulness of the listener was to configure the bind address, so
it seems it would be covered. The SSL configuration could be nicer too, to
some extent.


>
> This is one of many reasons I always recommend against using JMX
> directly for monitoring. It's much, much easier to use the
> JMXProxyServlet to traverse firewalls, etc. It's nice to see that JVMs
> are now supporting real authentication systems (e.g. LADP,
> client-TLS-cert, etc.) but it's a little too late for that IMHO.
>

Well, you have jolokia for you then ;)

Rémy


>
> You can also set the binding interface with:
>
>   -Dcom.sun.management.jmxremote.host
>
> That should accept anything you can give to
> InetAddress.getByName()[1]. This isn't documented anywhere in the
> "Monitoring and Management Using JMX Technology" page for some reason,
> but it's there in the code.
>
> Note that:
>
>   -Dcom.sun.management.jmxremote
>
> ... is no longer necessary
>
> (Note that I haven't actually tried any of this myself yet.)
>
> Am I correct that modern JVMs no longer require the
> JmxRemoteLivecycleListener?
>
> - -chris
>
> [1] I had a bear of a time finding this:
>     https://bugs.openjdk.java.net/browse/JDK-6425769
>
> http://mail.openjdk.java.net/pipermail/hotspot-dev/2015-November/020717.
> html
> <http://mail.openjdk.java.net/pipermail/hotspot-dev/2015-November/020717.html>
>
> > --- .../mbeans/JmxRemoteLifecycleListener.java         | 65
> > ++++++++++++++++------ webapps/docs/changelog.xml
> > |  7 +++ 2 files changed, 56 insertions(+), 16 deletions(-)
> >
> > diff --git
> > a/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java
> > b/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java
> > index 3e472d0..77a785d 100644 ---
> > a/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java
> > +++
> > b/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java
> > @@ -25,10 +25,11 @@ import java.net.MalformedURLException; import
> > java.net.ServerSocket; import java.net.Socket; import
> > java.net.UnknownHostException; +import java.rmi.AccessException;
> > import java.rmi.AlreadyBoundException; +import
> > java.rmi.NotBoundException; +import java.rmi.Remote; import
> > java.rmi.RemoteException; -import
> > java.rmi.registry.LocateRegistry; -import
> > java.rmi.registry.Registry; import
> > java.rmi.server.RMIClientSocketFactory; import
> > java.rmi.server.RMIServerSocketFactory; import java.util.HashMap;
> > @@ -417,18 +418,6 @@ public class JmxRemoteLifecycleListener
> > extends SSLHostConfig implements Lifecyc RMIClientSocketFactory
> > registryCsf, RMIServerSocketFactory registrySsf,
> > RMIClientSocketFactory serverCsf, RMIServerSocketFactory serverSsf)
> > {
> >
> > -        // Create the RMI registry -        Registry registry; -
> > try { -            registry = LocateRegistry.createRegistry( -
> > theRmiRegistryPort, registryCsf, registrySsf); -        } catch
> > (RemoteException e) { -            log.error(sm.getString( -
> > "jmxRemoteLifecycleListener.createRegistryFailed", -
> > serverName, Integer.toString(theRmiRegistryPort)), e); -
> > return null; -        } - if (bindAddress == null) { bindAddress =
> > "localhost"; } @@ -449,11 +438,20 @@ public class
> > JmxRemoteLifecycleListener extends SSLHostConfig implements
> > Lifecyc cs = new RMIConnectorServer(serviceUrl, theEnv, server,
> > ManagementFactory.getPlatformMBeanServer()); cs.start(); -
> > registry.bind("jmxrmi", server.toStub()); +            Remote
> > jmxServer = server.toStub(); +            // Create the RMI
> > registry +            try { +                new
> > JmxRegistry(theRmiRegistryPort, registryCsf, registrySsf, "jmxrmi",
> > jmxServer); +            } catch (RemoteException e) { +
> > log.error(sm.getString( +
> > "jmxRemoteLifecycleListener.createRegistryFailed", +
> > serverName, Integer.toString(theRmiRegistryPort)), e); +
> > return null; +            }
> > log.info(sm.getString("jmxRemoteLifecycleListener.start",
> > Integer.toString(theRmiRegistryPort),
> > Integer.toString(theRmiServerPort), serverName)); -        } catch
> > (IOException | AlreadyBoundException e) { +        } catch
> > (IOException e) { log.error(sm.getString(
> > "jmxRemoteLifecycleListener.createServerFailed", serverName), e);
> > @@ -589,4 +587,39 @@ public class JmxRemoteLifecycleListener
> > extends SSLHostConfig implements Lifecyc return true; } } + + +
> > private static class JmxRegistry extends
> > sun.rmi.registry.RegistryImpl { +        private static final long
> > serialVersionUID = -3772054804656428217L; +        private final
> > String jmxName; +        private final Remote jmxServer; +
> > public JmxRegistry(int port, RMIClientSocketFactory csf, +
> > RMIServerSocketFactory ssf, String jmxName, Remote jmxServer)
> > throws RemoteException { +            super(port, csf, ssf); +
> > this.jmxName = jmxName; +            this.jmxServer = jmxServer; +
> > } +        @Override +        public Remote lookup(String name) +
> > throws RemoteException, NotBoundException { +            return
> > (jmxName.equals(name)) ? jmxServer : null; +        } +
> > @Override +        public void bind(String name, Remote obj) +
> > throws RemoteException, AlreadyBoundException, AccessException { +
> > } +        @Override +        public void unbind(String name) +
> > throws RemoteException, NotBoundException, AccessException { +
> > } +        @Override +        public void rebind(String name,
> > Remote obj) +                throws RemoteException,
> > AccessException { +        } +        @Override +        public
> > String[] list() throws RemoteException { +            return new
> > String[] { jmxName }; +        } +    } + } diff --git
> > a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index
> > efc0ab6..9bbff4c 100644 --- a/webapps/docs/changelog.xml +++
> > b/webapps/docs/changelog.xml @@ -45,6 +45,13 @@ issues do not "pop
> > up" wrt. others). --> <section name="Tomcat 9.0.29 (markt)"
> > rtext="in development"> +  <subsection name="Catalina"> +
> > <changelog> +      <fix> +       Refactor JMX remote RMI registry
> > creation. (remm) +      </fix> +    </changelog> +  </subsection>
> > </section> <section name="Tomcat 9.0.28 (markt)" rtext="release in
> > progress"> <subsection name="Catalina">
> >
> >
> > ---------------------------------------------------------------------
> >
> >
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> > For additional commands, e-mail: dev-help@tomcat.apache.org
> >
> -----BEGIN PGP SIGNATURE-----
> Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/
>
> iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl35REwACgkQHPApP6U8
> pFgalg/+KXEqkcGk2sNSWOHch6VgmoSXTX/380xBc24c1nnN8o+JfMaBbvarRvGB
> DHw8IbAs/h9yq1fw3Ym7yffh2ZJN9o6TZt38cDdfxWphB+Vr1cqr1UrgLaj2QTm2
> 22UOqlKYnHvGSo9fvNwQ+r8rT7Dz6YabSrrCec+ukaMvK848173+vpQN2mZ/+uLk
> ++/HnK0qhWAxzvfHe1/V5HbeQlhxBTHHPc21JaEIDxSFFp9dnBjvnz+tm60OHL0n
> 44XskeV7nAdWgdvtjeSzkJaCFAwQPvM0UbxH9pJMKs2K1W8EXsaGbM0Q4Jf5RoK8
> 4BqFA2VaH0y+w1nyH/Q9tsEcSLDxRu8mIyCPk9FjdQWGpCKK4zU2DntrlDqZY4aw
> HEMjrCViBFeEwaUjEBb+7ScJtLVadTWW+j1a6VdonSHYyGn5LTsENDVIiNU0KGCu
> VW1ce6We1nW2bqsbocAQosReCLPzjFCztW/A9fqsgk7liXHBGpqWqF/Jst1crL1x
> JQSfFSX6No/GNGqi+Hv1BHsCBjU+iZ0u+3nil8Sh2SN9R4ewsliGidC30wxW7v1V
> iOqGmqBCy/UMsZ4XDMaCWCKFDGHYtKhnTYwng7UpBEkeyEfIIbHdd3xIBo5sCvt6
> olHHKPguC3ANm8d9QH2AWpbRTystFZsA7eGV652jxopvNNnxL/Q=
> =ZkwZ
> -----END PGP SIGNATURE-----
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
>
>

Re: [tomcat] branch master updated: Refactor JMX remote RMI registry creation

Posted by Mark Thomas <ma...@apache.org>.
On 17/12/2019 21:10, Christopher Schultz wrote:
> Rémy,
> 
> On 11/14/19 07:39, remm@apache.org wrote:
>> This is an automated email from the ASF dual-hosted git
>> repository.
> 
>> remm pushed a commit to branch master in repository
>> https://gitbox.apache.org/repos/asf/tomcat.git
> 
> 
>> The following commit(s) were added to refs/heads/master by this
>> push: new 1fc9f58  Refactor JMX remote RMI registry creation 
>> 1fc9f58 is described below
> 
>> commit 1fc9f589dbdd8295cf313b2667ab041c425f99c3 Author: remm
>> <re...@apache.org> AuthorDate: Thu Nov 14 13:39:31 2019 +0100
> 
>> Refactor JMX remote RMI registry creation
> 
> I think modern JVMs do everything the JmxRemoteLifecycleListener has
> been doing for us for a while. Maybe it's time to remove it?

Pressing the delete key is my favourite form of refactoring ;) so +1

This looks like another entry for the TOMCAT-NEXT.txt file to me.
Something along the lines of:
 - remove it in 10
 - deprecate in Tomcat < 10
 - rewrite the JMX docs to reference the JVM provided features in all
   versions

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org