I want to write an unprivileged (non-root-access) JMX client program that monitors a privileged (running as root) application that has JMX local access enabled -Dcom.sun.management.jmxremote .
At least on MacOSX, jconsole (and jps) don't see root processes when I run as myself.
Is this just the fact of life here, or is there some way to configure this?
If your client is not permitted to see the root process, then you cannot attach by PID. What you need is to have the root application load a JMXServer that will listen on a [>1024] port and then you can connect through the port rather than by PID. The easiest way to do this would be to specify a couple of more system properties which will trigger the JVM to load a JMX server automatically. For example (these are all the most insecure):
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.port=7777
See JMX Management and Monitoring Properties.
To create a JMXServer programmatically, see the JavaDoc for javax.management.remote. There is a really good guide/tutorial on this topic here.
JMX uses a simple TCP port that you can define with some command-line options. If the port is open, anyone (included non-priviledged users) should be able to see it.
As for the process itself, jps cannot see other user's process, but you can see then with "ps aux".
Related
Memory Analysers (Instrumentation and Monitoring tools) like VisualVM and jProfiler connect to Java Application's JVM though JMX extensions (though there might be other means to connect - like jstatd etc, i have seen JMX is quite common)
My Understanding About JMX:
By default JMX must expose its default port(not sure if there is a default port number) so that Memory Analysers can connect. So, I assume that when more than one java apps are running with default JMX config, on the same machine, there must be a JMX port conflict.
But I have never noticed that. I have seen java apps running happily with default configs and Mem Analysers could happily connect with each of these java apps at the same time. So my understanding about JMX ports is not entirely correct. Could some one say how more than one java app is able to expose JMX functionality with default configurations at the same time on the same machine. (???? is a random port used by JMX for each java application????)
Tools like VisualVM use JMX together with Dynamic Attach mechanism to monitor local Java Virtual Machines.
First, the tool connects to a local JVM via Attach
API.
Then it executes (also via Attach API) a command to start Management Agent (JMX server) in the target JVM.
The target JVM starts Management Agent on some free port and sets the opened port value in the Agent properties.
The tool uses Attach API again to read Agent properties, and thus discovers the port the Agent listens to.
Then it establishes the JMX connection to the Management Agent on this port.
Obviously, different local JVMs start Management Server on different ports, but VisualVM discovers the port number via Dynamic Attach.
I have an app that consumes so much memory, I would like to profile it, but I'm unable to start the app and pass the argument -agentpath; after I add this argument it waits for the profiler to connect, and so the GAE application doesn't startup. I get this message
Profiler Agent: Waiting for connection on port 5140 (Protocol version: 15)
I'm using maven to start up GAE application.
Sample command to start up:
java -agentpath:C:/visualvm_139/profiler/lib/deployed/jdk16/windows-amd64/profilerinterface.dll=C:\visualvm_139\profiler\lib,5140 -javaagent:C:\Users\User\.m2\repository\com\google\appengine\appengine-java-sdk\1.9.59\appengine-java-sdk\appengine-java-sdk-1.9.59\lib\agent\appengine-agent.jar -Dappengine.fullscan.seconds=5 -classpath C:\Users\User\.m2\repository\com\google\appengine\appengine-java-sdk\1.9.59\appengine-java-sdk\appengine-java-sdk-1.9.59\lib\appengine-tools-api.jar com.google.appengine.tools.development.DevAppServerMain -p 8888 C:\Users\User\eclipse\workspace\App\
An alternative solution would be using;
-Xdebug
-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=y
which would block the app until a debug client is attached on port 8000.
If you are having trouble using VisualVM with App Engine, you can try another approach, such as using Stackdriver to monitor different aspects of your Java VM, such as memory usage.
This link has all the useful information on how to set up a Stackdriver agent and use its monitoring functions to determine where the memory leaks come from.
If you don't need to profile startup of your application (from the description it looks like you don't), just start your application normally (without -agentpath). Start VisualVM, open your application and go to Profiler tab.
if you need to profile startup of your application use Startup profiler. It will tell you, what you should do.
I have written a Java service to run on a server.
I used JMX and jconsole to monitor the service from myPC.
In order to connect, I have to copy and paste the following link into jconsole:
service:jmx:rmi://192.168.5.207:9999/jndi/rmi://192.168.5.207:9999/jmxrmi
After quitting jconsole, If I want to reconnect, I have to copy and paste the link again.
Is there a way to save the link in jconsole so that I can reuse it?
Or can you suggest another remote monitor tool.
I think, you will not be able to save URLs in JConsole. You can use VisualVM instead. It is very good tool which has all the functionality as JConsole with some very good extra features.
You can specify the URL as program argument:
jconsole [ options ] [ pid | [ host:port ]]
pid
Process ID of a local Java VM that was started with the system property com.sun.management.jmxremote. The Java VM must be running with the same user ID as the user ID running jconsole. See JMX Monitoring and Management for details.
host:port
Name of the host system on which the Java VM is running and the port number specified by the system property com.sun.management.jmxremote.port when the JVM was started. See JMX Monitoring and Management for details.
http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jconsole.html
I want to create a JMX agent that has to be accessible from local host only.
Please advise how can I do that.
Also help with a Simple JMX client on same machine that will connect to that JMX agent.
If somehow we can get away with specifying an explicit port, that will be helpful.
You might find this helpful. It uses the attach API for Oracle's JVM to connect to a running Java process and have it start a local only JMX agent. You would setup whatever MBeans you want to expose as usual. I get the impression that this code is similar to what JConsole does for connecting to local JVM processes. You might also want to investigate the source for Jmxterm which leverages JConsole for connecting to local JVM processes.
All,
If i want to enable JMX on Tomcat for monitoring from the same machine, (i.e. not remotely) are these properties still required?
com.sun.management.jmxremote.authenticate=false
com.sun.management.jmxremote.port=12345
Isnt it the case that the authenticate and port number properties are only relevant if monitoring remotely? Do i need the above if monitoring locally?
If the port number is not required, how does the client know who to contact Tomcat? Does it listen to a port number that TOmcat has open by default?
You are correct, these parameters only required when monitoring remote application via JMX. When monitoring locally, you can skip them. Obviously the process needs to be started by the same user.
I think there are some exceptions to this rule, see
http://download.oracle.com/javase/1.5.0/docs/guide/management/agent.html#local
Q:"If the port number is not required, how does the client know who to contact Tomcat?"
A: jconsole, jps and the likes simply looks for any Java processes that are running on the system and owned by the same user.
Read here: http://download.oracle.com/javase/6/docs/technotes/guides/management/jconsole.html (chapter about attachable applications).
Here is a writeup i did on this subject. JMX setup for external access