There are a whole lot of strategies to interoperability between .net and Java. probably the most generic approaches is to make use of internet features and craft WSDL and XML Schema that may work in each environments. As you might expect, net functions are top-quality appropriate for cyber web based purposes. if you are writing an intranet application that works on a LAN inside a single department or firm then different middleware technologies become eye-catching. in particular, message oriented middleware (mother) has long been a favored choice to integrate diverse structures inside a company. using mom as a foundation for communique between .internet and Java this text demonstrates interoperability between a .internet customer and a Java center tier in the context of a simple stock software operating on a local LAN. The implementation makes use of the JMS assist in the Spring framework, accessible for .net as well as Java, to give a common programming model across each tiers of the software.Why Messaging?
in lots of methods, message oriented middleware can also be considered an elder-statesman of interoperability. companies such as IBM and TIBCO had been providing messaging middleware for over twenty years that work on heterogeneous working systems and have multiple language bindings. In 1999 the Java Message carrier (JMS) specification breathed new lifestyles into the messaging house by defining a standard set of APIs and behavior for messaging providers to implement. Given the heritage, it isn't unbelievable that JMS implementations run on multiple operating methods and most, but no longer all, provide a .internet API 1. The examples in this article use TIBCO's JMS implementation which offers Java, .net, .net Compact Framework, and C++ client APIs. As a side word, there are a few alternatives purchasable to access JMS from .internet besides the fact that your favorite supplier does not give a .internet customer. One of these is to make use of an interoperability product such as JNBridge 2 or Codemesh 3.
whereas interoperability is a compelling motive to use messaging there are a lot of other areas that make it a really eye-catching, if no longer a de facto, alternative to be used in an application's structure. briefly, mother excels in offering asynchronous communication between approaches, submit-subscribe (one-to-many) message birth semantics, and high degrees of reliability. if your application can advantage from these aspects you are going to fairly frequently discover a messaging solution to be a natural healthy. if your business is already using messaging for some of these factors however best inside Java or C++ based functions, extending its function to consist of .net valued clientele a logical extension of the latest architecture. No be counted the motivating factors, making a JMS based mostly solution has its personal studying curve and collection of most excellent practices. this text makes use of the Spring framework on .web and Java to demonstrate a way to right away get began developing JMS functions. It additionally gives advice on some of the issues that naturally come up when the use of messaging to communicate between .net and Java.Introducing Spring.net
while most people are universal with the Spring Framework for building Java functions many are not aware about its .net counterpart, Spring.web four. Spring.web is a .net version of the Spring framework developed "from the floor up" in C# that contains over to .net the Spring design and method to utility construction. It includes the equal set of core performance as its Java counterparts, i.e. Inversion of handle, aspect Oriented Programming, net Framework, RPC Exporters, Declarative Transaction management, and an ADO.internet framework. in short, if you are already a "Spring.Java" person, you're going to suppose correct at home with Spring.internet.
not like Spring.Java which bundles many third birthday party libraries in its base offing, Spring.internet separates guide for third celebration libraries into one by one downloadable modules. One of those modules provides JMS help in accordance with TIBCO's JMS implementation. if you want to run the article's examples make sure you download an evaluation edition of TIBCO EMS (commercial enterprise Message service) from TIBCO's web web site 5.
A natural query to ask is "Why does Spring.net simply assist TIBCO's JMS and never <insert company identify right here>?" There isn't any basic reason different carriers are not supported. It has just been a practical cause at this time due to the fact there isn't a de facto JMS API in .web that each vendor is required to enforce. As such, each dealer finally ends up developing their personal .net impressed replica of the Java JMS API. The open source challenge .net Message provider API (NMS) intention is to provide such a typical API and it will very possible be used for future JMS work in Spring.net 6. considering that i am very regularly occurring with TIBCO's JMS product I chosen it out of convenience as the first issuer to support in Spring.web.Messaging with the Spring Framework
The goals of Spring's JMS assist are to raise the level of abstraction when the use of JMS and to assist messaging premier practices. Spring achieves these dreams with the aid of providing convenient to use messaging classes that make commonplace operations standard and creating a "undeniable ancient object" (POJO/POCO) programming model for messaging by the use of the use of MessageConverters. MessageConverters are accountable for conversion between JMS messages and "simple old objects" and are similar in spirit to XML/Object mappers however with a JMS twist. the use of message converters provide the improvement of holding JMS artifacts confined to the outermost layers of your application consequently allowing the bulk of your software to continue to be expertise agnostic. in the event you come to a decision to swap middleware, the refactoring required could be significantly below if the JMS MapMessage found its method into your enterprise processing.
Like JDBC, JMS is a low degree API requiring you to create and manipulate diverse intermediary objects even for essentially the most basic of JMS tasks. For sending messages, Spring's JmsTemplate manages these intermediary objects on your behalf and makes common JMS operations "one-liners". On the receiving side, Spring's MessageListenerContainer implementations will let you easily create the infrastructure to aid concurrent asynchronous consumption of messages. both JmsTemplate and MessageListenerContainer can be linked to a MessageConverter to translate between the JMS and POJO/POCO worlds.
JmsTemplate, MessageListenerContainers, and MessageConverters are the relevant artifacts in Spring's JMS guide. this text makes use of them significantly and explains them in some element but isn't a definitive reference. For greater particulars confer with the Spring reference documentation or a different Spring resource.whats up World in Spring JMS
earlier than diving into the details of interoperability and Spring JMS, here is a quick instance in .net that sends a "hey World" TextMessage to the JMS queue named "examine.queue" using JmsTemplate.ConnectionFactory manufacturing facility = new ConnectionFactory("tcp://localhost:7222");JmsTemplate template = new JmsTemplate(manufacturing facility);template.ConvertAndSend("test.queue", "hi there world!");
if you are all conventional with the JMS API, that you could instantly see how essential it's to make use of JmsTemplate as in comparison to direct use of the JMS API. this is basically because JmsTemplate is presenting all the boilerplate aid management of JMS Connections, sessions and MessageProducers that you would otherwise need to code. It also adds different conveniences akin to translating checked exceptions to unchecked in Java, resolving string based mostly JMS destinations to JMS vacation spot objects, and delegating to a MessageConverter to convert objects to JMS messages. in case you want to ship messages without a conversion JmsTemplate has a simple send formulation.
When calling the ConvertAndSend method, JmsTemplate uses the default MessageConverter implementation, SimpleMessageConverter, to transform the string "hiya World!" to a JMS TextMessage. SimpleMessageConverter additionally supports converting between a byte array and a ByteMessage and a hash table and a JMS MapMessage. featuring your own custom MessageConverter implementation lies on the heart of creating a complex Spring JMS software. The regular strategy is to create a converter for objects that you're already using on your utility code and easily are looking to marhsall/unmarshall them onto JMS.JMS Interoperability in a Nutshell
With Spring as a common framework on each .net and Java the issues round interoperability boil right down to the implementation of suitable MessageConverters and "undeniable historical objects" that are exchanged between .internet and Java. For comfort let's call these undeniable ancient objects "business objects". They may basically be full fledged domain objects, information transfer objects, or a UI-optimized edition of your domain objects correct for presentation. during this method the company objects themselves virtually become the facts contract between both tiers. The fields and residences protected as part of that records contract is stylish on the implementation of the converter. observe that particular facts types aren't explicitly shared. The statistics types on each side of the fence need to be compatible with each other most effective in as lots as their linked message converter can efficiently function its job.
whereas this strategy is actually less prescriptive than the use of up front contracts as in web services there are several options that possible use to enormously constrain the records it truly is exchanged and in the reduction of trivial mismatches. One non technological difficulty that helps in this regard is that in intranet or departmental applications it is regularly the same neighborhood (and even grownup) that develops both the .internet customer and Java core tier. communication and ordinary integration trying out can hence exchange to a big extent using up entrance contacts intended for consumption by means of disparate construction groups. when you are a fan of the use of up entrance formal contracts to define the interaction between tiers, then the proposed JMS strategy will probably no longer be to your liking. That being noted, this looser and certainly less standardized approach to interoperability has been successfully used to my capabilities in a few projects.
here sections take an more and more refined approach to using MessageConverters and preserving enterprise objects in sync between .web and Java. The example functions starts off by using the SimpleMessageConverter included with Spring to trade hash tables. Then they create a .web and Java implementation of an easy business object and a corresponding pair of customized MessageConverters. ultimately, they can reveal some concepts to reduce the duplication of effort worried in growing converters and business objects by hand on each and every platform by utilizing a source code translator and a conventional "all-aim" MessageConverter than converts arbitrary object forms. The a considerable number of pros and cons of each method are mentioned alongside the way.inventory buying and selling example
The context of the illustration is a simplified inventory buying and selling software. Their application can have three leading pieces of functionality - the distribution of actual-time market statistics assistance, the creation of recent trades, and the retrieval of a portfolio of trades.
starting with the distribution of market information, they create the JMS infrastructure to ship messages from the Java center tier to the .web customer. On the Java middle tier a JmsTemplate is created for sending messages and on the client side a SimpleMessageListenerContainer for receiving messages. both courses use an illustration of SimpleMessageConverter by means of default. considering market records is pretty much a collection of key value pairs, i.e. rate=28.5, TICKER="CSCO", it is low cost to use the default converter and change a simple hash desk between .net/Java.
The configuration for each JmsTemplate and SimpleMessageListenerContainer requires a JMS connection manufacturing unit and the JMS destination name and type. SimpleMessageListenerContainer also requires a reference to an implementation of a JMS MessageListener callback for processing the messages. Spring provides a MessageListenerAdapter class that implements the JMS MessageListener interface and makes use of a MessageConverter to convert the bought JMS Message to an object. The MessageListenerAdapter then makes use of this object to call a way on a consumer supplied handler category that has a matching system signature.
The previous circulate is most beneficial defined with an illustration. If the MessageListenerAdapter is configured to use the SimpleMessageConverter, then an incoming JMS MapMessage should be converted to a .net IDictionary and a way on the handler class with the signature "void address(IDictionary information)" might be invoked. If the converter produced an object of type change, then the handler type have to contain a technique named handle(exchange alternate). The sequence diagram under indicates the move of events.
This delegation scheme is what's frequently noted within the Java world as "Message-driven POJOs" or "Message-pushed objects" on account that it is a "plain historical object" and not a JMS MessageListener that acts as the messaging callback. One competencies of this approach is for you to quite simply create integration vogue check cases that pastime the movement of the software through directly calling the handler methods. one other skills is that the MessageListenerAdapter acts as a substitute for if/else or swap/case blocks commonly present in messaging functions. SimpleMessageListenerContainer incorporates many other facets, akin to automatic sending of a reply message based on the return cost of the handler method and is meant to be subclassed for customization of the processing movement. confer with the Spring reference documentation for more particulars.
The Spring configuration for these objects is proven below.
The core tier writer:<bean identity="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"><property identify="connectionFactory"><ref bean="connectionFactory"/></property><property identify="pubSubDomain" cost="proper"/><property name="defaultDestinationName" cost="APP.inventory"/></bean>
and client buyer<object identification="jmsContainer"class="Spring.Messaging.Tibco.Ems.Listener.SimpleMessageListenerContainer, Spring.Messaging.Tibco.Ems"><property name="ConnectionFactory" ref="connectionFactory"/><property identify="PubSubDomain" price="real"/><property identify="DestinationName" value="APP.inventory"/><property identify="ConcurrentConsumers" value="1"/><property name="MessageListener" ref="messageListenerAdapter"/></object>
<object id="messageListenerAdapter"type="Spring.Messaging.Tibco.Ems.Listener.Adapter.MessageListenerAdapter, Spring.Messaging.Tibco.Ems"><property identify="DelegateObject"><object classification="Spring.JmsInterop.Handlers.SimpleHandler, Spring.JmsInterop"/></property><property identify="DefaultListenerMethod" cost="HandleObject"/></object>
observe that Spring.internet makes use of the XML aspect 'object' in its place of 'bean' to define object definitions. The handler object has the unfortunate name from the .web viewpoint of "DelegateObject". This property has nothing to do with .net delegates.
All information sent to the customer is on the JMS subject matter APP.stock and all data sent from the customer to the center tier is on the JMS queue APP.inventory.REQUEST.
Sending a JMS message is easy as proven under with some contrived market dataMap marketData = new HashMap();marketData.Add("TICKER","CSCO");marketData.Add("fee", new drift(23.54));... jmsTemplate.send(marketData);
On the receiving side the processing is performed inner the handle method of StockAppHandler.public classification SimpleHandlerpublic void HandleObject(IDictionary information)log.InfoFormat("obtained market facts. Ticker = 0, price = 1", records["TICKER"], information["PRICE"]);// forward to controller to update view. . .
This minimal amount of infrastructure code is all that is needed to get started. besides the fact that children, whereas replacing a hash desk is easy and supported out of the field, it is barely applicable to use within the most simple of interoperability situations. I take standard to imply under ~5 statistics exchanges each with lower than ~10 key, value pairs. The rationale it doesn't scale to extra complex eventualities is pretty evident, the facts contract is too unfastened and it becomes difficult to be certain there are no mismatches in key, value pairs between both tiers. A greater herbal approach is to make use of courses to encapsulate the data. The courses themselves can make certain to a big extent that the facts content is relevant, as an example with the aid of providing parameterized constructors, or by using third party validation libraries. Validation issues apart, it's quite simply more convenient to deal without delay with the objects used in the middle tier for company processing as compared to introducing hash tables to fulfill the necessities of the MessageConverter. As such, so as to work at once with objects, custom message converters should be created and plugged into the Spring JMS infrastructure.the use of a custom Converter
Spring's MessageConverter interface is terribly primary. It consists of just the two strategies shown beneath,public interface IMessageConverterMessage ToMessage(object objectToConvert, .Session session);object FromMessage(Message message);
In case of failure to transform a message, a MessageConversionException is thrown.
we will create a customized message converter to ship a trade advent request message from the client to the middle tier. The classification TradeRequest collects the tips entered via the user when filling in a create change from and additionally carries a validation components. The TradeRequest type includes the following residences, image, # shares, fee, OrderType, AccountName, action (buy/sell), requestid, and user identify. The converter implementation is simple to code as it without difficulty adds these residences to corresponding fields of a JMS MapMessage. The implementation of "ToMessage" on the client is shown below.public type TradeRequestConverter : IMessageConverterpublic Message ToMessage(object objectToConvert, Session session)TradeRequest tradeRequest = objectToConvert as TradeRequest;if (tradeRequest == null)throw new MessageConversionException("TradeRequestConverter can't convert object of category " +objectToConvert.GetType());tryMapMessage mm = session.CreateMapMessage();mm.SetString("accountName", tradeRequest.AccountName);mm.SetBoolean("buyRequest", tradeRequest.BuyRequest);mm.SetString("orderType", tradeRequest.OrderType);mm.SetDouble("rate", tradeRequest.cost);mm.SetLong("amount", tradeRequest.quantity);mm.SetString("requestId", tradeRequest.RequestId);mm.SetString("ticker", tradeRequest.Ticker);mm.SetString("username", tradeRequest.UserName);
trap (Exception e)throw new MessageConversionException("couldn't convert TradeRequest to message", e);
... (FromMessage not proven)
The "FromMessage" implementation conveniently creates a TradeRequest object and units its houses using values bought from the message. See the code for particulars. note that when you are the usage of homes to marshall/unmarshall the data be certain there are no side outcomes of calling these houses in a marshalling context.
To send information from the customer to the middle tier they deserve to create a reflect photo of the previous JMS infrastructure, a JmsTemplate in the customer and a SimpleMessageListenerContainer within the core tier. The core tier's message container is configured to use a Java edition of the TradeRequestConverter and a message handler category, StockAppHandler, which has a method "void tackle(TradeRequest). The customer configuration is proven beneath.<object name="jmsTemplate" classification="Spring...JmsTemplate, Spring.Messaging.Tibco.Ems"><property identify="ConnectionFactory" ref="connectionFactory"/><property name="DefaultDestinationName" value="APP.stock.REQUEST"/><property name="MessageConverter"><object category="Spring.JmsInterop.Converters.TradeRequestConverter, Spring.JmsInterop"/></property></object>
The difficult coded client use of the template is proven beneath.public void SendTradeRequest()TradeRequest tradeRequest = new TradeRequest();tradeRequest.AccountName = "ACCT-123";tradeRequest.BuyRequest = proper;tradeRequest.OrderType = "MARKET";tradeRequest.volume = 314000000;tradeRequest.RequestId = "REQ-1";tradeRequest.Ticker = "CSCO";tradeRequest.UserName = "Joe trader";
a chain diagram for sending a message on the customer is shown under:
The core tier configuration is shown below along with an easy implemention of the POJO message handler.<bean identity="jmsContainer" classification="org.springframework.jms.listener.SimpleMessageListenerContainer"><property identify="connectionFactory" ref="connectionFactory"/><property identify="destinationName" cost="APP.inventory.REQUEST"/><property identify="concurrentConsumers" value="10"/><property name="messageListener" ref="messageListenerAdapter"/></bean>
<bean identity="messageListenerAdapter" class="org.springframework.jms.listener.adapter.MessageListenerAdapter"><property name="delegate"><bean category="org.spring.jmsinterop.handlers.StockAppHandler"/></property><property identify="defaultListenerMethod" value="handleObject"/><property identify="messageConverter"><bean class="org.spring.jmsinterop.converters.TradeRequestConverter"/></property></bean>
public category StockAppHandler protected ultimate Log logger = LogFactory.getLog(getClass());public void handleObject(TradeRequest tradeRequest)logger.info("Recieved TradeRequest object");
The talents of this method is that customer and middle tier builders can very nearly "share" a category, during this case TradeRequest, which consists of both facts and performance. One disadvantage to sharing classes, principally in tremendous tasks, is the duplication of effort in growing pairs of business objects and converters. If the information exchanged between tiers is comparatively good, this duplication may also be regarded a one time charge. besides the fact that children, if the records exchanged is altering on a weekly or day by day basis as is commonly the case throughout active construction, it could actually develop into a tedious assignment.
a great way to contend with these issues is to create a single all-intention MessageConverter than can address dissimilar message forms and to put in writing the enterprise objects once in Java and use a supply code conversion tool to get the C# equal. The next section discusses this strategy is more detail.accepted Message Converter
As that you may see within the outdated list of TradeRequestConverter the implementation is calling out *not* to be coded by hand. an answer that makes use of code generation or reflection may also be used instead. The example code includes an 'XStream' impressed reflection based converter, ReflectionMessageConverter, that can convert a big range of objects. This converter has right here features and obstacles.
The converter should still be regarded a work in growth and updates to it can be obtainable on the Spring.internet site.
every other choice strategies to a single all aim MessageConverter is to delegate the hard work to an latest marshalling technology. for example, which you can delegate an XML/Object converter and send the XML string because the payload of the JMS Message. these days Tangosol delivered a platform and language-impartial portable Object structure (POF) as part of Coherence that might even be used for this equal intention.
The example utility uses the ReflectionMessageConverter to send a alternate object to the customer in response to the TradeRequest. as an example of sending a more complicated object the client sends a PortfolioRequest and should get hold of a Portfolio object that incorporates a consumer and an inventory of trade objects in response. The configuration of the converters is proven beneath.<object name="reflectionMessageConverter"category="Spring.JmsInterop.Converters.ReflectionMessageConverter, Spring.JmsInterop">property name="ConversionContext" ref="conversionContext"/></object>
<object name="conversionContext" classification="Spring.JmsInterop.Converters.ConversionContext, Spring.JmsInterop"><property identify="TypeMapper" ref="typeMapper"/></object>
<object name="typeMapper" type="Spring.JmsInterop.Converters.SimpleTypeMapper, Spring.JmsInterop">
<!-- use fundamental configuation fashion --><property identify="DefaultNamespace" cost="Spring.JmsInterop.Bo"/><property identify="DefaultAssemblyName" cost="Spring.JmsInterop"/>
<!--<property identify="IdTypeMapping"><dictionary><entry key="1" cost="Spring.JmsInterop.Bo.alternate, Spring.JmsInterop"/></dictionary></property>--></object>
The simple configuration style of the TypeMapper used above makes use of the final part of the utterly qualified type name because the classification identifier that's placed into the message on the wire when marshalling. The DefaultNamespace and DefaultAssemblyName properties are used to assemble the fully qualified category identify when unmarshalling. The corresponding definition of the mapper on the Java side is shown under.<bean identification="classMapper" type="org.spring.jmsinterop.converters.SimpleClassMapper"><property identify="defaultPackage" value="org.spring.jmsinterop.bo"/>
<!--<property identify="idClassMapping"><map><entry key="1" cost="org.spring.jmsinterop.bo.alternate"/></map></property>-->
The IdTypeMapping/IdClassMapping properties (commented out) display how one can evade using classification names completely and use an arbitrary identifier to specify the type.Sharing company Objects
One approach that may in the reduction of the trouble in retaining business objects in sync is to use the Java Language Converter (JLCA) to instantly convert Java classes to C# 7. while this tool is supposed to be used as a "one-time" translation of a Java code base it can be incorporated into an automatic build procedure and used to synchronize your company objects between Java and .web. business objects are basically a very good candidate for this converter when you consider that they do not comprise know-how selected APIs akin to those for records entry or net programming that are elaborate for the convert as it should be devoid of subsequent guide tweaking.
youngsters, the JLCA is not without its warts. There are quite a lot of limitations and quirks but you can nevertheless create advanced C# courses that convert effectively to Java with out guide intervention. one of the most great quirks is that components names are left as lowercase but on the plus facet, JavaBean get/set methods are converted to .web residences. different limitations are that annotations aren't converted to attributes and there is no aid for generics. Namespaces are left because the java equipment name but an easy regex submit processing fixes that simply. The converter also creates C# implementations of some assisting classes if needed, as an example a C# equivalent to java.util.Set. With a bit experimenting you'll see how a ways you can use this technology on your personal assignment. A "cheat sheet" summarizing the talents of the converter are available on Gaurav Seth's blog 8. One remaining tidbit of JLCA advice is that the business at the back of the JLCA, ArtinSoft also sells a product, JLCA associate, which means that you can exchange or add the transformation suggestions 9.
running the JLCA on the Java classes in this example works very well. you could toggle the use of the hand coded C# business objects and the JLCA generated ones by using including/apart from the "Bo" and "Jlca" directories in the .web solution. In certain look/modify the validation system within the TradeRequest category which uses elementary conditional good judgment and collection type manipulation. An ant script is provided to run the JLCA on the Java company objects and alter the equipment name to the suitable .web namespace.
A screenshot of the customer after having received a few market facts events and sending both a TradeRequest and PortfolioRequest is shown under.
when you are already in a messaging environment or are drawn to the facets of messaging such as asynchronous verbal exchange and put up/subscribe beginning, the usage of Spring's JMS help in both Java and .web gives you with an impressive starting element to create interop solutions. Spring is rarely very prescriptive when it comes to the contracts used to be sure compatibility between JMS producers and buyers nevertheless it does deliver an easy extension element, the MessageConverter, that you can introduce a contract of your personal devising. The sophistication of the converters and linked objects should match the complexity of your software. The inventory trading software and ReflectionMessageConverter lay the foundation for effortless experimentation of your personal.
To reiterate a frequently mentioned description of the Spring framework - "it makes the handy stuff convenient and the challenging stuff feasible". i am hoping that you're going to agree that this also applies to Spring's JMS aid in a mixed .net/Java ambiance. on the end of the day, no remember what route you opt for for interoperability, you're going to locate that the usage of Spring on each .internet and Java is really useful on account that the same programming mannequin and most fulfilling practices can effortlessly be shared between the two worlds.
The source code accompanying this article may also be downloaded here.