From the docs
It is not a general-purpose publish-subscribe system, nor is it intended for interprocess communication
What do they mean by saying it's not a general-purpose publish-subscribe system?
As far as I understand this is within a JVM only, publish/subscribe is usually between processes residing in potentially different places: like one JVM talking to another, suppose one Spring application publishing events that are to be consumed by another Spring application, residing in entirely different places.
It's better explained in the bottom of the EventBusExplained page:
Why can't I do <magic thing> with EventBus?
EventBus is designed to
deal with a large class of use cases really, really well. We prefer
hitting the nail on the head for most use cases to doing decently on
all use cases.
Additionally, making EventBus extensible -- and making it useful and
productive to extend, while still allowing ourselves to make additions
to the core EventBus API that don't conflict with any of your
extensions -- is an extremely difficult problem.
If you really, really need magic thing X, that EventBus can't
currently provide, you should file an issue, and then design your own
alternative.
(Emphasis mine.)
Compare EventBus to Kafka for example -- the latter is much more extensible but also more complex.
Related
I've read up on Jonathan Oliver's .NET EventStore library, and I must say the concept appeals to me a lot: having just a simple no-dependencies library which is non-intrusive and just focuses on event sourcing, leaving a lot of freedom when choosing technologies for databases, messaging, etc.
My question: Is something similar also available in the Java world? I know there are all kind of CQRS-related frameworks, like Axon and Jdon, but those do a lot more than just event sourcing... Anyone working on a straightforward port, perhaps?
I'm not aware of any that exist. At the same time, it wouldn't be terribly difficult to write one. The hardest part for me in writing the EventStore was arriving at the correct model. I had two private/internal releases within my company, and then two public releases before I was really satisfied with how things turned out. There are a few Ruby ports and other languages as well, and usually they take a few hours to write because the authors copy the model. If you take the same approach, I don't see why you couldn't write your own within a few hours.
I realize the question is old, but for those in a similar position now:
you could try Greg Young's EventStore (http://geteventstore.com)
It needs .NET or mono to run but there is a JVM-based client library:
https://github.com/EventStore/eventstorejvmclient
You could have a look at Occurrent which is designed to be used as a library. This means that you can use only the event store, and nothing else, and add more components when you find fit.
It's also designed to integrate well with popular frameworks such as Spring Boot if you want to use a framework on top (without necessarily having to use framework-specific code in your domain model).
In theory, it could support messaging, but appears to only support databases currently.
Using JDBC is not that much of an imposition and can wrapped up to suit your needs fairly easily. If you want simplicity, I would use JDBC.
If you want to support JMS (messaging) I would use only that (with an adapting service to any database you want to use) This gives you simple standard event driven interface for all types of messaging (and any database you connect to)
My question: What approach could/should I take to communicate between two or more JVM instances that are running locally?
Some description of the problem:
I am developing a system for a project that requires separate JVM instances to isolate certain tasks from each other entirely.
In it's running, the 'parent' JVM will create 'child' JVMs that it will expect to execute and then return results to it (in the format of relatively simple POJO classes, or perhaps structured XML data). These results should not be transferred using the SysErr/SysOut/SysIn pipes as the child may already use these as part of its running.
If a child JVM does not respond with results within a certain time, the parent JVM should be able to signal to the child to cease processing, or to kill the child process. Otherwise, the child JVM should exit normally at the end of completing its task.
Research so far:
I am aware there are a number of technologies that may be of use e.g....
Using Java's RMI library
Using sockets to transfer objects
Using distribution libraries such as Cajo, Hessian
...but am interested in hearing what approaches others may consider before pursuing one of these options, or any others.
Thanks for any help or advice on this!
Edits:
Quantity of data to transfer- relatively small, it will mostly be just a handful of POJOs containing strings that will represent the result of the child executing. If any solution would be inefficient on larger amounts of information, this is unlikely to be a problem in my system. The amount being transferred should be pretty static and so this does not have to be scalable.
Latency of transfer- not a critical concern in this case, although if any 'polling' of results is needed this should be able to be fairly frequent without significant overheads, so I can maintain a responsive GUI on top of this at a later time (e.g. progress bar)
Not directly an answer to your question, but a suggestion of an alternative.
Have you considered OSGI?
It lets you run java projects in complete isolation from each other, within the SAME jvm.
The beauty of it is that communication between projects is very easy with services (see Core Specifications PDF page 123). This way there is not "serialization" of any sort being done as the data and calls are all in the same jvm.
Furthermore all your requirements of quality of service (response time etc...) go away - you only have to worry about whether the service is UP or DOWN at the time you want to use it. And for that you have a really nice specification that does that for you called Declarative Services (See Enterprise Spec PDF page 141)
Sorry for the off-topic answer, but I thought some other people might consider this as an alternative.
Update
To answer your question about security, I have never considered such a scenario. I don't believe there is a way to enforce "memory" usage within OSGI.
However there is a way of communicating outside of JVM between different OSGI runtimes. It is called Remote Services (see Enterprise Spec PDF, page 7). They also have nice discussion there of the factors to take into consideration when doing something like that (see 13.1 Fallacies).
Folks at Apache Felix (implementation of OSGI) I think have implementation of this with iPOJO, called Distributed Services with iPOJO (their wrapper to make using services easier). I've never used this - so ignore me if I am wrong.
I'd use KryoNet with local sockets since it specialises heavily in serialisation and is quite lightweight (you also get Remote Method Invocation! I'm using it right now), but disable the socket disconnection timeout.
RMI basically works on the principle that you have a remote type and that the remote type implements an interface. This interface is shared. On your local machine, you bind the interface via the RMI library to code 'injected' in-memory from the RMI library, the result being that you have something that satisfies the interface but is able to communicate with the remote object.
akka is another option, as well as other java actor frameworks, it provides communication and other goodies derived from the actor model.
If you can't use stdin/stdout, then i'd go with sockets. You need some sort of serialization layer on top of the sockets (as you would with stdin/stdout), and RMI is a very easy to use and pretty effective such layer.
If you used RMI and found the performance wasn't good enough, i'd switch to some more efficient serializer - there are plenty of options.
I wouldn't go anywhere near web services or XML. That seems like a complete waste of time, likely take more effort and deliver less performance than RMI.
Not many people seem to like RMI any longer.
Options:
Web Services. e.g. http://cxf.apache.org
JMX. Now, this is really a means of using RMI under the table, but it would work.
Other IPC protocols; you cited Hessian
Roll-your-own using sockets, or even shared memory. (Open a mapped file in the parent, open it again in the child. You'd still need something for synchronization.)
Examples of note are Apache ant (which forks all sorts of Jvms for one purpose or another), Apache maven, and the open source variant of the Tanukisoft daemonization kit.
Personally, I'm very facile with web services, so that's the hammer which which I tend to turn things into nails. A typical JAX-WS+JAX-B or JAX-RS+JAX-B service is very little code with CXF, and manages all the data serialization and deserialization for me.
It was mentioned above, but i wanted to expand a bit on the JMX suggestion. we actually are doing pretty much exactly what you are planning to do (from what i can glean from your various comments). we landed on using jmx for a variety of reasons, a few of which i'll mention here. for one thing, jmx is all about management, so in general it is a perfect fit for what you want to do (especially if you already plan on having jmx services for other management tasks). any effort you put into jmx interfaces will do double duty as apis you can call using java management tools like jvisualvm. this leads to my next point, which is the most relevant to what you want. the new Attach API in jdk 6 and above is very sweet. it enables you to dynamically discover and communicate with running jvms. this allows, for example, for your "controller" process to crash and restart and re-find all the existing worker processes. this is the makings of a very robust system. it was mentioned above that jmx basically rmi under the hood, however, unlike using rmi directly, you don't need to manage all the connection details (e.g. dealing with unique ports, discoverability, etc). the attach api is a bit of a hidden gem in the jdk, as it isn't very well documented. when i was poking into this stuff initially, i didn't know the name of the api, so figuring how the "magic" in jvisualvm and jconsole worked was very difficult. finally, i came across an article like this one, which shows how to actually use the attach api dynamically in your own program.
Although it's designed for potentially remote communication between JVMs, I think you'll find that Netty works extremely well between local JVM instances as well.
It's probably the most performant / robust / widely supported library of its type for Java.
A lot is discussed above. But be it sockets, rmi, jms - there is a lof of dirty work involved.
I would ratter advice akka. It is a actor based model which communicate with each other using Messages.
The beauty is, the actors can be on same JVM or another (very little config) and akka takes care the rest for you. I haven't seen a more cleaner way than doing this :)
Try out jGroups if the data to be communicated is not huge.
How about http://code.google.com/p/protobuf/
It is lightweight.
As you mentioned you can obviously send the objects over the network but that is a costly thing not to mention start up a separate JVM.
Another approach if you just want to separate your different worlds inside one JVM is to load the classes with different classloaders. ClassA#CL1!=ClassA#CL2 if they are loaded by CL1 and CL2 as sibling classloaders.
To enable communications between classA#CL1 and classA#CL2 you could have three classloaders.
CL1 that loads process1
CL2 that loads process2 (same classes as in CL1)
CL3 that loads communication classes (POJOs and Service).
Now you let CL3 be the parent classloader of CL1 and CL2.
In classes loaded by CL3 you can have a light-weight communication send/receive functionality (send(Pojo)/receive(Pojo)) the POJOs between classes in CL1 and classes in CL2.
In CL3 you expose a static service that enables implementations from CL1 and CL2 register to send and receive the POJOs.
I wonder how is the best way to integrate Java modules developed as separate J(2)EE applications. Each of those modules exposes Java interfaces. The POJO entities (Hibernate) are being used along with those Java interfaces, there is no DTO objects. What would be the best way to integrate those modules i.e. one module calling the other module interface remotely?
I was thinking about: EJB3, Hessian, SOAP, JMS. there are pros and cons of each of the approaches.
Folks, what is your opinion or your experiences?
Having dabbled with a few of the remoting technologies and found them universally unfun I would now use Spring remoting as an abstraction from the implementation.
It allows you to concentrate on writing your functionality and let Spring handle the remote part with some config. you have the choice of several implementations (RMI, Spring's HTTP invoker, Hessian, Burlap and JMS). The abstraction means you can pick one implementation and simply swap it if your needs change.
See the SpringSource docs for more information.
The standard approach would be to use plain RMI between the various service components but this brings issues of sharing your Java interfaces and versioning changes to your domain model especially if you have lots of components using the same classes.
Are you really running each service in a separate VM? If these EJBs are always talking to each other then you're best off putting them into the same VM and avoiding any remote procedure calls as these services can use their LocalInterfaces.
The other thing that may bite you is using Hibernate POJOs. You may think that these are simple POJOs but behind the scenes Hibernate has been busy with CGLib trying to do things like allow lazy initialization. If these beans are serialzed and passed over remote boundaries then you may end up with odd Hibernate Exception getting thown. Personally I'd prefer to create simple DTOs or write the POJOs out as XML to pass between components. My colleagues would go one step further and write custom wire protocols for transferring the data for performance reasons.
Recently I have been using the MULE ESB to integrate various service components. It's quite nice as you can have a mix of RMI, sockets, web services etc without having to write most of the boiler plate code.
http://www.mulesource.org/display/COMMUNITY/Home
Why would you go with anything other than the simplest thing that works?
In your case that sounds like EJB3 or maybe JMS, depending on whether the communication needs to be synchronous or asynchronous.
EJB3 is by far these easiest being built on top of RMI with the container providing all the additional features you might need - security, transactions, etc. Presumably your POJOs are in a shared jar and therefore can simply be passed between your EJBs, although I tend towards passing value objects myself. The other benefit of EJB is, when done right, that it's the most performant (that's just my opinion btw ;-).
JMS is a little more involved, but not much and a system based on asynchronous communication affords certain niceties in terms of parallelizing tasks, etc.
The performance overhead of web-services, the inevitable extra config and additional points of failure make them, IMHO, not worth the hassle unless you've a requirement that mandates their use - I'm thinking interop with non-Java clients or providing data to external parties here.
If you need network communication between Java-only applications, Java RMI is the way to go. It has the best integration, most transparency and the least overhead.
If, however, some of your clients aren't Java-based, you should probably consider other options (Java RMI actually have an IIOP-dialect, which allows it to interact with CORBA, however - I wouldn't recommend doing this, unless it's for some legacy-code integration). Depending on your needs, webservices are probably your friend. If you are conserned with the networkload, you could go webservices over Hessian.
You literally mean remotely? As in running in a different environment with therefore different availability characteristics? With network overheads?
Assuming "yes" my first step would be to take a service approach, set aside the invocation technology for a moment. Just consider the design and meaning of your services. You know they are comparativley expensive to invoke, hence small busy interfaces tend to be a bad thing. You know that the service system might fail between invocations, so you may favour stateless services. You may need to retry requests after failure, so you may favour idempotent service designs.
Then consider availability relationships. Can your client work without the remote system. In some cases you simply can't progress if the remote system isn't available (eg. can't enable the employee if you can't get to the HR system) in other cases you can adopt a "fire-and-tell-me-later" philosophy; queue up the requests and process responses later.
Where there is an availability depdency, then simply exposing a synchronous interface seems to fit. You can do that with SLSB EJBs, if everything is Java EE, that works. I tend to generalise expecting that if my services are useful then non Java EE clients may want them too. So SOAP (or REST) tends to be useful. These days adding a web service interface to your SLSB is pretty trivial.
But my pet theory is that any sufficiently large IT system ends up needing aynch communications: you need to decouple the availability contraints. So I would tend to look for a JMS-style relationship. An MDB facade in front of your services, or SOAP/JMS is not too hard to do. Such an approach tends to highlight the failure-case design issues that were probably lurking anyway, JMS tends to make you think: "suppose I don't get an answer? suppose my answer comes late?"
I would go for SOAP.
JMS would be more efficient but you would need to code up an message driven bean for each interface.
SOAP on the other hand comes with lots of useful toolkits that will generate your message definition (WSDL) and all the neccesary handlers (client and server) when given an EJB.
With soap you can (but dont have to) deal with certificate security and secure connections over public networks. As the default protocol is HTTP over port 80 you will have minimal pain with firewalls etc. SOAP is also great for hetrogenious clients (in your case anything that isn't J2EE) with good support for most common languages on most common platforms.
Building a client-side swing application what should be notified on a bus (application-wide message system, similar in concept to JMS but much simpler) and what should be notified using direct listeners?
When using a bus, I always have an unescapable feeling of "I have no idea who uses that and where". Also, no set order, hard to veto events, hard to know exactly what's going on at a set time.
On the other hand, using listeners means either directly referencing the source object (coupling) or passing the reference through myriad conversions (A--b_listener-->B, B--c_listener-->C only because a needs to know something only C can to tell, but B has no interest in).
So, are there any rule of the thumb regarding this? Any suggestion how to balance?
In my experience, trying to make Swing do something it wasn't designed for, or doesn't want you to do, is extremely painful.
I would go with the simplest thing that would work; keep your code clean, do it the "Swing Way" until you start seeing problems.
Event buses are very, very useful tools for providing decoupling in certain architectures. Listeners are easy to implement, but they have significant limitations when your object and dependency graph gets large. Listeners tend to run into problems with cyclic dependencies (events can 'bounce' in odd ways, and you wind up having to play games to ensure that you don't get stuck. Most binding frameworks do this for you, but there's something distasteful about knowing that listener events are shooting off into a million places).
I make this kind of decision based on project size and scalability. If it's a big app, or there are aspects of the app that can by dynamic (like plugin modules, etc...) then a bus is a good way to keep the architecture clean (OSGI-like module containers are another approach, but heavier weight).
If you are considering a bus architecture, I recommend that you take a look at the Event Bus project - it works very well with Swing and provides a robust, out of the box solution for what you are asking about.
The convention in Java Swing is to use listeners heavily. Sticking with the convention improves maintainability but stifles innovation.
I've not encountered the bus approach in Swing, but I find it interesting.
Well, I can imagine the approach where models are updated using BUS like system and events from models are delegated using listeners. Simple scenario: I got server side which represents producer of data. Then on client side a got consumer interface which consumes all incoming messages and transform them into my internal messages/DTOs and push them into bus which distributes them into application model(s). These model process incoming messages and decide to notify interested components using listeners.
what is the best method for inter process communication in a multithreaded java app.
It should be performant (so no JMS please) easy to implement and reliable,so that
objects & data can be bound to one thread only?
Any ideas welcome!
Could you clarify a bit? Do you mean IPC in a single JVM? (Multiple threads, yes, but at an OS-level only one process.) Or do you mean multiple JVMs? (And truly OS-level inter process communications.)
If it is the first, then maybe something out of java.util.concurrent, like ConcurrentLinkedQueue would do the trick. (I pass message around inbetween my threads with classes from java.util.concurrent with success.)
If the later, then I'm going to just guess and suggest taking a look at RMI, although I don' think it qualifies as fully reliable--you'd have to manage that a bit more 'hands on' like.
Assuming the scenario 1 JVM, multiple threads then indeed java.util.concurrent is the place to look, specifically the various Queue implementations. However an abstraction on top of that may be nice and there Jetlang looks very interesting, lightweight Java message passing.
I recommend looking into the entire java.util.concurrent package, which have multiple classes for dealing with concurrency and different communication means between threads. All depends on what you want to achieve, as your question is pretty general.
You should use a producer/consumer queue. By doing that you avoid the pitfalls of multithreaded programming: race-conditions and deadlocks. Plus it is not just easier and cleaner, but also much faster if you use a lock-free queue like Disruptor or MentaQueue. I wrote a blog article where I talk about this in detail and show how to get < 100 nanoseconds latencies: Inter-thread communication with 2-digit nanosecond latency.
I've just added MappedBus on github (http://github.com/caplogic/mappedbus) which is an efficient IPC library that enable several Java processes/JVMs to communicate by exchaning messages and it uses a memory mapped file for the transport. The troughput has been measured to 40 million messages/s.