Communication between multiple JVMs

We have a Java toolkit that is shipped as a JAR file. The toolkit is ported from a C++ DLL running on Windows. Therefore, in both instances (Java and C++), we can't control who loads us or when.

I need to communicate between different JVMs running on the same machine. The communication is very simple: "Is this user logged on in your JVM?" I send a string to the other JVM and I get back a boolean. I don't need to worry about crossing machine boundaries. Also, I'm not expecting to have a huge number of JVMs running. Maybe 3 or 4 could be likely. However, the solution does need to scale in case there are more than that. I'm not setting a limit on the number of JVMs either.

The C++ code handled this situation very easily and elegantly. It created a named system semaphore (mutex) whenever a user logged on. The name of the mutex was the username. So, if there were multiple instances of the DLL running in separate processes (EXEs), we could easily tell if this user was logged on in another instance. We'd try to create the system semaphore - it would fail saying the name already exists. Therefore, we'd know the user was already logged on. The named system semaphore provided the means for a machine-global list - which is exactly what we wanted. It also had this extra benefit: if the process terminates normally or abnormally, the system semaphore is removed from memory. This means: the application is terminated, the user is no longer logged on, and we can relog this user on.

Therefore, I have 2 requirements:

1) A machine-global list where we can place a string. Keep in mind, it doesn't absolutely have to be a machine-global list. A suitable means to talk to other JVMs is acceptable too.

2) If the process exits normally or abnormally, the string(s) get removed (for this JVM) from the list. Abnormal termination is the more important one to focus on because lots of people of varying skill levels use our toolkit. Abnormal terminations can be common.

The first thought is to store these in a file. That solves #1, but not #2. I've seen the JIPC package. However, I'm not too crazy about requiring 3rd party developers to start up another program (JIPC) before they start up their application. As I said, we're just a toolkit so we can't control when or who loads us. It's not totally out of the question, but I'd prefer something else.

I have a fairly involved solution that involves sockets. The first JVM creates a ServerSocket on a specific port and becomes the server. Subsequent JVMs also try to create the ServerSocket on the same port. They get a BindException because the ServerSocket already exists, so they know they're clients. Then, they create a client socket and talk to the server that way. This gets a little hairy when the server goes away. The clients will scramble to become the server and then all the other clients need to reconnect to the new server.

This proposed solution sounds like it will address both requirements. However, I'm looking for something simpler. I'm asking this forum for help in case there's an easier way to do this. I don't have the breadth of experience with Java yet to know if there's a simpler way to fix this. If I have to go with the socket solution, I will. I just didn't want to overlook something simple that is already built into Java.

Thanks for any tips or suggestions

[3424 byte] By [eiStreamGreg] at [2007-9-30 20:25:21]
# 1

There is a difference between just wanting to save something, and wanting that something to go away under all conditions when the application exits.

For the first case you can look at java.util.prefs.Preferences.

If you need the second then you use one of the following...

- Sockets

- java.nio.channels.FileLock (but only if it works on the target systems)

- JNI and some OS dependent feature.

jschell at 2007-7-7 1:09:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 2

Thanks for the response.

FileLock. We still have to target JDK 1.3 so we can't use FileLocks (at this point)

JNI: That's an interesting idea. I suspect many people are using our software on Windows. Therefore, we could probably fix it in Windows the same as in the C++ code. If they're not on Windows, we could use the Sockets approach.

I also had another idea: how about hashing the username string into some integer (or long) value. Then use the hashed value to lock some other resource: like the port number passed to ServerSocket. I know ServerSocket only accepts 0 - 0xFFFF so this obviously won't work. But is there some other system-wide thing we could lock given an integral value?

eiStreamGreg at 2007-7-7 1:09:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 3

>

> I also had another idea: how about hashing the

> username string into some integer (or long) value.

> Then use the hashed value to lock some other resource:

> like the port number passed to ServerSocket. I know

> ServerSocket only accepts 0 - 0xFFFF so this obviously

> won't work. But is there some other system-wide thing

> we could lock given an integral value?

That doesn't seem to have anything to do with the original question and I am not sure of the point.

If you are using sockets then just use a socket. If you are worried about conflicts then implement a strategy to try several.

jschell at 2007-7-7 1:09:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 4
Never mind about the hashing value. As I think about it some more, it really wouldn't work. There's a chance two different strings could hash to the same value. That would foil the algorithm.Thanks for the responses
eiStreamGreg at 2007-7-7 1:09:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...