|
Comments
Did you read today's front page stories & breaking news?
SYS-CON.TV
|
Tools & Automation Sleeping with the Enemy
.NET and Java living together
By: Fred Down
Jul. 2, 2004 12:00 AM
People often assume that .NET and J2EE are locked in some kind of life and death struggle. In fact, they can co-exist very well as I proved on a recent project. Both .NET and J2EE are based on open standards; these are Web Services Definition Language (WSDL) and Simple Object Access Protocol (SOAP), both of which are built on Extensible Markup Language (XML). This article describes how a .NET Web Services application was cloned using Java to run on a variety of Unix platforms. History Nova Marketing Group decided to produce a Web services version of nCode. The first implementation of nCode Web Services Edition was built on the Windows .NET architecture. My project consisted of building a version that would run on UNIX, specifically AIX and WebSphere. Free Tools: Not Just Because I'm Cheap When building open source tools, things go better if one builds them with gcc. They also seem to work better on open source platforms. This will become very relevant later. Implementation At the start of the nCode Web Services Edition project we developed a proof of concept based on gSoap, gSoap is a C++-based set of utilities for writing SOAP clients and servers. It has a utility that generates C++ code for clients and servers given a WSDL file. This has the advantages of producing low footprint, high performance clients and servers. These SOAP application servers work with Apache 1.x Web servers. In many ways, this seemed to be an excellent product, and for many applications it is highly recommended. Unfortunately for us, this approach had two fatal drawbacks:
PERSIA, which is now called LIEF3, is a proprietary Web services product from Roguewave. This looked promising, as at the time we were very into doing the project in C++. However an AIX version was not available, and there were requirements concerning the C++ compiler. The folks at Roguewave were extremely helpful with technical information. Rolling our own SOAP was considered, but rejected after my experiences trying to get gSoap to work with IIS SOAP. This is seriously complex code that would overstretch us in both implementation and testing. Unix-based DCOM was explored as part of a solution. It seemed to have the option of allowing us to reuse the DCOM-based nCode server that had been produced for Windows. This ultimately turned out not to be true. The Windows-based nCode DCOM server made heavy use of Windows threads, which are not portable to a POSIX based environment. Another problem was that the data transformations from DCOM format to nCode format were coded in Visual Basic. DCOM stores variable length arrays in a particular format called SAFEARRAY. While easy to access from .NET languages like C#.NET and VB.NET, they are not at all easy when using MS Visual C++. It would be even harder when using a generic C++ compiler such as g++. The Java Revelation Java is a managed environment. It is much easier to write crash-proof programs using Java than using other languages like C or C++. Writing C++ that does not contain memory leaks or memory access errors is much easier said than done. Server software must run for months without restarting, so even small memory leaks are problematic. J2EE provides a standard cross-platform and cross-vendor environment. "Write once, run anywhere" is considerably more than just a slogan. Java provides a standard way to process WSDL to implement Web services. It is also very well documented. Using the tool wscompile and a small amount of Swing Java GUI code, it was quite easy to produce a Java-based client that could access a subset of the .NET-based IIS server's Web services. The utility wscompile or an equivalent is contained in any Java Web services toolkit. This utility takes as input a WSDL file and produces the classes required to create either a SOAP client or a SOAP server. The WSDL file I used was produced by the nCode Web Services Edition .NET development team. In this case I used wscompile to produce the classes for a client. Producing the client was a significant milestone since it verified that .NET SOAP and Java SOAP were actually compatible. This was not the case with the prototype built using gSoap. The data structures used were not trivial, variable length arrays of nested structures were amongst some of the challenges presented. Next I had to produce a proof-of-concept server. The WSDL file was processed once again with the wscompile utility to create the Java classes needed for the server. The server's Java code accessed the nCode libraries by JNI. JNI is Java's mechanism for invoking routines in external libraries. Nova Marketing Group already had the necessary JNI wrapper classes. The proof-of-concept server was produced as a servlet running on the Tomcat application server platform. According to Sun: "Java Servlet technology provides Web developers with a simple, consistent mechanism for extending the functionality of a Web server and for accessing existing business systems. A servlet can almost be thought of as an applet that runs on the server side - without a face. Java servlets make many Web applications possible." Apache Axis was selected to handle the SOAP on the application server end. According to the Axis Web site: "Axis is essentially a SOAP engine - a framework for constructing SOAP processors such as clients, servers, gateways, etc. The current version of Axis is written in Java." Axis provided the tools to convert the WSDL produced by the .NET implementation into a set of Java classes that, in turn, implemented an applet that could be run on any J2EE-compliant application server. Axis also provided stub routines for implementing the nCode interface logic. Tomcat was chosen as the application server since it is free, small, and cross-platform. It is also well documented and easy to configure. This allowed the proof of concept to be demonstrated with Tomcat running on a Pentium 200 running Linux. Figure 1 illustrates the UNIX-based proof-of-concept server architecture. I proved to myself that Java SOAP and .NET SOAP were interoperable. The proof of concept used moderately complex data such as nested structures and variable length arrays and could exchange data in both directions with its .NET counterpart. Next I had to design the real thing. Various approaches were considered. For a while I favored scaling up the proof of concept and calling nCode directly using JNI. I was persuaded from this by Nova's technical team who had produced a separate nCode server process to handle nCode transactions. The Windows approach is shown in Figure 2. Requests are processed by IIS, the Windows Web/application server. These are then passed by DCOM to an nCode transaction server, which passes the request to an available worker thread or queues the request until a worker thread becomes available. The number of worker threads is defined at start time by a configuration file. Each worker thread contains its own connection to the nCode API, which resides in a set of Windows DLLs. These connections are created only once, at start-up time. Connecting to the API is a comparatively expensive operation, so connecting only once saves resources. If no transactions are received for a certain period (about 20 minutes) the transaction server closes down. This flushes any data requests as well as freeing resources. A multithreaded approach was mandated for better scalability. Since some nCode transactions could be too time consuming for high transaction volume systems, it would be impractical for all other Web requests to be stalled pending the completion of a complex query. Why a JNI Approach Would Have Been a Bad Idea
Evolution of the Solution Various approaches were considered. CORBA was initially ruled out since I had bad experiences with it on an earlier project. However, it eventually became apparent that creating a language-neutral, architecture-neutral, bug-free interprocess communication package from scratch was a tall order. CORBA suddenly became more attractive. What made it more attractive was that Java supported CORBA as an inter-process communication protocol. The CORBA IDL (Interface Definition Language), which defines the interfaces, was obtained by converting the DCOM IDL used on the Windows implementation. There was a need to provide a Web services to nCode Server layer. The nCode Server was a port of the existing Windows nCode Server, which implemented an interface that was much closer to the API provided by the nCode shared libraries. The Web services API was much higher level. This mapping was done on the Windows version using Visual Basic, which had to be hand translated in Java for my implementation. Building the Unix nCode Server - First Find Your ORB
Using the IDL-to-C++ generator, I was able to make a skeleton server. All I had to implement was the functionality that linked the IDL methods. Simple really; well, not quite. The first problem: How does the Java code find the C++ server? There are various ways a server based on CORBA can advertise its presence. I chose the simplest. When the server starts, it writes its ior (how to communicate) data to a file in/tmp. The Java side just reads this and links to the server accordingly. Since Mico is multithreaded, there was no need to implement threading manually. It came for free with Mico. Mico threads are transitory. The nCode connections were implemented in a pool, since the setting up of connections to nCode is a comparatively expensive operation. When a thread starts, it looks for an existing free connection in the pool. If there are no free connections it creates a new one and adds it to the pool. If there is no server activity for twenty minutes all connection are closed to flush any data. The implemented solution is depicted in Figure 3. Implementation Surprises The AIX nightmare The AIX version of the nCode libraries is implemented using xLC, the IBM C++ compiler, since that is what Nova's customers use. Mixing different C++ compiled objects requires considerable patience, luck, and in-depth knowledge. Mico wouldn't build using xLC on my hardware. I eventually resolved this problem by building the Mico library using GNU g++ and using my own patience, luck, and in-depth knowledge. After combining the GNU g++ compiled Mico library with the xLC-generated nCode shared libraries, things went more smoothly. Other Bad Dreams The next problem was a memory leak in Mico when CORBA used output-only parameters in our interfaces. This went away when the parameters were made input/output. Good Dreams Functional testing was performed using Web pages hosted on an IIS Web server that made Web services requests to another application server to perform various nCode functions. The server URL for the application server requests was defined in a parameter file. Changing the URL value allowed me to test the Unix implementation of nCode Web Services Edition. Stress testing was performed by a suite of VB.NET utilities that made Web services requests to a server defined in the configuration files. This suite, which was highly multithreaded, was able to simulate a wide range of scenarios by defining complex test scripts. Testing was performed initially using Tomcat, and finally using WebSphere. The implementation in WebSphere was simple, a matter of creating a WAR file containing all the Java class files and the JAR files to run them. A WAR file is the same as a Java JAR file but the suffix is changed to WAR. WebSphere's configuration utility just read the WAR file and performed all the necessary setup. Comparison Between Windows nd Unix Implementations Acknowledgements Resources Reader Feedback: Page 1 of 1
Your Feedback
Latest Cloud Developer Stories
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week
Breaking Cloud Computing News
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||