The RMI connector is a connector for the JMX Remote API that uses RMI to transmit client requests to a remote MBean server. This package defines the classes that the user of an RMI connector needs to reference directly, for both the client and server sides. It also defines certain classes that the user will not usually reference directly, but that must be defined so that different implementations of the RMI connector can interoperate.
The RMI connector supports the JRMP transport for RMI, and optionally the IIOP transport.
Like most connectors in the JMX Remote API, an RMI connector
usually has an address, which
is a {@link javax.management.remote.JMXServiceURL
JMXServiceURL}. The protocol part of this address is
rmi
for a connector that uses the default RMI
transport (JRMP), or iiop
for a connector that
uses RMI/IIOP.
There are two forms for RMI connector addresses:
Addresses are covered in more detail below.
The usual way to create an RMI connector server is to supply an RMI connector address to the method {@link javax.management.remote.JMXConnectorServerFactory#newJMXConnectorServer JMXConnectorServerFactory.newJMXConnectorServer}. The MBean server to which the connector server is attached can be specified as a parameter to that method. Alternatively, the connector server can be registered as an MBean in that MBean server.
An RMI connector server can also be created by constructing an
instance of {@link
javax.management.remote.rmi.RMIConnectorServer
RMIConnectorServer}, explicitly or through the MBean server's
createMBean
method.
You can choose the RMI transport (JRMP or IIOP) by specifying
rmi
or iiop
in the
protocol
part of the
serviceURL
when creating the connector server. You
can also create specialized connector servers by instantiating
an appropriate subclass of {@link
javax.management.remote.rmi.RMIServerImpl RMIServerImpl} and
supplying it to the RMIConnectorServer
constructor.
If the serviceURL
you specify has an empty URL
path (after the optional host and port), or if you do not
specify a serviceURL
, then the connector server
will fabricate a new JMXServiceURL
that clients can
use to connect:
If the serviceURL
looks like:
service:jmx:rmi://host:port
then the connector server will generate an {@link
javax.management.remote.rmi.RMIJRMPServerImpl
RMIJRMPServerImpl} and the returned JMXServiceURL
looks like:
service:jmx:rmi://host:port/stub/XXXX
where XXXX
is the serialized form of the
stub for the generated object, encoded in BASE64 without
newlines.
If the serviceURL
looks like:
service:jmx:iiop://host:port
then the connector server will generate an {@link
javax.management.remote.rmi.RMIIIOPServerImpl
RMIIIOPServerImpl} and the returned
JMXServiceURL
looks like:
service:jmx:iiop://host:port/ior/IOR:XXXX
where IOR:XXXX
is the standard CORBA
encoding of the Interoperable Object Reference for the
generated object.
If there is no serviceURL
, there must be a
user-provided RMIServerImpl
. If the {@link
javax.management.remote.rmi.RMIServerImpl#toStub toStub}
method on this object returns an instance of {@link
javax.rmi.CORBA.Stub}, then the connector server will generate
a JMXServiceURL
using the iiop
form above. Otherwise, it will generate a
JMXServiceURL
using the rmi
form.
The host
in a user-provided
serviceURL
is optional. If present, it is copied
into the generated JMXServiceURL
but otherwise
ignored. If absent, the generated JXMServiceURL
will have the local host name.
The port
in a user-provided
serviceURL
is also optional. If present, it is
also copied into the generated JMXServiceURL
;
otherwise, the generated JMXServiceURL
has no port.
For an serviceURL
using the rmi
protocol, the port
, if present, indicates
what port the generated remote object should be exported on. It
has no other effect.
If the user provides an RMIServerImpl
rather than a
JMXServiceURL
, then the generated
JMXServiceURL
will have the local host name in its
host
part and no
port
.
As an alternative to the generated addresses just described,
the serviceURL
address supplied when creating a
connector server can specify a directory address in
which to store the provided or generated RMIServer
stub. This directory address is then used by both client and
server.
In this case, the serviceURL
has one of these two
forms:
service:jmx:rmi://host:port/jndi/jndi-name
service:jmx:iiop://host:port/jndi/jndi-name
Here, jndi-name
is a string that can be
supplied to {@link javax.naming.InitialContext#bind
javax.naming.InitialContext.bind}.
As usual, the host
and
:port
can be omitted.
The connector server will generate an
RMIServerImpl
based on the protocol
(rmi
or iiop
) and, for
rmi
, the port
if any. When
the connector server is started, it will derive a stub from this
object using its {@link
javax.management.remote.rmi.RMIServerImpl#toStub 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 JMXServiceURL
is:
service:jmx:rmi://ignoredhost/jndi/rmi://myhost/myname
then the connector server will generate an
RMIJRMPServerImpl
and store its stub using the JNDI
name
rmi://myhost/myname
which means entry myname
in the RMI registry
running on the default port of host myhost
. Note
that the RMI registry only allows registration from the local
host. So, in this case, myhost
must be the name
(or a name) of the host that the connector server is running
on.
In this JMXServiceURL
, the first rmi:
specifies the RMI
connector, while the second rmi:
specifies the RMI
registry.
As another example, if the JMXServiceURL
is:
service:jmx:iiop://ignoredhost/jndi/ldap://dirhost:9999/cn=this,ou=that
then the connector server will generate an
RMIIIOPServerImpl
and store its stub using the JNDI
name
ldap://dirhost:9999/cn=this,ou=that
which means entry cn=this,ou=that
in the LDAP
directory running on port 9999 of host dirhost
.
If the JMXServiceURL
is:
service:jmx:iiop://ignoredhost/jndi/cn=this,ou=that
then the connector server will generate an
RMIIIOPServerImpl
and store its stub using the JNDI
name
cn=this,ou=that
For this case to work, the JNDI API must have been configured
appropriately to supply the information about what directory to
use.
In these examples, the host name ignoredhost
is
not used by the connector server or its clients. It can be
omitted, for example:
service:jmx:iiop:///jndi/cn=this,ou=that
However, it is good practice to use the name of the host where the connector server is running. This is often different from the name of the directory host.
When using the default JRMP transport, RMI socket factories can
be specified using the attributes
jmx.remote.rmi.client.socket.factory
and
jmx.remote.rmi.server.socket.factory
in the
environment
given to the
RMIConnectorServer
constructor. The values of these
attributes must be of type {@link
java.rmi.server.RMIClientSocketFactory} and {@link
java.rmi.server.RMIServerSocketFactory}, respectively. These
factories are used when creating the RMI objects associated with
the connector.
An RMI connector client is usually constructed using {@link
javax.management.remote.JMXConnectorFactory}, with a
JMXServiceURL
that has rmi
or
iiop
as its protocol.
If the JMXServiceURL
was generated by the server,
as described above under "connector
addresses generated by the server", then the client will
need to obtain it directly or indirectly from the server.
Typically, the server makes the JMXServiceURL
available by storing it in a file or a lookup service.
If the JMXServiceURL
uses the directory syntax, as
described above under "connector addresses
based on directory entries", then the client may obtain it
as just explained, or client and server may both know the
appropriate directory entry to use. For example, if the
connector server for the Whatsit agent uses the entry
whatsit-agent-connector
in the RMI registry on host
myhost
, then client and server can both know
that the appropriate JMXServiceURL
is:
service:jmx:rmi:///jndi/rmi://myhost/whatsit-agent-connector
If you have an RMI stub of type {@link javax.management.remote.rmi.RMIServer RMIServer}, you can construct an RMI connection directly by using the appropriate constructor of {@link javax.management.remote.rmi.RMIConnector RMIConnector}.
When using the IIOP transport, the client and server can
specify what ORB to use
with the attribute java.naming.corba.orb
.
Connection to the ORB happens at {@link
javax.management.remote.rmi.RMIConnectorServer#start() start} time
for the connector server, and at {@link
javax.management.remote.rmi.RMIConnector#connect(java.util.Map)
connect} time for the connector client.
If the java.naming.corba.orb
attribute is contained
in the environment Map, then its value (an {@link
org.omg.CORBA.ORB ORB}), is used to connect the IIOP Stubs.
Otherwise, a new org.omg.CORBA.ORB is created by calling {@link
org.omg.CORBA.ORB
org.omg.CORBA.ORB.init((String[])null,(Properties)null)}. A
later RMI connector client or server in the same JVM can reuse
this ORB, or it can create another one in the same way.
If the java.naming.corba.orb
attribute is
specified and does not point to an {@link org.omg.CORBA.ORB ORB},
then an {@link java.lang.IllegalArgumentException}
will be thrown.
The mechanism described here does not apply when the IIOP Remote objects (Stubs or Servers) are created and connected to an ORB manually before being passed to the RMIConnector and RMIConnectorServer.
If an RMI connector client or server receives from its peer an instance of a class that it does not know, and if dynamic code downloading is active for the RMI connection, then the class can be downloaded from a codebase specified by the peer. The article Dynamic code downloading using Java RMI explains this in more detail.
@see JavaTM Remote Method Invocation (RMI) @see Java Naming and Directory InterfaceTM (JNDI) @see RFC 2045, section 6.8, "Base64 Content-Transfer-Encoding" @since 1.5