Why Tomcat server is accessible thru jmxrmi port 1099 - java

My understanding is that tomcat server can be accessed thru jmxrmi if we configure following properties. Port can also be configured.
-Dcom.sun.management.jmxremote.port=30000
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.password.file=xyz
-Dcom.sun.management.jmxremote.access.file=xyz
After that tomcat server can be connected thru some jmx tools like jconsole or jvisualvm etc. But I also noticed that same tomcat server can also be connected on default jmxrmi port 1099. I havent configured anywhere port 1099. Even though if I comment out all above properties, I see tomcat still can be connected to on port 1099 on jvisualvm.
Please suggest, what might be enabling this connectivity on default port. And how can I disable this connectivity?
Possibly some other third party libraries in classpath might be doing it, but how to figure which one?

JMX uses two ports: one for the JMX connection (which you have set to port 30000) and another one for RMI communications. Java defaults to port 1099, but if it's in use, it will choose the first port available after 1099. In Java 8, you cannot explicitly set this port via system properties.
For later Java versions, you can use the system property com.sun.management.jmxremote.rmi.port.
Tomcat has a workaround for this. You can use the JmxRemoteLifecycleListener to set the rmiServerPortPlatform attribute. Set that to whatever port you prefer.
Note that you cannot disable this second port: it is required for JMX to operate properly.

Related

Force JMX of Apache ActiveMQ to only be accessible from localhost

I have a RHEL6 server running Apache ActiveMQ, and I cannot find a way to disable remote access to JMX.
I can disable JMX entirely, but that restricts the functionality of ActiveMQ, which uses JMX to access the broker to get status information, or communicate shutdown requests (ActiveMQ falls back to SIGKILL!).
I want to have ActiveMQ be accessible through JMX, but only from localhost.
According to Apache's website, remote connections should be disabled by default, but I'm able to connect to the default 1099 port from other machines. As far as I can tell, the settings for JMX are left as default.
I'm aware of a number similar questions, but proposed solutions haven't been working for me, in particular:
Adding -Dcom.sun.management.jmxremote.host=localhost and/or -Dcom.sun.management.jmxremote.local.only=true doesn't help
Adding -Djava.rmi.server.hostname=localhost also doesn't help
This even though this solution and some comments to it seem to indicate that the Java version I'm running (>8u102) fixes some known problems.
Some solutions talk about it being necessary to switch to "coding" (e.g., this or this) but it's unclear to me how such an approach could be used with ActiveMQ.
In bin/env (of the Apache ActiveMQ build) add this:
-Dcom.sun.management.jmxremote.host=127.0.0.1
Then observe that JMX port binds only to the localhost ip
% netstat -na | grep 1099
tcp4 0 0 127.0.0.1.11099 *.* LISTEN

Tomcat debugging not possible through eclipse

