closing rmi registry - java

Using RMI to pass String object from WebAppA to WebAppB.WebAppB is the RMIServer whereas WebAppA is RMIClient.I have added ContextListener in WebAppB, so that the rmi service starts right away when the context is initialized in tomcat.And in the contextDestroyed method of tomcat I am trying to close/shut down rmi using the following statements:
unexportObject(remoteObj,true);
LocateRegistry.getRegistry(3232).unbind("MessagePath"); //MessagePath - name of the remote reference
But even after the execution of the aforeseen statements, rmi is listening for incoming requests at port 3232.I saw that by using "netsat -ano" in command prompt.Please do help me to close RMI Service.

getRegistry returns a stub only, so use the instance returned by createRegistry in unexportObject. However in my case this does not help either - the registry is not active anymore, but the sockets are still open and listening :-(

createRegistry won't work when you're trying to shutdown the registry.
Registry registry = LocateRegistry.createRegistry(3232);
This will throw a BindException when the registry is already running. So you cannot the create object to use it in
UnicastRemoteObject.unexportObject(registry, true);
However, even if you use
Registry registry = LocateRegistry.getRegistry(3232);
You just get the stub, which cannot be used as a parameter to unexport the object.
The reason its a cause of concern for me is because I only wish to start the registry if I could check it has not started yet. And I haven't found a way to do that!

I have found a way of shutting down the registry from any process (and for that matter shutting down any bound processes which are bound in the registry)
Any of the Interfaces which extends remote and which you eventually want to kill off should also extend the following Interface:
public interface PIDSupplierInterface extends Remote {
String getPID() throws RemoteException;
}
every server class you create with this as part of its interface must then implement getPID(). The thing you then have to do is return the process ID. Google "getpids" for Windows, or go here: www.jroller.com/santhosh/entry/get_current_java_process_id. For Linux as I understand it getting the PID is more straightforward. Then (in Windows) you want to go
String PID = myServer.getPID();
String[] a_command = { "taskkill", "/pid", PID };
Runtime.getRuntime().exec(a_command, envp, dir);
to kill off the PID of the registry itself, first, when starting the registry (programatically), simply go
PIDSupplierInterface stub = PIDSupplierInterface)UnicastRemoteObject.exportObject(
new PIDSupplierServer(), 0);
reg.bind( "regKiller", stub );
where PIDSupplierServer is a class which implements only PIDSupplierInterface.
Then, when you want to kill off the RMI registry from any Process just go
PIDSupplierInterface regProcess = (PIDSupplierInterface)reg.lookup( "regKiller" );
String regPID = regProcess.getPID();
String[] a_command = { "taskkill", "/pid", regPID };
Runtime.getRuntime().exec(a_command, envp, dir);
the reg has disappeared from your system. Or is your question more complicated for some reason? Any comments welcome.

Related

Restart Java RMI registry on same or different port on Windows only after timeout

I have an RMI server which publishes an object like so:
int port = ....;
String name = "...";
Remote server = UnicastRemoteObject.exportObject(someobject, port+1);
Registry registry = LocateRegistry.createRegistry(port);
registry.rebind(name, server);
log.info("created service name "+name+", on port "+(port+1)
+" in registry on port "+port);
When I stop the program and just rerun it, it logs that it has created everything, but then immediately exits, likely due to the rmi server thread exiting (the last non-daemon). I registered a defaultUncaughtExceptionHandler, but get nothing logged from it. Only after a minute or so I am able to restart the program without it immediately exiting.
If I would always use the same port, this would only half surprise me, because I know that ports may be blocked a little while after their last use. But the behavior is the same even if I use a different port (+100 or so) each time.
Any ideas why this happens and how to possible prevent it?
You need to store the result of createRegistry() into a static variable. Otherwise it is liable to be garbage-collected.

RMI connection with wifi and dialup internet

