JMS and the .NET Developer
Much of enterprise software is built on a message-passing paradigm, and the popular .NET and Java platforms both offer APIs that provide access to messaging. While .NET offers access to Microsoft’s MSMQ through a set of standard APIs, there’s a problem: MSMQ isn’t widely used in the enterprise, even in .NET shops.
Most existing enterprise infrastructure passes messages between components through Java Message Service (JMS), so unless you’re tackling a completely greenfield project, the odds are that you will be interacting with JMS, even if you’re writing your code in C# or VB.
If you’re starting a primarily .NET-based project from scratch, with no requirement that JMS be used, you still might want to give serious consideration to using it. JMS has been around for a long time, and implementations are generally pretty solid. In addition, many different vendors offer JMS implementations that comply with the standard, and, while it’s not trivial, it is relatively straightforward to switch from one vendor’s JMS implementation to another. MSMQ, on the other hand, is only implemented by one vendor, Microsoft, so once you choose it, you’re locked in; switching from MSMQ to JMS later isn’t straightforward, since the two systems are incompatible and their APIs are quite different.
What this means is that, as a .NET developer, you may not have a choice as to whether to use JMS, and, even where you do, you may have good reasons to choose it. So how can you write .NET code that exchanges messages with a JMS infrastructure?
One or two JMS vendors offer .NET client libraries that work with their implementations. Unfortunately, they won’t work with anyone else’s implementations, which means that you’re just as locked in as you would be if you were using MSMQ, only this time to a vendor other than Microsoft. Fortunately, there’s a different approach you can take, using an interoperability technology called bridging.
When bridging is used, your .NET code continues to run in a .NET runtime, and your Java code continues to run in a Java runtime; the bridging component handles the communications between the two runtimes and makes it as transparent, seamless, and efficient as possible. While there are several ways to implement bridging, one approach is to have the bridging product analyze the target code, in this case the Java-based JMS APIs, and create .NET-based proxies that mirror the underlying JMS API. The .NET developer then simply programs against the proxies, and any calls to the proxies get mirrored to the underlying Java JMS libraries and are handled just as if all the code were written in Java.
JNBridge’s JNBridgePro is one bridging product, and it can be used to implement a connection between .NET code and a JMS infrastructure. The details of how this is done are beyond the scope of this article, but they can be found here.
One thing to note is that the JMS API is composed of interfaces, not classes, and the interfaces are the same regardless of the vendor and the implementation. Each vendor provides classes that implement the interfaces, but you as the developer don’t need to see those classes or know anything about them. This means that all you have to do to write .NET code that interacts with JMS is to proxy the interfaces (which are the same regardless of JMS vendor or product) and program against those interfaces. You can use one vendor’s implementation by dropping its Java-based JMS client library into your program, but if your employer later decides to use a different vendor’s product, you just swap the JMS client libraries (and the JMS server, or course), but there’s no need to change your .NET code: The JMS APIs you’ve programmed against, because they are standard interfaces, haven’t changed. Graphically, your code is organized as follows:
One of the problems with bridging between .NET code and the JMS API is that you, as a .NET programmer, have to know how to program against JMS. If you’re familiar with JMS programming, or are happy to learn, that’s fine. Otherwise, you might be more productive if you were programming against a messaging API that was more familiar, or at least more .NET-friendly. In that case, you might want to go one step further and use an adapter.
An adapter does a lot of the work for you. It places another layer over the proxied JMS API, so that it offers a more .NET-oriented API to the programmer. In effect, it translates the programmer-facing API to JMS. In some cases, the adapter provides the developer with a standard and familiar API; for example, the JNBridge JMS Adapter for .NET offers a Windows Communications Foundation (WCF)-based API. The adapter can be used wherever a WCF endpoint is consumed. The developer using the adapter does not need to know anything about JMS programming; they can program against more familiar, .NET-oriented APIs. Along with that advantage, the adapter retains the ability to work with any vendor’s JMS implementation; only the vendor-specific JMS client libraries and some configuration information must be changed.
The worldwide popularity of JMS has made it indispensable in many existing IT infrastructures. This means that .NET developers must find some way to integrate JMS into .NET applications. While it could be a long, arduous task to do so, it needn’t be: Adapters can help in this endeavor, and ensure JMS and .NET play nice after all.