81

I have the following situation:

I have 2 JVM processes (really 2 java processes running separately, not 2 threads) running on a local machine. Let's call them ProcessA an ProcessB.

I want them to communicate (exchange data) with one another (e.g. ProcessA sends a message to ProcessB to do something).

Now, I work around this issue by writing a temporary file and these process periodically scan this file to get message. I think this solution is not so good.

What would be a better alternative to achieve what I want?

haylem
  • 22,460
  • 3
  • 67
  • 96
tnk_peka
  • 1,525
  • 2
  • 15
  • 25
  • In the meantime [memory mapped files](https://stackoverflow.com/questions/25396664/shared-memory-between-two-jvms) have been added to the possibleapproaches. – Curiosa Globunznik Oct 24 '20 at 12:33

7 Answers7

92

Multiple options for IPC:

Socket-Based (Bare-Bones) Networking

  • not necessarily hard, but:
    • might be verbose for not much,
    • might offer more surface for bugs, as you write more code.
  • you could rely on existing frameworks, like Netty

RMI

  • Technically, that's also network communication, but that's transparent for you.

Fully-fledged Message Passing Architectures

  • usually built on either RMI or network communications as well, but with support for complicated conversations and workflows
  • might be too heavy-weight for something simple
  • frameworks like ActiveMQ or JBoss Messaging

Java Management Extensions (JMX)

  • more meant for JVM management and monitoring, but could help to implement what you want if you mostly want to have one process query another for data, or send it some request for an action, if they aren't too complex
  • also works over RMI (amongst other possible protocols)
  • not so simple to wrap your head around at first, but actually rather simple to use

File-sharing / File-locking

  • that's what you're doing right now
  • it's doable, but comes with a lot of problems to handle

Signals

  • You can simply send signals to your other project
  • However, it's fairly limited and requires you to implement a translation layer (it is doable, though, but a rather crazy idea to toy with than anything serious.

Without more details, a bare-bone network-based IPC approach seems the best, as it's the:

  • most extensible (in terms of adding new features and workflows to your
  • most lightweight (in terms of memory footprint for your app)
  • most simple (in terms of design)
  • most educative (in terms of learning how to implement IPC). (as you mentioned "socket is hard" in a comment, and it really is not and should be something you work on)

That being said, based on your example (simply requesting the other process to do an action), JMX could also be good enough for you.

Curiosa Globunznik
  • 3,129
  • 1
  • 16
  • 24
haylem
  • 22,460
  • 3
  • 67
  • 96
  • Keep in mind JMX has problems when dealing with multiple class loaders as objects are shared in the JVM. Casting is problematic. Maybe serialization/deserialization is sometimes needed. – LppEdd Oct 28 '20 at 23:32
23

I've added a library on github called Mappedbus (http://github.com/caplogic/mappedbus) which enable two (or many more) Java processes/JVMs to communicate by exchanging messages. The library uses a memory mapped file and makes use of fetch-and-add and volatile read/writes to synchronize the different readers and writers. I've measured the throughput between two processes using this library to 40 million messages/s with an average latency of 25 ns for reading/writing a single message.

MikaelJ
  • 331
  • 3
  • 5
  • 5
    if i'm not mistaken this lib maps some fixed sized file to the memory, and appends messages until end of file is reached, does that mean it simply dies when all is read from file? its not a ring buffer as far as i can tell – vach Nov 06 '17 at 09:15
7

What you are looking for is inter-process communication. Java provides a simple IPC framework in the form of Java RMI API. There are several other mechanisms for inter-process communication such as pipes, sockets, message queues (these are all concepts, obviously, so there are frameworks that implement these).

I think in your case Java RMI or a simple custom socket implementation should suffice.

Strelok
  • 50,229
  • 9
  • 102
  • 115
  • 1
    Like for pipes (named pipes). It is the easiest way because you just reading/writing ordinary file. – Dmitry Trifonov Apr 16 '18 at 16:27
  • @DmitryTrifonov Pipes only work for two threads running in the same JVM, this question was specifically for 2 different processes. – Ignace Vau Jul 12 '20 at 17:40
  • @IgnaceVau could you expand on pipes? I'd like to understand more (examples, documentation). Thanks! – LppEdd Oct 28 '20 at 23:08
3

Sockets with DataInput(Output)Stream, to send java objects back and forth. This is easier than using disk file, and much easier than Netty.

Alexei Kaigorodov
  • 13,189
  • 1
  • 21
  • 38
2

I tend to use jGroup to form local clusters between processes. It works for nodes (aka processes) on the same machine, within the same JVM or even across different servers.

Once you understand the basics it is easy working with it and having the options to actually run two or more processes in the same JVM makes it easy to test those processes easily.

The overhead and latency is minimal if both are on the same machine (usually only a TCP rountrip of about >100ns per action).

Martin Kersten
  • 5,127
  • 8
  • 46
  • 77
1

socket may be a better choice, I think.

Marcus
  • 6,701
  • 4
  • 19
  • 28
  • socket is hard to implement so i don't think it is a easy way, is there another solution ?? a higher level api, a framework, easier to implement. – tnk_peka Jun 08 '12 at 02:47
  • 1
    Hard or simple depends on the purpose. For a simple thing, I DO NOT believe that using the heavy libraries is more worth than simply creating a Socket class on your own. – M-D May 20 '16 at 15:36
0

Back in 2004 I implement code which do the job with sockets. Until then, many times I search for a better solution, because socket approach triggers firewall and my clients worry. There is no better solution until now. Client must serialize your data, send and server must receive and unserialize. It is easy.

Chameleon
  • 1,804
  • 2
  • 15
  • 21