We are well aware of the fact that you have a multitude of alternatives available to solve your particular integration problem. In this document we provide a comparison of some popular integration approaches and some of their pros and cons. We are intentionally not getting into product comparisons, so don't look here for a comparison with competing integration products. The reasons for that are simple:
- You would have no reason to trust our assessment.
- Product comparisons tend to represent a snapshot in time.
Both our product and our competitors' products change over time and we have better things to do than always keeping abreast of exactly which feature has lately been added by "FooBar Integrator Pro Enterprise Edition."
Technology comparisons tend to be more lasting than product comparisons and more valuable at that. That being said, you will have to compare the products, because even if they look alike on the surface, there often are suprising differences under the hood.
The one thing that we would like to stress ahead of time —because it can't be stressed enough— is the importance of correctly assessing the cost of maintaining your integration solution over time. Most technology or product evaluators do a fair job at assessing the strengths and weaknesses of different integration approaches with respect to the initial integration problem, but that is only the first step. Over the years, your early choices can come back to haunt you because they only solved the small, initial problem but not the bigger problem that developed over time. If you've been around the block a couple of times, you probably agree:
"Beware of the quick, cheap fix! It usually ends up costing more.
Enough generalisms, let's dive into some meatier material.
Characteristics of Codemesh Technology
As our product offering grows both wider and deeper, it becomes harder to cover all our products with some sweeping characterizations. Historically though, Codemesh's integration technology has always had some distinguishing characteristics across all products:
- Code generator technology that imposes no (or at least almost no) limitations on the types it can be used for.
- Repeatable and predictable results in the face of change.
- Applicable at API level.
- Extremely fast, tight, reliable, and secure integration approach.
- Portable across compilers/platforms/JREs.
You can find out particulars of Codemesh's Java/C++ integration technology and Codemesh's Java/.NET integration technology but let's see first how the above mentioned key strengths stack up against other integration approaches. We will compare Codemesh technology with
In-house development is actually our biggest competition. We understand that you wish to minimize your reliance on third-party components and that there is a certain appeal to owning all the pieces of your solution. We only ask you to be aware of all the consequences of writing this glue code yourself if that's the decision you're making.
Over the years since 1999, we have seen some truly nasty JNI-based integrations. It is easy to understand why JNI has a reputation as a slow and unreliable technology when you've seen some real-life JNI projects. These projects were not failures because JNI is bad or because the engineers were stupid, but because JNI is inherently hard to use and there are few resources discussing its proper usage. The resources that are available tend to focus on the things that work well and easily and neglect to discuss the tough parts.
We once spoke to a Sun insider who told us that JNI (in his opinion) was meant to be consumed by a code generator and not by humans. We tend to agree with this characterization. When someone asks us to describe JNI, we describe it as "the JVM's assembly language interface." It's relatively easy to write one "Hello World" using JNI, just as it's relatively easy to write one highly optimized function in assembly language. Does that mean that you would want to write your entire application in assembler? Would you like to maintain that application?
We will not make any assumptions about the size of your integration problem, the number of compilers it needs to support, etc., we'll just focus on the problems you might face when you write JNI by hand. Another page contains a more detailed, technical comparison of Codemesh bindings and handwritten JNI. Here, we just provide you with a table containing higher level problem areas and you make a mental checkmark if you think one of the listed issues might be a problem for you:
|Multithreading||JNI handles are initially thread-specific. Using them incorrectly on the wrong thread can bring down the JVM or cause very hard to debug problems.|
|Reference leaks||You are in complete control of the life cycle of your JNI references. Any recurring leak can being down your JVM.|
|Error handling||You always have to explicitly check for exceptions and errors. Missing one will bring down the JVM.|
|Callbacks||There is no callback mechanism in JNI. Do you expect to have C/C++ event handlers for Java events?|
|Performance||Some JNI operations are cacheable, others are not. Not cacheing cacheable operations has a severe performance impact.|
|String handling||Character sets and string marshalling are problematic.|
|JVM portability||Some things work with one JVM but not with another.|
|Platform- and compiler-portability||Writing platform portable C code is not easy but writing platform portable C++ code is really hard. Particularly, when the design is imposed on you by the Java types that you're trying to wrap!|
|Glue code maintenance||If your Java code changes, the glue code needs to be updated. Even if your code doesn't change, someone else's code might (for example the JRE). How much time/money/resources do you allocate for this type of work?|
|Glue code type safety||If you write the glue by hand, you're probably going to end up with some utility types that don't provide the same type-safety as generated proxy classes. This is particularly troublesome in the face of change: what used to work perfectly now causes as crash, or worse: it fails silently with a reference leak.|
|Glue code enhancements||So you have your hand-written integration library and now a new set of functionality needs to be integrated. How long will it take you to do that work?|
|Maintenance||That's the big one: who's going to maintain your JNI code?
Even if you were lucky enough to have a JNI expert on staff, what happens when she leaves? Who wants to do JNI maintenance forever?
If you are in any way similar to most of our users, web services-based integration will seem very attractive to you for several reasons, chief among them:
- You already have a "free" web services stack available in your environment.
- You are interested in using web services as a learning experience.
- Web services is one of the "sexy" technologies that everyone is talking about.
These are all perfectly valid points, but they don't necessarily make web services the best fit for your integration problem. We have in fact won many customers in evaluations that pitted us directly against web services-based prototypes! Why is that?
Consider what web services were initially invented for (and are still best at):
"loosely coupled systems across the network or internet."
Maybe you have one of those integration problems but if you did, you would probably not be looking at this page. You really have a different problem: the problem of integration across programming languages. That's a very different thing from integration across processes or networks!
Let's assume for the moment that your problem can be paraphrased by the following sentence:
"I need to call my Java-based Foo API from C++ or .NET."
Let's further assume that we can disregard the nature of the API for the time being. It could be a locally used custom Java API, it could be the Java Message Service (JMS) API, or it could be an Enterprise Java Beans (EJB) API. The only thing that counts is that we have the API in Java and we want to use it in a different language.
Please recall what web services are really good at: loosely coupled systems across networks. Language independence or cross-language integration is not really a design goal of web services; it's a coincidental consequence of using a structured, serialized message representation called XML which can be parsed in many different programming languages languages.
At this point, it is usually a good idea to clarify that the standard integration mechanism of Codemesh products is in-process (the alternative mechanism is an out-of-process mechanism we call Shared JVM). In-process integration is radically different from web services or CORBA or any other integration approach that involves separate processes. Follow the in-process link above to find out more about it.
When we contrast web services with Codemesh's in-process integration, we get the following picture:
|Performance (1) (perf)||High||Low|
|Applicability for large APIs (5)||High||Low|
|Applicability for component APIs||High||High|
|Portability beyond C++/.NET||Smaller||Larger|
(1) Performance of in-process integration is of course higher simply due to the fact that a cross-language API call maps to something that is only slightly slower than native function call whereas web services calls involve large amounts of marshalling and inter-process communications. But there's an additional performance effect that was pointed out to us by customers in EJB use cases: when you use web services to communicate between a pure C++ client and an EJB server, the server has to do a lot of marshalling work. One of our customers observed that they could comfortably run 30 high-load test clients against an industrial strength EJB server using Codemesh's language bindings. When they tried to benchmark the same use case using web services the server performance degraded dramatically to the point of uselessness.
(2) Security of in-process integration is exactly as good as the security of the integrated components. This contrasts sharply with web services, where the simple fact that you have inter-process communications opens up all kinds of additional attack vectors. Running a web services-based integration solution without additional security should be a no-no for anyone.
(3) In-process integration requires a JRE which can be bundled with your application. Other than that one passive component, there are no server processes, registry entries, post-install configuration steps, etc. A well designed in-process integration can be totally self-configuring and xcopy deployable.
(4) Generated proxy classes have virtually the same usability as the underlying Java classes. This means that there are very few surprises for the programmer who's using them.
(5) Imagine a web services-based integration API for 2,000 types. You simply don't use web services for this kind of integration. Web services is a component integration technology, not an API integration technology.
The picture for CORBA is very similar to the Web Services picture. CORBA is an integration technology that is very well suited for integration between heavier modules but not so much for integration between larger APIs. Please refer to the table in the Web services section for a detailed discussion.