How to unload/kill rmiRegistry if app was terminated abnormally

Hello,

I use the following method in coding to [1] launch the RMIRegistry to listen on port PORT, [2] Exports the remote object to make it available to receive incoming calls, [3] Bind the service name to the Registry

int PORT = 1101;

String HOST_NAME ="myHost";

String SERVICE_NAME ="myRMIService";

LocateRegistry.createRegistry( PORT );

UnicastRemoteObject.exportObject( (MyRMIInterface)MyRMIObj );

Naming.rebind("//" + HOST_NAME +":" + Integer.toString( PORT ) +"/" + SERVICE_NAME, MyRMIObj);

However, If I the application was terminated abnormally and then restart the application, I always got the following exceptions separately (which I think the application will try to launch the RMIRegistry again and hence cause the following exceptions)

First Exception:

java.rmi.server.ExportException: internal error: ObjID already in use

at sun.rmi.transport.ObjectTable.putTarget(Unknown Source)

at sun.rmi.transport.Transport.exportObject(Unknown Source)

at sun.rmi.transport.tcp.TCPTransport.exportObject(Unknown Source)

at sun.rmi.transport.tcp.TCPEndpoint.exportObject(Unknown Source)

at sun.rmi.transport.LiveRef.exportObject(Unknown Source)

at sun.rmi.server.UnicastServerRef.exportObject(Unknown Source)

at sun.rmi.registry.RegistryImpl.setup(Unknown Source)

at sun.rmi.registry.RegistryImpl.<init>(Unknown Source)

at java.rmi.registry.LocateRegistry.createRegistry(Unknown Source)

....

Second Exception:

java.rmi.server.ExportException: Port already in use: 1101; nested exception is:

java.net.BindException: Address already in use: JVM_Bind

at sun.rmi.transport.tcp.TCPTransport.listen(Unknown Source)

at sun.rmi.transport.tcp.TCPTransport.exportObject(Unknown Source)

at sun.rmi.transport.tcp.TCPEndpoint.exportObject(Unknown Source)

at sun.rmi.transport.LiveRef.exportObject(Unknown Source)

at sun.rmi.server.UnicastServerRef.exportObject(Unknown Source)

at sun.rmi.registry.RegistryImpl.setup(Unknown Source)

at sun.rmi.registry.RegistryImpl.<init>(Unknown Source)

at java.rmi.registry.LocateRegistry.createRegistry(Unknown Source)

......

Caused by: java.net.BindException: Address already in use: JVM_Bind

at java.net.PlainSocketImpl.socketBind(Native Method)

at java.net.PlainSocketImpl.bind(Unknown Source)

at java.net.ServerSocket.bind(Unknown Source)

at java.net.ServerSocket.<init>(Unknown Source)

at java.net.ServerSocket.<init>(Unknown Source)

at sun.rmi.transport.proxy.RMIDirectSocketFactory.createServerSocket(Unknown Source)

at sun.rmi.transport.proxy.RMIMasterSocketFactory.createServerSocket(Unknown Source)

at sun.rmi.transport.tcp.TCPEndpoint.newServerSocket(Unknown Source)

... 11 more

I don't know how to [1] free the RMIRegistry from listening on PORT and [2] also to terminate it from the background (it seems that RMIRegistry was executed in the Windows Task background).

Has anyone got any experiences on dealing with this issue?

Thanks in advance!

[3346 byte] By [jdevnewbiea] at [2007-10-2 20:06:07]
# 1

1. You can only get these exceptions if the RMI Registry is still running, in which case you don't need to start another one.

2. If the RMI Registry is started from outside any given JVM that JVM has no way to shut it down. If it is started outside all JVMs but its own there is no way to shut it down other than brute force, e.g. ctrl/C or shutting down the computer.

ejpa at 2007-7-13 22:46:21 > top of Java-index,Core,Core APIs...
# 2

I've always considered running the registry within the same JVM as an application to be a crock.