I've made a script called debug.sh and placed it under the bin directory (start it with ./debug.sh) to start Tomcat 8 in debugging mode:
set JPDA_ADDRESS=8000
set JPDA_TRANSPORT=dt_socket
set JAVA_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n
bash catalina.sh jpda start
But if it started, there is now message which says, that Tomcat is listening on port 8000. Also if I type
netstat -nat
there is no application listening on port 8000.
What exact configuration do I have to set, to remote debug my Tomcat 8 server which is running on a specific IP or do I have just a little problem in my script?
This answer has been updated following the comments, I did not understand the problem in the first place.
I guess you have followed that doc: this is about developing Tomcat itself.
I am not sure you are using the proper way to configure the port (I don't know your specific configuration details). In a standard environment, the ports are configured in the server.xml (note that several different ports are used by Tomcat for the different services).
To remotely monitor your server, you should use a JMX client. As far as I know, Eclipse doesn't include one (or at least not one documented) - you could code one as this is a Java specification (JSR262). You have one in a standard Java environement (JConsole). By default, JMX is not enabled on Tomcat. If you need to enable it, the fine way is to follow the doc.
Tomcat JMX monitoring and JConsole are both available in most versions of Tomcat and the Java runtime.
The following exchange seems to be about your problem.

How to find the default JMX port number?

I am running a Java application on Java 6 VM on a remote Windows XP, on which I can run jvisualvm.exe to connect to the running application automatically.
Now I need to connect that application from my local computer, but I don't know the JMX port number of the remote computer. Where can I find it? Or, must I restart that application with some VM parameters to specify the port number?
After reading the question How to find the JMX port in a server, I executed the command on the remote computer
netstat -apn
but got nothing.
Now I need to connect that application from my local computer, but I don't know the JMX port number of the remote computer. Where can I find it? Or, must I restart that application with some VM parameters to specify the port number?
By default JMX does not publish on a port unless you specify the arguments from this page: How to activate JMX...
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=localhost
NOTE: you need to be careful of the security ramifications of some of the above settings.
Also, if you are running you should be able to access any of those system properties to see if they have been set:
if (System.getProperty("com.sun.management.jmxremote") == null) {
System.out.println("JMX remote is disabled");
} else [
String portString = System.getProperty("com.sun.management.jmxremote.port");
if (portString != null) {
System.out.println("JMX running on port "
+ Integer.parseInt(portString));
}
}
Depending on how the server is connected, you might also have to specify the following parameter. As part of the initial JMX connection, jconsole connects up to the RMI port to determine which port the JMX server is running on. When you initially start up a JMX enabled application, it looks its own hostname to determine what address to return in that initial RMI transaction. If your hostname is not in /etc/hosts or if it is set to an incorrect interface address then you can override it with the following:
-Djava.rmi.server.hostname=<IP address>
As an aside, my SimpleJMX package allows you to define both the JMX server and the RMI port or set them both to the same port. The above port defined with com.sun.management.jmxremote.port is actually the RMI port. This tells the client what port the JMX server is running on.

VisualVM through firewalls - RMI troubleshooting

Sorry for this question which must have been asked many times, but I can't succeed in resolving my problem.
I've read a lot of blogs, sites, forums, .... and didn't find any solution in my case.
Case :
I need to connect VisualVM on my box to distant servers (tomcats, weblogics) for performance / threads / memory monitoring.
Those servers are installed on (physical or virtual) machines which are protected by a firewall.
Large intervals of ports are open in the firewall and can be used, but not all ports.
Tests
I've tried direct connections through JMX in VisualVM, using following JVM options on the server-side at server startup :
-Djava.rmi.server.hostname=[hostname]
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=[port]
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
I've precised the hostname because from my network the hostname and the IP address of the server are not the same than those from the network of the remote server.
No success, VisualVM always seems searching for an unknown server.
tried starting jstatd on the server-side on a port accessible (-p option) from my box (telnet on this port works), but when launching visualVM on this host with the jstatd port, it still seems waiting for something unreachable.... Same behavior with jps connecting to this remote host.
tried using the same tools on a server with less network protection, and it works. So I have seen the connections between my box and the server and they are done on ports different from what I've specified to jstatd.
I understand that this port is needed for first communication (kind of handshake) and real communications are done on other ports, but not predictible (ex: 60305, 55197, ...).
Not sure I understand very well how RMI works.
Please, help me, I'm going crazy !
Unfortunately JMX tries to open ports other than the one you configure. Just yesterday I succeeded connecting to tomcat behind firewall via JMX. The two tricky parts are:
put a file called jmxremote.access in CATALINA_HOME/conf, which contains the following lines:
monitorRole readonly
controlRole readwrite
in server.xml set the ports that will be used by jmx, via a special tomcat listener (catalina-jmx-remote.jar required in /lib):
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener"
rmiRegistryPortPlatform="9009" rmiServerPortPlatform="9010" />
Then open these two ports on the firewall. It works. But that's just for tomcat.
Another option is to use ssh tunnelling. In short - you connect via SSH and configure it to forward some local port (where the jmx client is running) to some ports on the other side of the tunnel.
References:
Connecting to JMX on Tomcat 6 through a firewall
Connecting MySQL server on Amazon EC2 instance using ssh tunnel
Here are the steps to do this:
Launch an ejstatd in your remote host this way (in ejstatd folder): mvn exec:java -Djava.rmi.server.hostname=[remote_host_name] -Dexec.args="-pr 1099 -ph 1100 -pv 1101" (used for "jstatd" type connection)
Launch your Java application with those additional Java parameters: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=1102 -Dcom.sun.management.jmxremote.rmi.port=1102 -Djava.rmi.server.hostname=[remote_host_name] (used for "JMX" type connection) (java.rmi.server.hostname is required here only because the IP and hostname from your network is not the same as the server point of view)
Open those 4 ports on your remote host and make them available to your local machine: 1099, 1100, 1101 and 1102
Launch JVisualVM
Right-click on "Remote" > "Add Remote Host..." and enter your remote host name in "Host name" (if you don't use the port 1099, you can change this in the "Advanced Settings")
Right-click on the remote host you've just created > "Add JMX Connection..." and enter "[remote_host_name]:1102" in "Connection" input, and check "Do not require SSL connection"
Your Java process will appear twice: one from the "jstatd" connection type, and one from the "JMX" connection type.
Disclaimer: I'm the author of the open source ejstatd tool.
On your [hostname], open up [port] and tcp port range 40000-60000 for your IP only.
This did the trick for me fairly well.

Remote Debugging in eclipse

I have an application running in server A. The dev environment is in server B.
I am trying to do remote debugging of app running in server A.
In server A i added following command to service start script
-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=4554,server=y,suspend=n
And service is running in server A.
When i try to launch remote debugging configuration it gives
Failed to connect to remote VM. Connection refused. Connection refused
port 4554 is free in server A.
What other configuration need to be done for this?
Regards
Dheeraj Joshi
Try this.
Set suspend=y, just to make sure you got the JVM line right. This should stop the VM on startup until you connect.
If you're on Unix, bring up the terminal and try telnet [host] [port] - this will quickly let you know if there's anything listening to that port on that host.
Make sure the connection properties in Eclipse are set correctly. Note that the port defaults to 8000.
Use the IP address instead of the host name, to rule out DNS/hostfile problems.
Another way of starting the JVM that I use successfully is:
-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=y
Check if there is a firewall between and/or on the two servers.

Categories