views:

698

answers:

9

I have two processes written in java in two machines within my network that should pass simple chunks of data to each other.


I'm looking for a quick and dirty way (without resorting to writing files and polling for changes on network share files)

A: 

The question is not clear. Are you looking for an API or library to use? Do the two machines know each other's address to begin with or do they need to discover each other?

You can use JMS for most communications, but all machines have to be familiar with a "broker process" that is running separately.

Uri
+5  A: 

java RMI (remote method interface)

Steve B.
Don't you need JNDI setup also? Hardly seems like quick and dirty.
Allain Lalonde
It's better than sockets. If you don't want to write to a shared file system, then what other choice is there?
Outlaw Programmer
JMS, Terracotta, Spring Remoting, HTTP, XMPP, anything but RMI. Yech.
Taylor Gautier
+1  A: 

What you have described is the quick (and not really that quick) and dirty way. The only other ways of accomplishing the task are setting up the processes to listen and send data through sockets (be that implemented directly by you - in java it is very easy, just Google and you will find, or as part of an library - probably needed for anything more complex)

So each process would have a listener on a specific port and every so often would send data across that port.

Jamie Lewis
+2  A: 

Assuming the machines have each other's addresses (getting said addresses is a different issue), I think your best bet is Spring remoting. You have a data passing interface, a domain object that encapsulates the data you want to pass, and a remoting service implementing that interface on each side. After that, your code treats the remote service as just another collaborator. Cheap, easy, fast, and you can use whatever transport you like (RMI, HTTP, Hessian, Burlap etc).

It usually takes me about 10 minutes (at most) to expose an existing interface/service as a remoting service, though first time will take a little longer.

GaryF
+1  A: 

I'll second the idea of having your processes communicate via sockets, and mention that Apache's MINA package makes that sort of thing very simple and robust, as well as scalable, without the overhead of a larger system like RMI or JMS. It also contains some good support for encoding and decoding messages. I've used very successfully in a medium-scale system.

This kind of communication tends to be pretty easy to abstract, too. Whether or not you use MINA, once you have classes set up to handle establishing/tearing down connections and moving data across the connections, they will probably be highly reusable.

MattK
A: 

I find RMI to be somewhat annoying. You have to define 3 files for a single remote object and you have to learn stuff that's outside the normal development process if you don't already know how to use it (I believe there is a separate compiler step involved).

There may be tools to make it work, but might I suggest just opening a simple socket? They are pretty close to trivial to use.

The only caveat is that you should be careful about defining what flows between the computers.

Bill K
stubs/skels as well as rmic went away when java 5 came out
basszero
I was thinking of the local and remote interfaces as well as the actual class definitions for both local and remote objects just to pass a string, but it's good to know that the remote compile step is gone, maybe I'll give it another try.
Bill K
ahhhhh ... yes, THOSE objects. I've found that the Proxy class combined with some careful reflection can abstract away some of the painful calls. Make a Proxy for your remote interface and delegate calls into the real object. Seamless.
basszero
+2  A: 

JMS over the ActiveMQ Broker is very easy. Its available here. The following is quick and dirty pseudo code to send a message, but as you can see its minimal code. Consider two Java apps, a publisher and a subscriber.

  1. Create a broker in one of your publisher:

    BrokerService broker = new BrokerService();    
    broker.addConnector("tcp://localhost:61616");    
    broker.setPersistent(false);    
    broker.start();
    
  2. Setup connections in both applications (Note: the subscriber will replace local host with the address of the machine running the broker):

    final ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");    
    TopicConnection connection = factory.createTopicConnection();    
    Session session = connection.createSession(false,Session.DUPS_OK_ACKNOWLEDGE);
    
  3. Send data in the publishing application:

    Topic topic = session.createTopic("Quick and dirty topic");
    MessageProducer producer = session.createProducer(topic);    
    ObjectMessage message = session.createObjectMessage();    
    message.setObject((Serializable) "Object you want to send");    
    producer.send(message);
    
  4. In you subscribing app (which must implement javax.jms.MessageListener) the following setup is needed:

    Destination dest = session.createTopic("Quick and dirty topic");    
    MessageConsumer consumer = session.createConsumer(dest);    
    consumer.setMessageListener(this);
    
  5. The subscribing app's onMessage(Message arg0) method (which it has because its a MessageListener) will be notified of the published objects.

bcash
A: 

I totally agree with GaryF Spring Remoting is the best option, it's quick and clean. If you are not familiar at all with Spring it can take you a little time at first. But believe me it totally worth it.

+1  A: 

You might find Terracotta to be a very easy way to do this. Terracotta allows you to cluster a portion of your heap (for example, a HashMap) and see the contents of that map on all nodes. Setting this up is fairly trivial.

Alex Miller