What is in-process integration?
In-process integration is a simple idea: integrate two disparate technologies in one process, thereby improving performance and avoiding deployment complexities and security concerns.
In-process integration is more than mere shared memory. Shared memory-based integration still involves two processes that just happen to share a convenient system resource. True in-process integration does not involve any other processes.
Codemesh has been able to do in-process integration of Java, C++, and .NET because all of these technologies support loading of the other technology in the same process:
- Java has the so-called Invocation Interface as a part of its larger Java Native Interface. The Invocation Interface allows launching a JVM from a regular process via a C function call while the rest of JNI supports calling C functions from Java.
- .NET comes with a CLR-hosting API in COM and P/Invoke to call into C code.
- C++ can be packaged in DLLs or shared objects and loaded into applications written in Java or .NET.
- In-process integration is tight.
It is a suitable API level integration technology (vs. more coarse grained component level integration technologies).
- In-process integration is secure.
A typical in-process solution is exactly as secure as its component pieces. There is simply very little an attacker can do to get between the two sides of the integration solution because they are tied together so tightly.
- In-process integration is fast.
Because there is no inter-process communication and very little data marshalling going on, in-process integration performance is comparable to native performance. Depending on the use case, the performance hit your application is taking can be negligible.
Performance of integration solutions is incredibly hard to measure. We're really not trying to wave our hands here, but the overall performance of your in-process integration solution depends on so many factors that we just don't want to provide you with benchmarks that are more or less meaningless. So what do we feel comfortable saying about performance?
- We have found that applications that are compute- or io-bound typically have negligible performance penalties when compared with pure Java, pure C++, or pure .NET.
- If you write your application obeying some simple coding guidelines and avoiding some performance anti-patterns, you usually don't have to optimize the integration parts of your application at all.
- If your job is to worry about performance, treat cross-language calls as client-server calls. You will with 99% certainty be satisfied if you apply some simple client/server design principles in the performance hotspots of your application (minimize round-trips, call larger work items, etc.)
- Application performance is not equal to API benchmark performance. You can probably come up with some benchmarks that demonstrate that a certain call or a certain feature takes 6 x, 10 x, or 25 x the time it would take in pure Java. Well, yes, that's not very surprising (BTW: we're still interested in hearing about it because over the years we have fixed some particularly silly performance bugs in our implementation based on such customer feedback). What's much more interesting is: how is your application performing? If your entire application consists of repeatedly and rapidly calling this one feature, you and we have a problem! Luckily, this is a very rare case and typically you also call other features whose excellent performance more than make up for the one feature that is slower.
- Worst case use cases unsurprisingly include: many cross language calls that perform little or no work on the other side; many string marshalling operations.
- JVM configuration can make a huge difference. Picking a different garbage collection algorithm, or tweaking it, can make a dramatic difference in performance. That is because the Java object lifecycle is controlled by objects on the native side and that causes differences in GC behavior. What is best for your application depends on how your application uses Java, so there's little more we can say, other than that we'll help you if have real problems.
- If you pressed us really hard we would say —after a lot of disclaimers— that the average performance penalty compared to a pure Java application is <25%. If that's too much for you, you'll probably have to invent your own, revolutionary integration approach, because we certainly can't come up with anything better!
There are very few downsides to in-process integration, but we can certainly list some:
- You need to deploy both integrated technologies.
That's usually the point of the integration, but it can sometimes be politically troublesome. In our particular case, you will need a Java runtime environment (which you can optionally deploy as part of your application).
- Every process using in-process integration has both integrated runtime environments inside.
Again, that being the definition of in-process integration, it's hardly a surprise but it can be an issue if you expect to have many in-process solutions running on one system. In that case, every process would have its own JVM (and in the case of .NET, its own CLR), which would put a significant strain on the host. If that's an issue for you, consider using the Shared JVM instead.