Java JMX Server - java

I'm curious about how JConsole and JMX work together. Specifically, I have read this JConsole Guide which mentions that
jconsole uses a JMXConnector client to connect to the JMXConnectorServer in
the target application. If the application isn't started with the JMX agent
then there isn't a JMXConnectorServer and jconsole doesn't have anything to
connect too. In that case it uses a HotSpotTM VM specific mechanism to start
the JMX agent in the target VM. Once the agent is started then jconsole connects
as normal.
When I start jconsole it simply needs a port and hostname for the JMX information, so I'm wondering if its possible to access the MBeans through any arbitrary tcp connection (and thus any programming language), or if there is something special that jconsole is also doing?
I know how to access the MBean Factory though java, but I am curious if I can access these items through an arbitrary language via TCP or another straightforward mechanism. Also see link discussing rest connector.

By default, the JMX server provides connection via RMI. That will make it tricky to access the server through an arbitrary language.
However, the JMX server is not limited to RMI as the communication protocol. The architecture is extensible and pretty much any transport protocol might be used - but it would need to be written almost from scratch.
Take a look at Jolokia - they do a pretty amazing stuff to let you talk to the MBean servers via a bunch of protocols (REST is one of them), amongst other things.

Related

RabbitMQ connecting VM to Host

I'm new-ish to networking, and I'm swimming (drowning) in semantics.
I have a VM which runs a Java application. Ideally, it would be fed inputs from the host through a RabbitMQ queue. The Java application would then place the results on another RabbitMQ queue on a different port where it will be used by the host application. After researching it for a bit, it seems like RabbitMQ only exists in the localhost space with listeners on different ports, am I correct in this?
Do I need 2 RabbitMQ servers running in tandem, then, (one on the VM and other on Host) each listening to the same port? Or do I just need one RabbitMQ server running while both applications are pointed to the same IP Address/Port?
Also, I have also read that you cannot connect as 'guest/guest' unless it is on localhost, which I understand, but how is RabbitMQ supposed to be configured/reachable to anything besides localhost?
I've been researching for several hours, but the documentation does not point to a direct answer/how-to guide. Perhaps it is my lack of network experience. If anyone could elaborate on these questions or point me to some articles/helpful guides, I would be much obliged.
P.S. -- I don't even know what code to display to give context. Let me know and I'll edit the code into the post.
RabbitMQ listens to TCP port 5672 on all network interfaces out-of-the-box. This includes the "loopback" interface (to allow fast connections to self) and interfaces visible to other remote hosts (including VMs).
For your use case, you probably need a single RabbitMQ instance for both directions. The application on the host will publish messages to one queue and the Java application in the VM will consume messages from that queue and push the result to a second queue. This second queue can be consumed by the application on the host.
For the user, you need to create a new user with the appropriate rights. This is documented in the access control article. To create the user, you can do it from the management web UI (after you enabled the management plugin) or using the rabbitmqctl command line tool.
The last part is networking between the host and the VM. It really depends on the technology you use. It may work out-of-the-box or you may have to configure how VMs are connected to the network. Refer to the documentation of your hypervisor.

Best way to tunnel RMI over HTTP

