Udostępnij za pośrednictwem


on Java-to-.NET interop via JMS and MQSeries

While looking around I found two articles, from SYS-CON's WebSphere Developer's Journal, covering J2EE and .NET interop via MQSeries.

part 1: https://sys-con.com/story/?storyid=43430&DE=1#RES

part 2: https://sys-con.com/story/?storyid=43452&DE=1#RES

These articles reference ma7p, the IBM supportpac, which is no longer available. ma7p has graduated into the MQSeries product. Upgrade to MQ V5.3 + CSD05 or later to get the MQ classes for .NET.

Interesting: the 2nd article documents a problem I ran into while trying to connect a Java/MQ application that uses the JMS api, with a .NET application that uses the MQ Classes for .NET. The JMS implementation essentially extracts function from the underlying MQ and embeds it into the API level. So, things like MessageId and CorrelationId, which are indispensable for a typical MQ app, are not transferrable between a JMS/Java app and a .NET app. JMS commandeers those MQ-isms and does not bubble them up into the application layer. In some cases there is a similarly named JMS thing, but it is not the same thing as the underlying MQ thing. In fact I could not find a way to set the MQ Message ID - the JMS doc I found said that the JMSMessageID on an outgoing JMS message will always be set by the JMS layer - the application is not able to set it. (not quite true, you can set it all you want, but as soon as you send the message, your MQ MessageId is over-written with a JMS-provided value). 

The net result was that I found myself reverse-engineering the JMS implementation of message-munging. At first it looked like it was just one or two methods, but the JMS-isms just kept coming and coming. The correlation ID needed to have a specific prefix. Strings had to conform to a JMS-specific encoding. If you try to encode a simple buffer with a couple of integers and a string, you get a big hairy XML envelope (with no namespaces! The dreaded RFH2 envelope) - the JMS message envelope. Which may be just what you DON'T want in a high-throughput messaging app. The JMS pitfalls and traps seemed to just keep going and going. Eventually I just punted and switched the Java app to use the "MQ Classes for Java", a package which defines, like the "MQ Classes for .NET", an IBM-only programming interface. When I use the MQ Classes for Java, I don't get the surprises I mentioned above.

Stop and think for a minute; This is a completely ridiculous situation. Imagine if you inserted rows into an Oracle database with a JDBC app, and then you could only read those rows with another JDBC app. Imagine if your LDAP repository, once you accessed it with JNDI, became a resource that could only be accessed by Java apps. Preposterous, right? Well that's what JMS does. You have to go to the high-fidelity MQ Classes for Java if you want to have a reasonable effort connecting Java to .NET apps. 

"Non-standard interface!" you point out. "Lock-in!" Yeah, you're right. But Interop trumps Neutrality. [Disclaimer, I never believed the "vendor neutrality" arguments anyway] The designers of JMS - either the IBM implementation of it, or the specification itself - have made decisions about message formats that specifically preclude any interop between a JMS (Java) app and a non-JMS app, without lots and lots of extra effort by the non-JMS side. The message formats are not published, so you either have to reverse-engineer them, and risk violating the JMS specification license, or ... you have to license and implement JMS. In either case, Vaya con dios, the future holds lots of work and lots of lawyers for you. Going with JMS, you may not get "Lock in" to a particular vendor of message middleware, but you do get "Lock out" - of anything non-Java.   

So I have some questions for you all:

  1. do you do interop between Java and .NET over MQ ? If so, do you use JMS? How do you resolve the issues I mentioned?
  2. anyone have any helper classes in C# or VB that unpacks the JMS envelope?
  3. what did you do about JMSMessageID?

Comments

  • Anonymous
    December 06, 2004
    Take a look at this
    http://active-jms.sourceforge.net/

    Dont know if it helps you. When I last looked at it, it supported a couple of JMS implementations like JBoss and OpenJMS. Not sure if it works with MQ though. It provides a COM interface but I dont know if it fine grained enough to provide CorrelationIDs etc.

    Actually if you want to use MQ for interop and you are free to chose any interface, I would go for MQ API. JMS adds its own headers to the actual message and can only be consumed by another JMS implementation on the otherside. Infact I find MQ API is much simpler than JMS API(cos you need a NamingServer to bind your queues/factories) unless you are entirely a Java shop.

  • Anonymous
    January 04, 2005
    The comment has been removed

  • Anonymous
    April 20, 2005
    IBM has shipped a beta of the Message Service Client for C/C++. It allows a C/C++ app to read or write JMS messages on MQ.

  • Anonymous
    August 03, 2005
    IBM has shipped a beta of the Message Service Client for C/C++. It allows a C/C++ app to read or write JMS messages on MQ.

  • Anonymous
    August 03, 2005
    IBM has shipped a beta of the Message Service Client for C/C++. It allows a C/C++ app to read or write JMS messages on MQ.

  • Anonymous
    March 06, 2006
    IBM published a paper on their XMS library.

  • Anonymous
    April 27, 2007
    IBM published a paper on their XMS library.

  • Anonymous
    April 27, 2007
    IBM has shipped a beta of the Message Service Client for C/C++. It allows a C/C++ app to read or write JMS messages on MQ.