As a simple example of the problems this can cause, try starting up a second server application that registers with the registry so started. If the first application - the one that started the registry - fails, then the second app is also in trouble.

In our - rmi heavy - application, we always start the rmiregistry as a separate service (under Windows).

Arranging for that service is also not necessarily a simple matter.

bschauwejavaa at 2007-7-13 22:46:21 > top of Java-index,Core,Core APIs...
# 3

My application is a console which have integrated functions, eg "Launch the server", "Configure Server (i.e. Port....)".

As a result, the server RMIRegistry was launched in program runtime.

However, I found that once the RMIRegistry was launched in code, I got not ideas to terminate it also by code, or through calling the Windows Task Manager to terminate the process (I didn't find the process rmiregistry.exe at the task list).

And also, has anyone know how to solve the exception of "ObjId in use"?

jdevnewbiea at 2007-7-13 22:46:21 > top of Java-index,Core,Core APIs...
# 4

> However, I found that once the RMIRegistry was

> launched in code, I got not ideas to terminate it

> also by code

// Start the registry

Registry registry = LocateRegistry.createRegistry(PORT);

// ...

// Stop the registry

UnicastRemoteObject.unexportObject(registry);

> And also, has anyone know how to solve the exception

> of "ObjId in use"?

See reply #1 point 1. This can only happen if the JVM containing the registry is still running, in which case the Registry is still running, so what's the problem?

I'm not clear what you can really mean by 'application terminated abnormally' if the JVM is still running. Anyway it seems you are trying to start another Registry from a JVM which is already running one. The answer to this is easy: 'don't'. You don't have to do it, you don't have to stop the existing one and start a new one, all you have to do is catch the exception and do LocateRegistry.getRegistry() instead.

ejpa at 2007-7-13 22:46:21 > top of Java-index,Core,Core APIs...
# 5

I would like to know what's the difference between LocateRegistry.getRegistry(PORT)

and LocateRegistry.createRegistry(PORT)

And, I know, the interface public static Registry LocateRegistry.getRegistry(int port) throws RemoteException

returns an object-type "Registry", but public static boolean UnicastRemoteObject.unexportObject(Remote obj, boolean force) throws NoSuchObjectException

accepts an object-type "Remote".

Can the "Registry"-type object be passed-to UnicastRemoteObjecdt.unexportObject()?

'application terminated abnormally" means the application was terminated by CTRL-C, or any exceptions raised casuing the application to terminate itself.

jdevnewbiea at 2007-7-13 22:46:21 > top of Java-index,Core,Core APIs...
# 6

> I would like to know what's the difference between

> LocateRegistry.getRegistry(PORT)

and

> LocateRegistry.createRegistry(PORT)

It's all there in the Javadoc.

> Can the "Registry"-type object be passed-to

> UnicastRemoteObjecdt.unexportObject()?

As it says in the Javadoc, Registry extends Remote.

> 'application terminated abnormally" means the

> application was terminated by CTRL-C, or any

> exceptions raised casuing the application to

> terminate itself.

I can only assume that you are catching some application exception and trying to restart the whole thing including the Registry from within the same JVM. If you are doing this and starting the Registry gives you 'ObjID in use' then obviously you don't have to start it.

If on the other hand the JVM containing the Registry and your application has completely exited, you can't get 'ObjID in use'.

ejpa at 2007-7-13 22:46:21 > top of Java-index,Core,Core APIs...
# 7
Thanks ejp.My application main console will launch a new frame, the frame will lauch the rmiregistry on start and which the frame defaultCloseOperation was set to DISPOSE_ON_EXIT, after closing thie frame and the console re-launch the frame again, then got the ObjId exception.
jdevnewbiea at 2007-7-13 22:46:21 > top of Java-index,Core,Core APIs...
# 8
I agree. The only problem is that you consider this to be a problem, and it isn't. Just catch the exception and react accordingly, probably by doing LocateRegistry.getRegistry() instead.
ejpa at 2007-7-13 22:46:21 > top of Java-index,Core,Core APIs...