I'm looking for a secure way to tunnel RMI traffic.
In My application(java Webstart) i must assume that the only port that is open is port 80.
I have the looked att socketfactories for rmi but do i really need a proxy then.
I need to do all my tunneling on the client side.
The only firewall i am trying to get past is on the client side.
I'm not able to open 1099 with port ranges above.
Would be nice to see some implementations.
Thanks!
Port 1099 was reserved for RMI at IANA in about 1995. There is no reason for it not to be open for outbound access in the client-side firewall.
RMI can be made to use fixed port numbers by supplying a port number when constructing (super(port)) or exporting (exportObject(object, port)). Better still, if you create the Registry within the server JVM via LocateRegistry.createRegistry(), all subequently exported remote objects will use that port unless they specify a different port or they use a server socket factory.
BUT ... RMI already includes HTTP tunneling 'out of the box'. No external solution required. You have to deploy the RMI-Servlet provided with the JDK, at the server end.
(a)
although not the newest fashion, exposing remote services with Hessian and Burlap seems to be a simple solution to avoid problem working across firewalls: http://hessian.caucho.com/doc/
see sample code for the server and client side:
http://www.javatpoint.com/spring-remoting-by-hessian-example
(b) or consider using Spring HttpInvokder (see some sample code here: http://www.javatpoint.com/spring-remoting-by-http-invoker-example)
HttpInvokder provides more customization options through the RemoteInvocationFactory, RemoteInvocationExecutor and HttpInvokerRequestExecutor strategies (for example, to add custom context information (such as user credentials) to the remote invocation, or using java’s built-in object serialization etc.), see:
http://docs.spring.io/spring-framework/docs/2.0.x/api/org/springframework/remoting/support/RemoteInvocationFactory.html

JMX Port dynamic allocation

I have 16 Java processes with the same main method and arguments running on one machine. I wish to monitor these remotely thru JConsole.
Hard coding port numbers like -Dcom.sun.management.jmxremote.port=5000 won't work because these processes are using same configuration and they can't work with same port.
Is it possible for the JVM to select a different port dynamically for each of the 16 processes?
Using RMI Connector might be the way as you may specify URL of your agent.
In case you'd need it, you may create RMI registry programatically using:
java.rmi.registry.LocateRegistry.createRegistry(port);
You may find following unrelated sample useful: Connecting Through Firewall Using JMX
I don't think the oracle jvm supports anything like this. the only thing that might work is using the port "0", which enables "dynamic" port selection in some rmi related stuff.

Does Java RMI IIOP work over internet?

I know that RMI is short on making connection outside LAN. I want to know if RMI IIOP can connect server client over internet. Is it possible ? If yes what are the possible solutions?
RMI works fine over the internet, it's TCP-based. I'd use KryoNet as an RMI implementation, personally. It's no-hassle, and extremely speedy. The serialisation mechanism uses Kryo, which is one of the fastest general purpose serialisation libraries. Note that there may be issues with firewalls. However, you could easily have an RMI server that listens on port 80. This would be work fine (unless there is heavy packet snooping, I guess). An RMI server that works over HTTP is interesting too. Mmm.
Yes, but only if the ports are open at the firewall. The advantage to using HTTP instead of RMI is that it can easily be passed through proxy servers.
There's no particular advantage to using IIOP over the native RMI protocol JRMP, as far as Internet-wide usage is concerned.
IIOP does gives you the ability to call your Java objects using non-Java based code, so if you want to support non-Java clients, you'll want to be thinking about IIOP or something more browser / JavaScript friendly like SOAP or XMLRPC.
If you don't need to support non-Java clients, there's not much to recommend IIOP. With IIOP, you lose the distributed garbage collection that JRMP provides, so you'll have to decide when any RMI-published object should no longer be published.
With JRMP, all you have to worry about manually managing are the RMI objects you bind to the RMI registry. All other objects you publish will be automatically garbage collected once all references to them (both local and remote) are dropped. If you use IIOP, you'll manually have to call PortableRemoteObject.unexportObject() when it's time to take them out of use.

Explain JMX URL

I am trying to understand a JMX service URL.
service:jmx:rmi://192.168.30.10:1234/jndi/rmi://192.168.30.10:2344/jmxrmi
It would be great, if someone can help me understand this.
Thanks
I will reuse an answer I wrote up earlier for this question: Cannot connect to Tomcat's MBeanServer via jconsole in Java6
It's not complete, but might help:
Suppose you have the JMX Server (alias 'JMX Agent' alias 'the JVM you want to connect to') running on 'TARGET MACHINE' with the RMI registry port at 'RMI REGISTRY PORT' and the JMX RMI server port at 'JMX RMI SERVER PORT'.
Note:
The RMI registry tells JMX clients where to find the JMX RMI server port; information can be obtained under key jmxrmi.
The RMI registry port is generally known as it is set through system properties at JVM startup.
The JMX RMI server port is generally not known as the JVM chooses it at random (if no other precautions are taken).
The following URI will lead to successful connection (tested)
service:jmx:rmi://<TARGET_MACHINE>:<JMX_RMI_SERVER_PORT>/jndi/rmi://<TARGET_MACHINE>:<RMI_REGISTRY_PORT>/jmxrmi
This looks nasty. Let's cut it apart.
This URI is an RFC2609 "Service Location Protocol URL" (well, it's really an URI, right?)
It is composed of:
service - a constant
jmx:rmi - the service type composed of: abstract type jmx and URL scheme rmi
the rest - the sap (service access protocol specification)
sap is decomposed into:
//<TARGET_MACHINE>:<JMX_RMI_SERVER_PORT> - ipsite
/jndi/rmi://<TARGET_MACHINE>:<RMI_REGISTRY_PORT>/jmxrmi - URL part
A well-informed JMX client connects to the "ipsite" to do JMX-over-RMI exchanges; but what of the JMX client that doesn't KNOW that port? Patience...
URL part is decomposed into:
/jndi/ - This seems to tell the JMX client that it can get lookup information at the location that follows
rmi://<TARGET_MACHINE>:<RMI_REGISTRY_PORT>/jmxrmi - Yep, we get information about the JMX RMI Server at the RMI registry, under the lookup key jmxrmi
This is somewhat cart-before-horse, as one has to contact the RMI registry given by the latter part of the SLP URL first.
After scratching head, intuitively, let's try:
service:jmx:rmi://<TARGET_MACHINE>/jndi/rmi://<TARGET_MACHINE>:<RMI_REGISTRY_PORT>/jmxrmi
Yes, that works! The JMX RMI server port is nicely obtained from the registry. On second thoughts, the target machine should also be obtained from the registry, thus:
service:jmx:rmi:///jndi/rmi://<TARGET_MACHINE>:<RMI_REGISTRY_PORT>/jmxrmi
Even better, that works, too!
References:
http://download.oracle.com/javase/6/docs/api/javax/management/remote/rmi/package-summary.html
http://download.oracle.com/javase/6/docs/api/javax/management/remote/JMXServiceURL.html
http://mx4j.sourceforge.net/docs/ch03s04.html
http://download.oracle.com/javase/6/docs/technotes/guides/management/agent.html#gdevg
http://www.rfc-editor.org/rfc/rfc2609.txt
To explain:
service:jmx:rmi://192.168.30.10:1234/jndi/rmi://192.168.30.10:2344/jmxrmi
service:jmx:rmi://192.168.30.10:1234 - says that there is a JMX Agent on the machine with IP address 192.168.30.10. The JMX agent is using (TCP) port 1234 to provide JMX service(s) over RMI (basically acts as an RMI server).
/jndi/rmi://192.168.30.10:2344/jmxrmi - says that the RMI stub to interact with the JMX Agent over RMI can be found in the RMI registry which is running on the machine with IP address 192.168.30.10 and is using (TCP) port 2344. To get the RMI stub you need to lookup the "jmxrmi" binding.
Previous answers suggest that the 2nd part of the URL is to obtain the server port of the JMX RMI server. That is not correct. The JMX RMI server port is (TCP) 1234 and is part of the URL. What you get from the RMI registry is the RMI stub (javax.management.remote.rmi.RMIServerImpl_Stub) which you can use to talk to JMX Agent (MBean Server) over RMI.
Hope this helps.
According to javax.management.remote.rmi
this url is assembled like this
service:jmx:rmi://ignoredhost/jndi/rmi://myhost/myname

Categories