- Introduction
- Surface Comparisons
- The Service
- The Twist
- The End (or Is It?)
The Service
For our starting service, we'll build a random number generator. We'll build more useful servers later on, but right now, we want to look just at the mechanics of building a Web service and accessing that service.
For this test, I used Borland's JBuilder, C#Builder, and Delphi. I chose Borland because they're good tool developers and because I've never used their Java or C# products, which leveled the playing field somewhat. Further, Borland has a distinct stake in being neutral in the Java versus .NET debate. Throwing a traditional native-code compiler into the mix helped put these newer platforms into contrast.
NOTE
One thing you'll observe from the following examples is that I'll spend no time at all discussing XML, SOAP, or even WSDL. As in politics or sausage-making, the details behind Web services are better left uninvestigated. (For now, anyway.)
Doing It in Java
Basically, to create a Java Web service, you do the following:
Write a class that does what you want.
Expose the methods that you want to give access to (by designating them as public).
Export the class as a bean.
Generate the necessary WSDL wrappers that will make your service available to the world.
The code is trivial:
informitjws for Inform IT Java Web Service public class ITJWS1 { public ITJWS1() { } public double getRandomNumber() { return Math.random(); } }
The really ugly part of generating the right files for a Web service should be taken care of by the tool you use. If you get into the nitty-gritty of WSDL and XML, you'd probably conclude that these standards were meant to be written by machines for other machines to read. JBuilder generated 30 lines of WSDL to implement this example (along with the appropriate port settings), and one of those lines was about 400 characters long. Even so, it's a good idea to look at the WSDL that your program generates, especially with an extremely simple class like the one above.
Now let's talk about the experience: Installing JBuilder was a relatively simple task. I was required to upgrade my Java Virtual Machine, which unfortunately destabilized my browser (Opera). Other than that, there was no hitch.
Development was straightforwardassisted, of course, by many Borland features designed to hide a great deal of complexity.
Deployment for testing was a dream. The key thing for testing any sort of client/server setup is the ability to "live debug"; you want to move seamlessly between client and server when tracing through code looking for bugs. I kept double-checking to see whether there was more I had to do, or if I'd really done what I thought I had, but it was really very easy.
Deployment for actual use was a bit more complex. I went with Apache Axis for this demo and, as the Axis Web site says, "Axis is a complicated system to install." If you really know your Apache, you probably won't feel the learning curve as much as I did; once you've taken your lumps, it's not that hard. It's also free. (And, of course, Axis is not the only option you have when deploying Java.)
Doing It in C#
One source of confusion in the whole Java versus .NET discussion stems from the fact that Java is both the language and the virtual machine (VM)the platform you develop forwhile .NET is Microsoft's virtual machine, on which you can develop in any language you like, as long as it's C#.
Seriously, Microsoft has emphasized .NET's multi-language capabilities to the point of exaggeration. You can get Java VM compilers for non-Java languages, too, and they suffer the same problem: Basically, both virtual machines are fairly high-level. In other words, they support their base languages fairly directly (rather than emulating a CPU, like the old P-Code system) and, generally, when a nonJava or nonC# language is adapted for either platform, it's compromised to the degree that it's no longer itself. I suspect that this multi-language support will be deemphasized as .NET matures.
So let's look at the C# code:
using System; using System.ComponentModel; using System.Web.Services; namespace ITWSC { public class WebService1: System.Web.Services.WebService { public WebService1() { //Generated by the environment InitializeComponent(); } #region Web Form Designer generated code //bunch of other code generated by //environment has been deleted (see below) [WebMethod] public double getRandomNumber() { Random R = new Random(); return R.NextDouble(); } } }
The actual C# code doesn't really look much different from the Java code, does it? While the code that we have to write isn't much different, there's a surprising amount of "noise" in this C# version. I've eliminated a couple dozen lines of code here because you commonly won't look at itand the environment actually hides it, by default. But those lines are there, and when working with Microsoft's Visual Studio .NET, I've had to tinker in this auto-generated code because the environment was better at adding stuff than deleting it.
From a philosophical standpoint, it's easy to favor the Java code as being cleaner, but the signal-to-noise ratio improves with meatier and more realistic projects.
Environment and deployment are far more critical than the actual coding if you're building something relatively trivial. Really, the biggest difference from Java is in how you specify methods to be published as Web services:
[WebMethod] //Tells the compiler to publish this as a Web service public double getRandomNumber() { Random R = new Random(); return R.NextDouble(); }
Unlike Java, .NET doesn't use static WSDL files. Basically, a .NET app responds to WSDL requests by generating the file on the fly. This is probably for the best, considering that .NET gives you a lot of other files to deal with and manage (or ignore, at your peril).
So how was the C# experience? The installation of C#Builder was traumatic compared to the JBuilder installation. Many files deep in the bowels of the operating system (OS) seemed to be affected. I had to upgrade Internet Explorer and my OS, and even install a patch to C#Builder before I started working.
NOTE
Not to belabor the obvious, but going the .NET route also means a commitment to the Microsoft perpetual upgrade/patch/payment route. Of course, there are potential benefits along with the attendant costs.
Development hit a minor hitch early on. In the past, I had always done .NET development at client sites, working on machines that were used as test servers. I didn't have Internet Information Services (IIS) installed on the machine I was using for this article, and, unlike Apache, IIS ain't free. C#Builder didn't come with IIS, although it does come with the developer's edition of SQL Server. Fortunately, you can download Cassini, a minimally capable server designed for developing .NET projects. (Well, you download the source, compile, and then you're set.) That was the only real hitch in the development experience. The environment had a nice, crisp feel to it as compared to JBuilder or Visual Studio .NET. It compiled quickly and deployed cleanly for testing. However, it generates an entirely different set of files than a Java development tool.
When the platform settles down, .NET deployment will be a breeze. It basically involves moving your development directory from your test server to your live (IIS) server. Expect about a zillion security breaches, of course: One way the .NET deployment gets its nice-and-easy feel is by using a lot of defaults. Many people will fail to change those defaults when they deploy.
I haven't explored all the ways in which Java Web services can be deployed, but I could see people being intimidated by the Apache Axis setup happily endorsing .NET for this simple scheme. The fact that this is really your only .NET option simplifies the equation even further. (I don't say this to offend anyone. For people who just want their jobs to be as simple as possible and hate making decisions, a single-vendor solution is welcome.)
In actual practice, deployment turned out to be a royal pain. The machine I was trying to do the install on didn't have the most recent version of .NET and refused to accept the necessary upgrades. (It wasn't my machine and the fact that this particular hardware wouldn't come up to snuff didn't surprise the machine's owners.) I ended up deploying on a test machine. So keep in mind that the whole upgrade/patch/payment routine doesn't just apply to development machines, but to all machines that the .NET solution runs on.
Doing It in Delphi
The code to implement the same server in Delphi has much of the cleanliness of the Java code, although it retains Pascal's interface/implementation division.
NOTE
Keep in mind that this is not Delphi .NET but the traditional Delphi stand-alone, native-code compiler. Years ago, Borland implemented the Java-inspired concept of interfaces to Pascal, and that has made keeping up with the various protocols possible. Theoretically, it should be possible to do this sort of thing with any language, provided that the right extensions are added, but the way of the world is apparently virtual machines.
unit ITWSDImpl; interface uses InvokeRegistry, ITWSDIntf; type TITWSD = class(TInvokableClass, IITWSD) public function getRandomNumber: Real; stdcall; end; implementation function TITWSD.getRandomNumber; begin result := Random; end; end.
And it requires an extra interface file that hides all the WSDL complexities:
unit ITWSDIntf; interface uses InvokeRegistry; type IITWSD = interface(IInvokable) ['{D1C7016D-D603-44C3-9DAD-490ED407C6BF}'] function getRandomNumber: real; stdcall; end; implementation initialization InvRegistry.RegisterInterface(TypeInfo(IITWSD)); end.
Delphi has the widest range of possibilities as far as what you can actually do with the result (say, turning it into a more traditional CGI app). I found it interesting that the mechanics of what was going on were easier to follow in Delphi, and that Delphi had no mysterious autogenerated supporting files. My two units compiled and created a single CGI executable (for example). Like .NET, Delphi doesn't actually use a static WSDL file, instead generating it on request.
Delphi didn't mess with any system files or with the Java virtual machine. Installing it didn't impact my system at all, except for using some disk space. And it runs faster and smoother thanwell, than just about anything.
Deployment could be similar to JBuilder's, in that you can hook into Apache, but here again you have many options, and it's a fairly trivial matter to provide interfaces to the same code for a stand-alone program, a CGI app, or a Web service.