Rather than speak in vague generalities lets go through two specific overlapping APIs - JavaSpaces and JMS - and think about what a unified version would look like.
Java Grand Unification Theory Some Specifics
Sorry it has taken me so long to get
back to this topic. I actually had a lengthy blog
written and pretty much ready to go, but decided against posting it.
The intent behind that blog was to elaborate a process for generating
the decision tree I discussed in
my last post. Unfortunately, it
came out sounding priggish, pretentious and process-enamored
(not to mention alliterative). I'll probably post it later anyway,
but was prevented from doing so this week by the intrusion of some
real design problems. Musing on these gave me the topic for this posting.
Electromagnetism, JavaSpaces and JMS
As a TIBCO/Rendezvous programmer of long standing, I've developed some facility with the
publish/subscribe model and I was attracted to JMS as soon as it was
announced. That background prevented me from understanding the
proper use of Jini/JavaSpaces (going back to the Java Shared Data
Toolkit) for quite some time. Over the past year, however, I've been
working on problems which are best suited to JavaSpaces and as a
result have come to understand that these two APIs are two sides of
the same coin in the same way that electricity and magnetism are
simply manifestations of the single underlying
phenomenon described by Maxwell's equations. (As you can
probably tell, I'm going to wear this physics analogy right down to
its nub, so you'll just have to bear with me until I've gotten it out
of my system.)
Since I've been thinking about some
specific problems with these two things a lot this week, I'm going to
take this opportunity to toss my thinking and a cleverly disguised
version of my current problems out into the blogosphere
and then listen to the echo rattling around.
Getting on Topic
I won't go into the specifics of the
two APIs here since about two minutes with
google will give you any number of
citations of people (including me) doing a compare and contrast
exercise on them. Suffice it to say that I perceive the main
differences to be:
JavaSpaces has the take
primitive that allows a message to be consumed by a single
subscriber, JMS does not.
JMS matches messages on
string-based topic names, JavaSpaces matches on Entry objects.
JMS dispenses with a centralized
server and its associated infrastructure while JavaSpaces requires
Apart from these differences, both JavaSpaces and JMS are
basically Message Oriented Middleware
(MOMs). Each allow an application to
asynchronously be a message source and/or message sink and
neither intrinsically allows a message source to be aware of which
sinks may have consumed a source's message.
I've used both Jini/JavaSpaces and JMS now
for computationally intensive tasks and have found the following (and
this gets us back to the topic of unification):
To completely implement the
Master/Worker pattern, I need additional glue code on top of either
of the two APIs
JavaSpaces needs a way for me to
group entries in the space: I end up sticking a string in each
entry that represents a group and I end up formatting that string so
that it can be decomposed into something tree-like (e.g.
org.worklet.finance.instrument.valuation). That string looks an
awful lot like a JMS Topic to me.
JMS needs a way for me to make
sure that my compute tasks aren't being duplicated: I end up
typically using a database to register the state of a compute
request and resolve race conditions. Basically, I let my SQL
database play the conflict resolution role of JavaSpaces.
JavaSpaces needs fail
over/replication/load balancing, this comes for free
in industrial strength JMS implementations.
JMS needs a server to retain
current state of any topic, this comes for free in
industrial strength JavaSpaces implementations.
Both APIs lack
an infrastructure out of the box to allow me to query worker state
or explore the topic space (i.e. Find out
what topics have people subscribed to them).
E pluribus unum
You can probably see what I'm getting
at here. The two APIs target subtly different
problems, and are actually quite good at dealing with the problems
they are designed to handle, i.e. they greatly facilitate the use of specific
design patterns associated with
at those problems. Specifically: pub/sub engines with JMS front ends are
gratefully used all over Wall St. to deal with the absolute flood
of market data that runs across a trading floor. Space-based
implementations have been helping folks with numerically intensive problems
for about as long. JavaSpaces and JMS were both created in a sense to make sure that
the Java platform had "coverage" of these two application spaces.
But as soon as I go to address my problem (via the
Master/Worker pattern) I find that I can use either (in fact both) of
them - provided I'm willing to add the necessary quanta of energy
involved to move the APIs to the next level. From a putting
my kids through private school vantage point, I appreciate
there being problems out there like this - but the fact of the matter
is that Master/Worker is a well-understood pattern whose use I think
will grow substantially in the near future. As a result, I would
argue that there ought to be a Java API which hides the implementation
details of this specific pattern. My feeling is that such an API would
subsume both JavaSpaces and JMS and would probably be associated with
Jini, but admittedly I'm a bigot about Jini.
So ideally I'd like to see Javaspaces and Jini evolve to have some features like the following:
Connectionless pushing of Java objects into topics.
Lets do the Jini code movement thing on a JMS backbone
Services spec'd out to sit on specific topics and do JavaSpaces-like
functionality complete with replication and failover
additional services which monitored the Master, Space, and Worker services
for administrative purposes.
Here's the conclusion I've come to for
my particular problem: I need to create a JMS/JavaSpaces
bridge. This will allow me:
to store JMS Topic state in JavaSpaces
to do a segmented replication of a JavaSpace (segmented by topics)
to piggyback off my existing JMS infrastructure with little coding effort
to load balance my JavaSpaces transparently to my clients
What's missing here is actually
bigger than what's present. How do I administer, deploy and manage a
rack of servers with all this software running on it? Sounds like I need to do some J2EE homework.
This series of posts are very nice to read. I share this feeling of hidden simmetry between all these communication technologies. Now I'm looking at Erlang <http://www.erlang.org> and it's distributed DBMS Mnesia. Both can be used to implement something like JMS (Erlang supports message queues natively, together with light-weight processes) and JavaSpaces (Mnesia can store arbitrary tuples and be queried over using Erlang syntax) without much hassle. I believe there's some light in that way, but they don't have a unifying theory. An interesting thing about Erlang is that, as far as you're listening to the correct port, you can match messages on patterns, so a single receiver can listen to messages looking like (Int, Int, String), (String, String), (Int, Atom), (Atom, String), etc., and ignore all other possible tuples, giving a space-like matching capability.
I also come from a TIBCO background and I'm currently working for a company that produces a commercial quality JavaSpaces implementation. I find it much easier to implement publish/subscribe messaging on top of JavaSpaces than to overcome the shortcomings of JMS noted in Van Simmons' article.
To establish groups in your entries, you could try the following rather than structured strings. I try to avoid using string-based naming patterns as much as possible, as you are susceptible to typos, and it is more difficult as a new programmer to recognize the pattern.
Create a tree of empty objects that serve as a naming tree. You add the object to your entry when you write it to the space. When you attempt to retrieve an item or group of items, include the object type in your template. So for instance you create a org.worklet.lifescience.proteinfolding.simulation class. If you want to readAll of this particular group, you make the request to the space with an empty entry, save a class of the group type you are interested in. You avoid the chance of making a typo, because your class won't compile if you type in an invalid classname.
I also think that the JavaSpaces implementation is intended to be a base upon which advanced services may be built. That is, using the primitive operations and structure of the system, most complicated operations are possible. From some of the other posts, it seems that indviduals and companies are working on "Value-Added" JavaSpaces. Many advanced functions are available in other implementations.
I was in a project group at UIUC that implemented a more adaptable tuple space system in Smalltalk. The project can be viewed here: http://wiki.cs.uiuc.edu/cs497rej/Smalltalk+Linda+system - there are links to a variety of Linda/TupleSpace systems and resources available from there.
I've got nothing agains JMS. I think it is a great tool for message passing, particularly for use between independent applications. But when you are interested in working with and sharing native objects between distributed apps, JavaSpaces (or a comparable tuplespace system) is the way to go.