ScopeWeb services provide an excellent solution for allowing cross-platform components to interoperate. However, Web services are designed for loosely coupled interactions that are infrequent and coarse-grained; therefore, they are not appropriate for applications that require frequent and fine-grained calls between Java and .NET classes. In the scenarios where Web services fall short of the requirements, Java/.NET bridging solutions such as JNBridgePro are the answer. JNBridgePro, a leading Java/.NET interoperability bridging product, provides a bi-directional, easy to use, high-performance, fine-grained direct mapping between Java/Java EE and .NET languages. JNBridgePro is appropriate to use when
When using JNBridgePro to allow .NET code to call Java code, the .NET code calls proxy objects that were automatically generated using the JNBridgePro proxy generation tool. The proxies manage the communication; the calling .NET classes aren't even aware that they're ultimately calling Java classes. JNBridgePro provides bi-directional interoperability for a wide variety of architectures because the Java code and the .NET code can be on different machines, the Java code can run in a standalone JVM or in a Java EE application server, and the solution provides interoperability for any JDK version. JNBridgePro OverviewJNBridgePro allows classes written in .NET languages like C#, C++, and Visual Basic to seamlessly and transparently access Java classes as though Java were itself a .NET language. JNBridgePro supports Java SE or Java EE and the leading Java EE application servers, allowing .NET code to access Java EE facilities including EJBs, JMS, and JNDI. JNBridgePro is designed so that the .NET objects interact with the Java objects through an automatically generated set of proxies. The Java objects behind the proxies may be on the same machine as the invoking .NET objects or on a different machine on the local area network or across the Internet; communication between the .NET and the Java objects uses .NET's remoting mechanism. JNBridgePro provides Java/.NET interaction via three communication mechanisms: a very fast in-process "shared memory" channel, a fast TCP/binary communication channel, and an HTTP/SOAP communication channel. When the coarse-grained, high-overhead approach of Web services prevents their use, the JNBridgePro Java/.NET bridging solution is an excellent choice. General Architectural Discussion of JNBridgeProA system using JNBridgePro consists of components on both the Java side and the .NET side. Figure 5-15 shows the architecture for .NET calling Java. When going in the other direction, the architecture is symmetrical by using proxies that allow Java to call .NET code. On the .NET side are the classes of the driving .NET application, the assembly consisting of the generated proxies, and a runtime component containing a set of core proxies and classes to manage Java-.NET communication and references to Java objects. On the Java side are the Java classes (either as individual class files or JAR files) and a Java runtime component that manages communication, method dispatch, and object references on the Java side. Figure 5-15. .NET calling Java architecture![]() The Java side can run inside a standalone Java Virtual Machine (JVM) or in any application server that contains a Java EE servlet container. The .NET side can be a standalone application, an ASP.NET Web application, or a Web service. JNBridgePro supports communication between Java and .NET sides using an in-process shared-memory channel, a fast binary protocol based on .NET Remoting, or HTTP/SOAP. No change to the code is required to switch between communication protocolsonly changes to configuration files. Use Case SetupFollowing is a quick sample scenario in the Supply Chain Management domain from the Web Services-Interoperability Organization's Supply Chain Management use case model at http://ws-i.org/documents.aspx. The goal of this use case is to show a consumer interacting with a GUI application that connects to a retailer's Java EE back-end system to purchase products. There are three actors in this use case; the first is a human user, the second is a demo system (the GUI shopping application), and the third is a Retailer System (that fulfills the order). For simplicity's sake, preconditions will not be checked, but it will be verified that the order can be fulfilled. If the order cannot be fulfilled, an exception will be thrown. Here is a slightly modified main success path for Use Case 1 or UC1 from the WS-I use case model. Table 5-1 depicts the main success path of the use case "purchase goods."
SolutionFor purposes of this example, it is assumed that for business reasons, the Demo System needs to be written in C#/.NET using Windows Forms while the Retailer System already exists and was built using a Java EE architecture. The main entry point to the order processing system is the method called placeOrder in the OrderProcessor Session EJB. Figure 5-16 shows the static UML model of the order processing subsystem. The placeOrder method of the OrderProcessor class throws an InvalidOrderException. The items returned by the getItems method are returned in an ArrayList. Figure 5-16. Entity relationship of the Java-side code![]() Here is an outline of what will be shown in the following section. The Java code that will be used to get a list of items for sale and place orders is briefly discussed. The JNBridgePro proxy generation tool takes this code and generates .NET proxies to it in the form of an assembly (DLL). The text then looks at a high level at some of the C# code that calls the Java code through the proxies. Finally, a detailed view is given on how the actual cross-platform calls are made through a sequence diagram call to the getItems method. Refer to Figure 5-16. Java-Side CodeListing 5-9 shows a snippet of the Java-side code. Listing 5-9. Snippet of the Java-Side Code
Generating ProxiesEach Java class that is to be accessible to .NET classes must have a corresponding .NET proxy class that manages communications with the Java class. The .NET classes interact with the proxy class as though it were the underlying Java class, and the actions are transparently communicated to the underlying Java class. JNBridgePro includes both a graphical and command line proxy generation tool. Proxies would only need to be generated for the methods of the OrderProcessor session bean and its supporting classes. Some additional proxies need to be generated to support EJBs (JNDI lookups and so on). Generating proxies takes three steps:
JNBProxy will, given one or more Java class names, generate .NET proxies for those classes and optionally all the supporting classes, including parameter and return value types, thrown exceptions, interfaces, and super classes, resulting in complete class closure. JNBProxy then generates a .NET assembly (a DLL file) that contains the implementation of the .NET proxy classes corresponding to the Java classes. Once this assembly has been generated, it can be used to access the corresponding Java classes. Using ProxiesWhen writing the code for Listing 5-10, the assembly with the generated proxies for the OrderProcessor Session beans must be imported into the Visual Studio project. Once that is done, all of the Java proxies are called in the exact same way that one would call any other C# object. Even the code completion technology of Visual Studio .NET, Intellisense, functions properly when writing code using the proxies generated by JNBridgePro. Listing 5-10 shows a small portion of the source code for the C# Windows Form portion of example code. As can be seen from Listing 5-10, the C# code for the Windows Form is strikingly similar to Java code. The getInitialContext and getItems methods have all the setup code expected to lookup an EJB including finding the initial context and getting the home and remote interface. Following is some of the source code along with a high-level explanation of what is happening between the C# and Java sides. Listing 5-10. .NET-Side Code
using javax.naming; "imports" the proxies that were generated by JNBridgePro that are used to access the Java/JNDI code. These proxies are included in the OrderProcessor assembly that has been included in the Visual Studio .NET project. The using keyword actually imports the proxies generated by JNBridgePro. new InitialContext(); creates a new object of type javax.naming.InitialContext. Because this is a proxy object, the new operator is actually creating a new object on the Java side and returning it as a C# object. java.lang.Object objRef = jndiContext.lookup("theOrderProcessor"); simply makes a method call on the jndiContext object, though it is a bit more complicated. Of course, this lookup happens on the Java side, and the resulting Object is sent back to the C# side. One interesting note here is that the context lookup returns an anonymous class; therefore, the proxy for this object must be generated on the fly. catch( java.lang.Exception ex ) catches any java.lang.Exception that is thrown by the code in the try/catch block. These exceptions are generated by the Java code and are automatically translated into exceptions that are compliant with the C# exception handling mechanisms. Resulting SystemThe ordering screen, upon activation, makes a call to the OrderProcessor EJB method getItems. The Item objects returned are used to populate each of the four items seen on the ordering screen. When the user enters a non-zero quantity and clicks the OK button, the C# code then calls the OrderProcessor Session EJB method placeOrder. The return value from that call is used to populate the Order Confirmation screen. From this simple example, one can see how JNBridge makes the cross-platform method calls. Refer to Figures 5-17 and 5-18. Figure 5-17. Running the Ordering Applications Figure 5-18. Windows form code Detailed Architectural DiscussionFollowing is a detailed look at what happens when a .NET method makes a call to the Java side. For purposes of explanation, consider the following line of code: System.Collections.ArrayList items = remote.getItems().NativeImpl; Figure 5-19 shows a detailed sequence diagram for the preceding method call. To better understand the technology behind JNBridgePro, look at this line of code by walking through a sequence diagram of the resulting call path. Figure 5-19. Sequence diagram for the .NET-to-Java integration example![]() Object LifelinesTable 5-2 summarizes the object lifelines discussed in this section.
Message CallsTable 5-3 summarizes the message calls discussed in this section.
BenefitsAs is apparent from the preceding example, using the JNBridgePro Java/.NET interoperability solution is quite easy.
ReliabilityJNBridgePro supports failover. In the "purchase goods" scenario given, it is possible that the Retailer System could be down. In most high-availability scenarios, a redundant failover server is available. Using JNBridgePro, a failover server can be specified. If the primary server fails for any reason, JNBridgePro can forward the request to the failover server. In this scenario, a FailedServerException is thrown so that the user knows that the primary server is not available and can then simply forward the request to the failover server. This is done semi-automatically because in many scenarios, an automatic rerouting of the order is sufficient. TransactionsJNBridgePro provides support for the transaction mechanisms of the Java and .NET platforms. When dealing with messaging systems, Transactions are of the utmost importance where performance and reliability are concerned. For more information on interoperability with Transactions, see Chapter 12, "Managing Distributed Transactions." SecurityIf one uses the in-process shared-memory channel, security is not a concern because the communication between the two applications is taking place in the same memory space. Using JNBridgePro's TCP/binary socket-based communication channel is normally done for applications running on the same intranet. JNBridgePro can also be used to interoperate between Java and .NET applications residing on any two Internet-connected machines. |