I have created a simple database application using rmi. It works fine with my local wireless network. But now i want to connect my client to the server through the internet. I know that, this can be achieved with setting up port forwarding in the router. But i want it to work in any computer which is connected to the internet using wifi connections, dialup
connections etc. How to do that?
what to write here? Naming.lookup ("rmi://?????????????");
As I am quite new to java, Please give me a detailed answer with a simple code example.
Thanks in advance
I hope you are messed up with Java RMI Concept. Irony is that a few days ago I was also thinking up the same except that I was thinking to connect up on my internal network.
There are two kinds of classes that can be used in Java RMI.
A Remote class is one whose instances can be used remotely. An object
of such a class can be referenced in two different ways:
1. Within the address space where the object was constructed, the object is an ordinary object which can be used like any other object.
2. Within other address spaces, the object can be referenced using an object handle. While there are limitations on how one can use an
object handle compared to an object, for the most part one can use
object handles in the same way as an ordinary object.
A Serializable class is one whose instances can be copied from one
address space to another. An instance of a Serializable class will be
called a serializable object. In other words, a serializable object is
one that can be marshaled.
SO, HERE COMES THE ANSWER TO YOUR QUESTION,ASSUMING YOU ARE TALKING ABOUT REMOTE CLASS ON DIFFERENT SYSTEM(SERVER).
The name of a remote object includes the following information:
The Internet name (or address) of the machine that is running the
Object Registry with which the remote object is being registered. If
the Object Registry is running on the same machine as the one that is
making the request, then the name of the machine can be omitted.
The port to which the Object Registry is listening. If the Object
Registry is listening to the default port, 1099, then this does not
have to be included in the name.
The local name of the remote object within the Object Registry.
The URL for a remote object is specified using the usual host, port and name:
rmi://host:port/name
host = host name of registry (defaults to current host)
port = port number of registry (defaults to the registry port number)
name = name for remote object
Assuming that your code is lying on the server having host-name as "XYZ.edu/home/CLasses"(you can give the DNS/IP-Address of server and include the location of the Class file),port-number="1099"(default) and name of the remote Object="abc" for your ABC.java Class in Server. In this way one will be able to call the Remote Object from different machines. Also, you need to keep the whole Server code on the Internet Address so that Clients can access them from the Internet(one can't access the offline-code present in your machine). Then only it can happen!!!
Here is the example Client program:
/**
* Client program for the "Hello, world!" example.
* #param argv The command line arguments which are ignored.
*/
public static void main (String[] argv) {
try {
HelloInterface hello =
(HelloInterface) Naming.lookup ("//ortles.ccs.neu.edu/Hello"); //see here the address of the server hosting the Server file,you can omit port number,it'll take default port 1099.
System.out.println (hello.say());
} catch (Exception e) {
System.out.println ("HelloClient exception: " + e);
}
}

Syslog4J (syslog) server not starting on Mac

I have the following code for custom syslog server (using Syslog4J) which works on Windows.
final UDPNetSyslogServerConfig udpConfig = new UDPNetSyslogServerConfig();
udpConfig.setPort(Integer.parseInt(port));
udpConfig.setHost(host);
udpConfig.addEventHandler(new Handler());
udpConfig.setUseDaemonThread(false);
SyslogServerIF server = SyslogServer.createInstance(host + port, udpConfig);
server.run();
It listens for the incoming events and invokes handler (method) whenever the event is received.
If I run the same code on Mac, it just comes out. Even if I use a loop to wait for the events, the events are not captured.
while (!stop) {
SyslogUtility.sleep(1000);
}
Even the handler's initialize() method is not invoked on Mac.
What port are you trying to use on Mac?
Is it in conflict with an in-use port (default is 514)?
Check /etc/syslog.conf on MacOS to see what port it is using for the built in syslog. On Ubuntu, this can be found in /etc/rsyslog.conf.

Java RMI - Remote Call from Ubuntu to OSX super slow

when I call a method from a RMI Ubuntu client on the OSX server passing an UnicastRemoteObject as parameter, things are super slow. So slow, that eventually, it gets executed but more likely, I get timeout exceptions after like 2-3 minutes. Both machines are in the same network. It's a freshly installed Ubuntu 12.04. I can telnet from the Ubuntu machine to the OSX one on the used RMI port, so at this point, it doesn't seem to be a problem. I can also call methods on the server without this UnicastRemoteObject parameter and everything works fine. From OSX to OSX is also fine...
This is, how the server gets started:
LocateRegistry.createRegistry(port);
nodeManager = new NodeManagerImpl(maxConfigurationsPerNode, true);
Registry registry = LocateRegistry.getRegistry(host, port);
registry.rebind("NodeManager", nodeManager);
And this is, how the client connects and calls the method:
Registry registry = LocateRegistry.getRegistry(host, port);
nodeManager = (NodeManager) registry.lookup("NodeManager");
handler = new NodeHandlerImpl();
id = nodeManager.register(handler, id);
NodeHandlerImpl is basically this:
public class NodeHandlerImpl extends UnicastRemoteObject implements NodeHandler {
public NodeHandlerImpl(boolean noSSL) throws RemoteException {
super(0, null, null);
}
....
}
The call to "register" is the one taking ages... NodeHandler extends Remote. When I remove the parameter handler, everything works fine again...
I'm a bit stuck here since a few hours, any clue would be great.
// Edit: Yep, Reverse DNS was the error.
With this hint, I found this site:
http://www.communardo.de/home/techblog/2008/09/17/rmi-kommunikation-zu-remote-hosts-mit-unguenstiger-dns-konfiguration/
So I changed my client connect code to the following and everything was fine:
System.setProperty("java.rmi.server.hostname", host);
Registry registry = LocateRegistry.getRegistry(host, port);
nodeManager = (NodeManager) registry.lookup("NodeManager");
handler = new NodeHandlerImpl();
id = nodeManager.register(handler, id);
This is most likely DNS misconfiguration. Java uses both DNS and reverse DNS. Make sure both are working correctly at both client and server hosts when looking up the other.

rmi registry: best way to assure there's one running?

I'm missing something about the difference between
starting rmiregistry at the command prompt (separately from whatever Java process is running a server that implements an RMI interface)
having the server call LocateRegistry.getRegistry()
having the server call LocateRegistry.createRegistry(Registry.REGISTRY_PORT)
I just want my server to register its exported objects with the registry, creating one if there isn't one running already. What's the best way to do this?
Old thread but...
man rmiregistry
says:
The methods of the java.rmi.registry.LocateRegistry class are used to
get a registry operating on the local host or local host and port.
otherwise you have:
The URL-based methods of the java.rmi.Naming class operate on a registry and can be used to look up a remote object on any host and on the local host
So I guess that's the important difference. Other thing is SecurityManager and policies.
This is how I used to do it, not sure if it is the right way though :/. I also had to mess around with policy files, so if this gives you trouble as well (the security manager part) you must create a policy file and use it.
try
{
try
{
java.rmi.registry.LocateRegistry.createRegistry(1099);
}
catch (java.rmi.server.ExportException e) { /* */ }
System.setSecurityManager(new java.rmi.RMISecurityManager());
Registry registry = LocateRegistry.getRegistry("127.0.0.1",1099);
registry.rebind(...);
}
catch (Exception e) { /* */ }
}

Categories