I am very new to JMX. I am trying to log the tomcat statistics like threads used, cache, sessions and other standard values. I am trying to achieve this with java code.
I have done the following things as of now. (I am trying to access the values of a local tomcat 6.0 monitor on windows)
1)I have added the following options in the catalina.bat
set CATALINA_OPTS=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9004 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
After that I restarted the tomcat server.
2) Then I wrote the following code.
package com.ss.fg;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
public class SystemConfigManagement
{
static MBeanServer connection = ManagementFactory.getPlatformMBeanServer();
public static void main(String[] args) throws Exception {
getActiveSession();
}
public static void getActiveSession()throws Exception
{
ObjectName name=new ObjectName("Catalina:type=Manager,path=/MMDisplay,host=localhost");
String attrValue = ManagementFactory.getPlatformMBeanServer().getAttribute(name, "activeSessions").toString();
System.out.println(attrValue);
}
}
I even tried context instead of path.
I am getting the following exception
Exception in thread "main" javax.management.InstanceNotFoundException: Catalina:type=Manager,path=/MMDisplay,host=localhost
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean(Unknown Source)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getAttribute(Unknown Source)
at com.sun.jmx.mbeanserver.JmxMBeanServer.getAttribute(Unknown Source)
at com.softsmith.floodgates.SystemConfigManagement.getActiveSession(SystemConfigManagement.java:15)
at com.softsmith.floodgates.SystemConfigManagement.main(SystemConfigManagement.java:10)
How can I resolve this issue?
Should I add Some jar files, or should I do some other settings..
Please help
When using
MBeanServer connection = ManagementFactory.getPlatformMBeanServer();
you are actually connectiong to the MBean-Server of the JVM running your program, not to that of your tomcat-instance, so it doesn't know of the Catalina-MBeans.
To establish a connection to a remote jvm try something like:
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://servername:9999/jmxrmi");
JMXConnector connector = JMXConnectorFactory.connect(url);
connector.connect();
MBeanServerConnection server = connector.getMBeanServerConnection();
//do work here
ObjectName name = new ObjectName("Catalina:type=Manager,path=/manager,host=localhost");
String attrValue = mb.getAttribute(name, "activeSessions").toString();
System.out.println(attrValue);
//..and don't forget to close the connection
connector.close();
If the error is still there make sure you are using the correct object-name.
When i using
MBeanServer connection = ManagementFactory.getPlatformMBeanServer();
i am actually connectiong to the MBean-Server of the JVM running my program, not to that of my tomcat-instance, so it doesn't know of the Catalina-MBeans.
so i try to connected remotly to jmx but have error like this :
java.io.IOException: Failed to retrieve RMIServer stub: javax.naming.CommunicationException [Root exception is java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is....
and now i solve :
for first i added catalina-jmx-remote.jar to TOMCAT_HOME/lib directory of Tomcat and then configure the listener on server.xml i added the following
snippet under the tag :
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" useLocalPorts="true" />
and finally i set the following sentence in my catalina.bat :
JAVA_OPTS="$JAVA_OPTS -Djava.rmi.server.hostname=localhost -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
Related
In this post java H2 hanging on getLocalhost on arm32 device I had a problem creating database using Hibernate. I have now managed to remove track down the issue to core java with this test program, InetAddress lookup using getByName("localhost") works, but getLocalHost() fails !
Points towards configuration issue with linux machine. localhost is in /etc/hosts
But I am no Linux expert, what could cause this ?
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Addresses
{
public static void main(String[] args) {
try {
InetAddress address= InetAddress.getByName("localhost");
System.out.println(address.getHostName()+ "-"+address.getHostAddress());
address= InetAddress.getLocalHost();
System.out.println(address.getHostName()+ "-"+address.getHostAddress());
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
Gives
localhost-127.0.0.1
java.net.UnknownHostException: N1-ZS10: N1-ZS10: Name or service not known
at java.net.InetAddress.getLocalHost(InetAddress.java:1505)
at Addresses.main(Addresses.java:12)
Caused by: java.net.UnknownHostException: N1-ZS10: Name or service not known
at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928)
at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323)
at java.net.InetAddress.getLocalHost(InetAddress.java:1500)
... 1 more
In the documentation on Java management, in the section headed "Mimicking Out-of-the-Box Management Using the JMX Remote API" (see bottom of page), it shows you how you can manually expose your MBeanServer via JMX. Something like this:
public static void main(String[] args) throws IOException {
final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
final Map<String, Object> env = new HashMap<String, Object>();
final SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory();
env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf);
final SslRMIServerSocketFactory ssf = new SslRMIServerSocketFactory();
env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf);
final int port = 32154;
System.setProperty("java.rmi.server.randomIDs", "true");
final Registry registry = LocateRegistry.createRegistry(port /*, csf, ssf */);
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:" + port + "/jmxrmi");
JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
cs.start();
If you try and run this code, this exception is repeatedly thrown (and you cannot remotely connect to the server):
26-Nov-2015 16:42:21:085: [sun.rmi.transport.tcp - FINE] [14]: RMI TCP Connection(4)-10.210.50.223: terminated with exception:
Exception in 14: Received fatal alert: certificate_unknown
javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1822)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1004)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1188)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:818)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
at java.io.DataInputStream.readInt(DataInputStream.java:370)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:686)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
I thought "it must be that the registry is not created with the relevant socket factories", so I uncommented the relevant arguments to LocateRegistry.createRegistry. But now this exception is thrown (and the application fails to start)
Exception in thread "main" java.io.IOException: Cannot bind to URL [rmi://:32154/jmxrmi]: javax.naming.CommunicationException [Root exception is java.rmi.ConnectIOException: non-JRMP server at remote endpoint]
at javax.management.remote.rmi.RMIConnectorServer.newIOException(RMIConnectorServer.java:804)
at javax.management.remote.rmi.RMIConnectorServer.start(RMIConnectorServer.java:417)
at gsa.core.monitor.ExposeMBeansViaSsl.main(ExposeMBeansViaSsl.java:32)
Note: the application is run with the relevant javax.net.ssl system properties set, as described in the tutorial. Anyone know what is going on?
I created sample class Testws with one simple method sayHi(String name) that simply showing welcome message. The target is to create web service application for this class and applying OWSM policies.
All the needed file is generated from Jdeveloper 11.1.1.7 and I added the oracle/wss_username_token_client_policy to the client side in TestwsPortClient. Problem is that when I run the main method from TestwsPortClient I got the following error:
SEVERE: java.io.FileNotFoundException: .\config\jps-config.xml (The system cannot find the path specified)
Although I tried (But it did not work) to set the system propriety to find the missing file as follow:
System.setProperty("oracle.security.jps.config",
"C:\\Users\\user\\AppData\\Roaming\\JDeveloper\\system11.1.1.7.40.64.93\\DefaultDomain\\config\\fmwconfig\\jps-config.xml");
Here is the Client Class TestwsPortClient:
public static void main(String[] args) {
testwsService = new TestwsService();
SecurityPoliciesFeature securityFeatures =
new SecurityPoliciesFeature(new String[] { "oracle/wss_username_token_client_policy" });
Testws testws = testwsService.getTestwsPort(securityFeatures);
// Add your code to call the desired methods.
System.setProperty("oracle.security.jps.config",
"C:\\Users\\user\\AppData\\Roaming\\JDeveloper\\system11.1.1.7.40.64.93\\DefaultDomain\\config\\fmwconfig\\jps-config.xml");
List<CredentialProvider> credProviders =new ArrayList<CredentialProvider>();
String username = "weblogic";
String password = "weblogic1";
CredentialProvider cp =new ClientUNTCredentialProvider(username.getBytes(), password.getBytes());
credProviders.add(cp);
Map<String, Object> rc = ((BindingProvider)testws).getRequestContext();
rc.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credProviders);
testws.sayHi("Salman");
}
Here the exception stack trace:
Note: the stack trace is too long this is just part of it where I think it will gives an idea about the error
SEVERE: java.io.FileNotFoundException: .\config\jps-config.xml (The system cannot find the path specified)
SEVERE: java.io.FileNotFoundException: .\config\jps-config.xml (The system cannot find the path specified)
INFO: WSM-09004 Component auditing cannot be initialized.
INFO: Recipient Alias property not configured in the policy. Defaulting to encrypting with signers certificate.
WARNING: JPS-00065 Jps platform factory creation failed. Reason: java.lang.ClassNotFoundException: oracle.security.jps.se.JpsSEPlatformFactory.
WARNING: JPS-00065 Jps platform factory creation failed. Reason: {0}.
......
at $Proxy34.sayHi(Unknown Source)
at test.TestwsPortClient.main(TestwsPortClient.java:44)
Caused by: oracle.security.jps.JpsException: JPS-00065: Jps platform factory creation failed. Reason: java.lang.ClassNotFoundException: oracle.security.jps.se.JpsSEPlatformFactory.
at oracle.security.jps.ee.JpsPlatformFactory$2.run(JpsPlatformFactory.java:197)
at oracle.security.jps.ee.JpsPlatformFactory$2.run(JpsPlatformFactory.java:190)
........
I can't seem to get this working. I'm just look at it for basic instruction for a lab, but I've no experience with RMI at all. I can't seem to get why I'm getting the error.
Server
public static void runServer() {
// Install security manager, if none is present
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
try {
Registry registry = LocateRegistry.getRegistry();
System.out.println("Reg: " + registry.toString());
String name = "Server";
Server server = new Server();
I_Server stub = (I_Server) UnicastRemoteObject.exportObject(server, 0);
registry.rebind(name, stub);
System.out.println("All is well :-)\n");
} catch (RemoteException re) {
System.err.println("Remote Exception in DisplayGetEngine.main()\n");
re.printStackTrace();
}
}
}
I have the following run commands and arguments in NetBeans
Arguments: -cp C:\rmi\Server\src;C:\rmi\Server\dist\Server.jar -Djava.rmi.server.codebase=file:/C:/rmi/Server/dist/Server.jar
Working Directory: C:\rmi\Server
My stacktrace is, at the rebind method.
Reg: RegistryImpl_Stub[UnicastRef [liveRef: [endpoint:[10.50.18.205:1099](remote),objID:[0:0:0, 0]]]]
Remote Exception in DisplayGetEngine.main()
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: server.I_Server
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:419)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at sun.rmi.transport.Transport$1.run(Transport.java:174)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:273)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:377)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at server.Server.runServer(Server.java:50)
at server.Server.main(Server.java:31)
If I don't run rmiregistry, this is my stacktrace
Remote Exception in DisplayGetEngine.main()
java.rmi.ConnectException: Connection refused to host: 10.50.18.205; nested exception is:
java.net.ConnectException: Connection refused: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:340)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at server.Server.runServer(Server.java:50)
at server.Server.main(Server.java:31)
Try calling createRegistry() first to make sure that you have a running registry. Also, port 0 should be a reserved port so you won't be able to make your server listen on that particular port. Try the default one 1099.
There is no problem in running rmiregistry. If you look into the stacktrace closely,the problem seems to be ClassNotFoundException while the arguments are being unmarshalled in the rmi registry. You will have to check the code base of the RMI server whether server.I_Server class is present in the Server.jar while running it in the classpath.
From RMI FAQs
A.4 Why am I getting a ClassNotFoundException?
Most likely the java.rmi.server.codebase property has not been set (or has not been set correctly) on a VM that is exporting your remote object(s). Please take a look at our tutorial, Dynamic code downloading using Java RMI (Using the java.rmi.server.codebase Property).
The issue was in the build file. I needed to insert this statement.
<target name="startRMI" depends="init">
<exec executable="C:\Program\Files\Java\jdk1.7.0_51\jre\bin\rmiregistry"
dir="${build.classes.dir}"></exec>
</target>
I have a problem using java rmi:
When I'm trying to run my server, I get a connectException (see below).
Exception happens when executing the rebind method:
Runtime.getRuntime().exec("rmiregistry 2020");
MyServer server = new MyServer();
Naming.rebind("//localhost:2020/RemoteDataPointHandler", server);
when using rmi://localhost:2020/RemoteDataPointHandler instead, it doesn't work either. Also using the default port does not work. I also tried using the 127.0.0.1 ip-address, but with the same effect.
my runtime args:
-Djava.security.policy=java.security.AllPermission
Exception in thread "main" java.rmi.ConnectException: Connection refused to host: localhost; nested exception is:
java.net.ConnectException: Connection refused
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at java.rmi.Naming.rebind(Naming.java:160)
at be.fortega.knx.server.Main.(Main.java:25)
at be.fortega.knx.server.Main.main(Main.java:16)
Caused by: java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:433)
at java.net.Socket.connect(Socket.java:524)
at java.net.Socket.connect(Socket.java:474)
at java.net.Socket.(Socket.java:371)
at java.net.Socket.(Socket.java:184)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:569)
... 7 more
had a simliar problem with that connection exception. it is thrown either when the registry is not started yet (like in your case) or when the registry is already unexported (like in my case).
but a short comment to the difference between the 2 ways to start the registry:
Runtime.getRuntime().exec("rmiregistry 2020");
runs the rmiregistry.exe in javas bin-directory in a new process and continues parallel with your java code.
LocateRegistry.createRegistry(2020);
the rmi method call starts the registry, returns the reference to that registry remote object and then continues with the next statement.
in your case the registry is not started in time when you try to bind your object
It seems to work when I replace the
Runtime.getRuntime().exec("rmiregistry 2020");
by
LocateRegistry.createRegistry(2020);
anyone an idea why? What's the difference?
You need to have a rmiregistry running before attempting to connect (register) a RMI service with it.
The LocateRegistry.createRegistry(2020) method call creates and exports a registry on the specified port number.
See the documentation for LocateRegistry
One difference we can note in Windows is:
If you use Runtime.getRuntime().exec("rmiregistry 1024");
you can see rmiregistry.exe process will run in your Task Manager
whereas if you use Registry registry = LocateRegistry.createRegistry(1024);
you can not see the process running in Task Manager,
I think Java handles it in a different way.
and this is my server.policy file
Before running the the application, make sure that you killed all your existing
javaw.exe and rmiregistry.exe corresponds to your rmi programs which are
already running.
The following code works for me by using Registry.LocateRegistry() or
Runtime.getRuntime.exec("");
// Standard extensions get all permissions by default
grant {
permission java.security.AllPermission;
};
VM argument
-Djava.rmi.server.codebase=file:\C:\Users\Durai\workspace\RMI2\src\
Code:
package server;
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.Remote;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class HelloServer
{
public static void main (String[] argv)
{
try {
if(System.getSecurityManager()==null){
System.setProperty("java.security.policy","C:\\Users\\Durai\\workspace\\RMI\\src\\server\\server.policy");
System.setSecurityManager(new RMISecurityManager());
}
Runtime.getRuntime().exec("rmiregistry 1024");
// Registry registry = LocateRegistry.createRegistry(1024);
// registry.rebind ("Hello", new Hello ("Hello,From Roseindia.net pvt ltd!"));
//Process process = Runtime.getRuntime().exec("C:\\Users\\Durai\\workspace\\RMI\\src\\server\\rmi_registry_start.bat");
Naming.rebind ("//localhost:1024/Hello",new Hello ("Hello,From Roseindia.net pvt ltd!"));
System.out.println ("Server is connected and ready for operation.");
}
catch (Exception e) {
System.out.println ("Server not connected: " + e);
e.printStackTrace();
}
}
}
it seems that you should set your command as an String[],for example:
String[] command = new String[]{"rmiregistry","2020"};
Runtime.getRuntime().exec(command);
it just like the style of main(String[] args).