I'm having trouble setting up Tomcat for JMX. I added the following properties to
CATALINA_OPTS="-Dcom.sun.management.jmxremote.port=18070 -Dcom.sun.management.jmxremote.password.file=$CATALINA_BASE/conf/jmxremote.password -Dcom.sun .management.jmxremote.ssl=false"
And added the jmxremote.password file to the conf directory. I wrote a client tool that connects to a JMX server running on port 18070. When I run the client program, I get the following error.
Exception in thread "main" java.lang.SecurityException: Authentication failed! Credentials required at com.sun.jmx.remote.security.JMXPluggableAuthenticator.authenticationFailure(JMXPluggableAuthenticator.java:193) at com.sun.jmx.remote.security.JMXPluggableAuthenticator.authenticate(JMXPluggableAuthenticator.java:145) at sun.management.jmxremote.ConnectorBootstrap$AccessFileCheckerAuthenticator.authenticate(ConnectorBootstrap.java:185) at javax.management.remote.rmi.RMIServerImpl.doNewClient(RMIServerImpl.java:213) at javax.management.remote.rmi.RMIServerImpl.newClient(RMIServerImpl.java:180) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:305) at sun.rmi.transport.Transport$1.run(Transport.java:159) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:155) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) at java.lang.Thread.run(Thread.java:619) at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255) at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142) at javax.management.remote.rmi.RMIServerImpl_Stub.newClient(Unknown Source) at javax.management.remote.rmi.RMIConnector.getConnection(RMIConnector.java:2312) at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:277) at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:248) at com.bt.c21sc.c21tkprobe.accessors.C21TkProbeJmxDAO.connect(Unknown Source) at com.bt.c21sc.c21tkprobe.service.C21TkProbeBD.execute(Unknown Source) at com.bt.c21sc.c21tkprobe.C21AppserverProbe.main(Unknown Source)
If I changed the properties of CATALINA_OPTS to
CATALINA_OPTS="-Dcom.sun.management.jmxremote.port=18070 -Dcom.sun.management.jmxremote.password.file=$CATALINA_BASE/conf/jmxremote.password -Dcom.sun .management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
Then it works great. I think I'm confused, this is what is classified as remote access. I am running the client program from an instance of Tomcat, but both Tomcat and the client tool are on the same computer (i.e., Different virtual machines, but with the same environment). I thought I needed to set up remote authentication if I was accessing the JMX server remotely from another machine.
By remote access, do they mean access to the JMX server from any virtual machine both locally and remotely?
Edit
Thanks. I found out that the problem is that, despite the fact that I supplied the username and password in the jmxremort.password and jmxremote.access files, I still had to specify the username and password from the client.
You are right that I do not need to provide user credentials if they run locally. I have proven this since I can access the Tomcat JVM through the Jconsole.
I access it programmatically, so I have to specify the URL that is shown below Service: JMX: RMI: /// JNDI / RMI: // local: 9004 / jmxrmi
Then I will get the jmx server as shown below.
url = new JMXServiceURL(urlString); Hashtable<String, String[]> env = new Hashtable<String, String[]>(); String[] credentials = new String[] {user,pass}; env.put(JMXConnector.CREDENTIALS, credentials); jmxc = JMXConnectorFactory.connect(url,env); mbsc = jmxc.getMBeanServerConnection();
If I access this locally, how would I do it? I know that it does not work locally without user credentials, since I found out what I need to provide. if Jconsole or visualvm can connect to it, then there must be a different approach that allows you to get the Tomcat jmx server without having to specify a port number.
The url contains the port number. If I access the JMX server programmatically, how can I access it without specifying a port number?
By the way, I am using Tomcat 5.5 and JDK 1.6
thanks