JMX provides a standard way to instrument the Java runtime environment and applications, and the JMX Remote API allows that instrumentation to be accessed remotely. there are couple system properties that you need to setup.
To enable the JMX agent and configure its operation using
jconsole, your must set some specific system properties when you start the JVM. For local access, set the property
com.sun.management.jmxremote as follows when starting the JVM:
java -Dcom.sun.management.jmxremote AppName
And, to enable monitoring and management from remote systems [here we disable the authentication and ssl] , set the property:
When we talk about the firewall settings, here is one quick question, Is the PortNumber pretty much all we needed to put it into our exception list? if you answer yes like me. you need read the following parts. or maybe that’s why you are redirected to this blog.
lets do a simple test, Just open you notepad and write a helloworld Application.
public class MyApp
then Compile and Run the application.
C:\temp>java -cp "." -Dcom.sun.management.jmxremote.port=2222 -Dcom.sun.management.jmxremote.ssl=false
Keep the application running, and Open Jconsole, put localost:2222 to the remote process field, and click to go. nothing special here, you will be able to see the Mbeans .
So, How does the jconsole communicate with our JMXRemote Port? your may run netstat or download a utility offered from microsoft called tcpview. when you filter to jconsole process, you may find the following sessions. besides, the port 2222, it open one extra tcp port . the port number looks like it just pick it up randomly
at the end of one day, if somebody enforce the firewall policy by adding port 2222 to the only allowed port, then Nobody can use the jconsole to monitor this jvm.
So how can we Restrict the JMX listening Port/TCP to use the predefined Port? here is the steps.
basic Idea, when the application startup, just start one JMXConnectorServer service explicitly. the server will expose jmxjmi service to the client. In java, there is one serverfactory called JMXConnectorServerFactory
The connector server will generate an
RMIServerImpl based on the protocol (
iiop) and, for
port if any. When the connector server is started, it will derive a stub from this object using its
toStub method and store the object using the given
jndi-name. The properties defined by the JNDI API are consulted as usual.
For example, if the
then the connector server will generate an
RMIJRMPServerImpl and store its stub using the JNDI name
then we just change the myapp.java to loadup the connecterserver directly.
public class MyApp
System.out.println("hello,world, press to continue");
Recompile and restart the app, run jconsole. check the tcp session. Only TCP Port 3333 is open and required this time now.
In this case, we owned the source code of our application. if you are using the commercial package or third party application, you can’t change their source code then.
not a big problem, the Insturment package allow Java programming language agents to instrument programs running on the JVM. we just inject the save logic by writing a customeragent , and use the javaagent parameter to load our customeAgent.
we define another class, named JconsoleAgent
then export the compiled class to a jar file named Jconsoleagent.jar . Edit the MANIFEST.MF file inclued in the jar, and put one more line.
then startup the application like
C:\temp>java -cp "." -DMyJMXPORT=3333 -javaagent:Jconsoleagent.jar MyApp
you will be able to use the port 3333 only here to do the jmx monitoring.
Hope it Helps.
Another question, if you have multi NICS on the server, you can specify which RMI server that will server the request by adding parameters like
Also, make sure you jconsole client can resmove the MyInternalNIC to the same IPaddress as you defined on the server. otherwise, you can’t conenct to the remote server
here is my great reference link, http://www.cs.washington.edu/education/courses/cse341/98au/java/jdk1.2beta4/docs/guide/rmi/rmiNetworkingFAQ.html