views:

59

answers:

2

Our current app runs in a single JVM.

We are now splitting up the app into separate logical services where each service runs in its own JVM.

The split is being done to allow a single service to be modified and deployed without impacting the entire system. This reduces the need to QA the entire system - just need to QA the interaction with the service being changed.

For inter service communication we use a combination of REST, an MQ system bus, and database views.

What I don't like about this:

  • REST means we have to marshal data to/from XML
  • DB views couple the systems together which defeats the whole concept of separate services
  • MQ / system bus is added complexity
  • There is inevitably some code duplication between services
  • You have set up n JBoss server configurations, we have to do n number of deployments, n number of set up scripts, etc, etc.

Is there a better way to structure an internal application to allow modular development and deployment while allowing the app to run in a single JVM (and achieving the associated benefits)?

+3  A: 

I'm a little confused as to what you're really asking here. If you split your application up into different services running across the network, then data marshalling has to occur somewhere.

Having said that, have you investigated OSGi ? You can deploy different bundles (basically, jar files with additional metadata defining the interfaces) into the same OSGi server, and the server will facilitate communication between these bundles transparently, since everything is running within the same JVM - i.e. you call methods on objects in different bundles as you would normally.

An OSGi server will permit unloading and upgrades of bundles at runtime and applications should run normally (if in a degraded fashion) provided the OSGi bundle lifecycle states are respected.

Brian Agnew
Thanks for the response. How does the server "facilitate communication" between the bundles?
Marcus
I've expanded on this in the edited response. You simply call the methods required.
Brian Agnew
What I'm getting at is how can you NOT split the app up? To have it run in the same JVM, but have it designed so you can deploy separate "modules" of the application on their own. By doing this, you have some confidence that the only part of the app that changed is "module A" and all you need to QA is the communication between "module A" and the rest of your app. And this will also reduce the risk that a change has crept into another one of your modules and causes some issues when all you meant to deploy is "module A".
Marcus
Ah. I've expanded on that further.
Brian Agnew
A: 

It sounds like your team has a manual QA process and the real issue is automating regression tests so that you can deploy new releases quickly and with confidence. Breaking up the code into separate servers is a workaround for that.

If you're willing to restart the server then one approach might be to compile the code into separate jar files, and deploy a module by dropping in a new jar and restarting. This is largely a matter of structuring your code base so that bad dependencies don't creep in and the calls between jars are made via interfaces that don't change. (Or alternately, use abstract classes so you can add a new method with a default implementation.) Your build system could help by making sure that separately deployed modules can only depend on common interfaces and anything else is a compile error. But note that your compiler isn't going to help you detect incompatibilities when you're swapping in jars that you didn't compile against, so I'm not sure this really avoids having a good QA process.

If you want to deploy new code without restarting the JVM then OSGI is the standard way to do that. (But one that I know little about.)

Brian Slesinsky